# Adobe Journey Optimizer

Utilisez cette option lorsque vous avez **Adobe Journey Optimizer (AJO)** et que vous voulez **des envois déclenchés par API** qui s’inscrivent dans une orchestration moderne des parcours.

Avant d’aller plus loin, assurez-vous de comprendre comment fonctionne le fournisseur de script dans la Wallet Crew. Commencez par [Adobe Marketing Cloud](/connectors/fr/email-provider/adobe-marketing-cloud.md) et le prérequis [extensibilité EmailSender](/connectors/fr/custom-connector/emailsender-extensibility.md).

### Quand utiliser ceci

On choisit généralement AJO lorsque vous voulez des envois quasi en temps réel et que votre équipe marketing gère déjà des parcours dans AJO.

### Configuration requise dans Adobe

Créez un parcours ou une campagne déclenché par API capable d’accepter un appel d’exécution. Configurez ensuite l’action e-mail.

Au minimum, convenez de ce que votre script envoie à AJO.

* **HTML entièrement rendu** de la part du Wallet Crew (`Objet`, `Body`).
* Ou **uniquement les variables de contexte**, avec le modèle géré dans AJO.

{% hint style="warning" %}
Choisissez une seule stratégie de rendu. Évitez de dupliquer la gestion des modèles à la fois dans The Wallet Crew et dans Adobe.
{% endhint %}

### Notes d’implémentation (OAuth + déclencheur)

AJO utilise Adobe IMS pour OAuth2 (identifiants client). Votre script demande généralement un jeton d’accès, puis appelle le point de terminaison d’exécution d’AJO pour votre campagne ou votre parcours.

{% hint style="info" %}
Les points de terminaison Adobe et la structure des charges utiles dépendent de la configuration de votre organisation, de la région et de la fonctionnalité AJO que vous utilisez (parcours ou campagne). Considérez l’extrait ci-dessous comme une base, et alignez-le sur la documentation officielle Adobe pour la version de votre produit.
{% endhint %}

Stockez ces valeurs comme secrets avant de tester :

* `adobe-clientId`
* `adobe-clientSecret`
* `adobe-orgId`
* `adobe-sandboxName`
* `adobe-ajo-triggerUrl` (URL complète du déclencheur AJO)
* `adobe-scope` (facultatif, selon votre configuration Adobe)

{% code title="Exemple Adobe Journey Optimizer (implémentation SendEmail)" %}

```javascript
import { getSecret } from "neo/secrets";

const CUSTOM_DOMAIN = "wallet.brand.com";
const TENANTID = "brand";

// Adobe IMS (identifiants client OAuth2)
// Votre environnement d’exécution fournit un `fetch` personnalisé capable d’effectuer des flux OAuth d’identifiants client.
const IMS_TOKEN_URL = "https://ims-na1.adobelogin.com/ims/token/v3";

/**
 * @typedef {Object} EmailData
 * @property {string} Subject - Ligne d’objet rendue.
 * @property {string} Body - Contenu du corps rendu.
 */

/**
 * Envoyer un e-mail en utilisant le nom de modèle et les données fournis.
 * L’appelant fournit les cultures prises en charge et un rappel
 * pour générer le contenu de l’e-mail rendu.
 *
 * @param {string} recipient - Adresse e-mail cible.
 * @param {string} emailTemplate - Nom du modèle à rendre.
 * @param {Object.<string, any>} data - Données du modèle transmises au script.
 * @param {string[]} cultures - Noms de cultures disponibles fournis par le fournisseur de cultures.
 * @param {(templateName: string) => Promise<EmailData>} buildEmail
 * Fonction de rappel qui renvoie le contenu final de l’e-mail rendu.
 *
 * @returns {Promise<void>}
 */
async function sendEmail(recipient, emailTemplate, data, cultures, buildEmail) {
  const email = recipient;
  const countryCode = data["country"] || "fr";
  const language = `${cultures[0]?.toLowerCase()?.substring(0, 2) || "fr"}_${countryCode.toLowerCase()}`;
  const customerId = data["id.customerId"];

  if (!customerId) {
    throw new Error('Champ "id.customerId" manquant dans les données de l’e-mail.');
  }

  // URL sur laquelle le client doit cliquer pour télécharger sa Carte.
  // Vous pouvez modifier le chemin pour l’adapter à votre structure de distribution.
  const url = `https://${CUSTOM_DOMAIN}/${TENANTID}/Carte?id.customerId=${encodeURIComponent(customerId)}`;

  // Conservez éventuellement le rendu de Wallet Crew disponible.
  // Si votre modèle AJO est entièrement géré dans Adobe, vous pouvez supprimer ceci.
  const rendered = await buildEmail(emailTemplate);

  // La configuration AJO doit être fournie sous forme de secrets.
  // Utilisez une URL complète pour éviter de coder en dur des chemins spécifiques au produit dans ce script.
  // Exemple (varie selon la configuration) : "https://platform.adobe.io/journey/execute/<CAMPAIGN_OR_JOURNEY_ID>"
  const ajoTriggerUrl = await getSecret("adobe-ajo-triggerUrl");
  const orgId = await getSecret("adobe-orgId");
  const sandboxName = await getSecret("adobe-sandboxName");
  const clientId = await getSecret("adobe-clientId");
  const clientSecret = await getSecret("adobe-clientSecret");

  // Conservez la portée configurable. Différentes configurations Adobe exigent des portées différentes.
  // Valeurs d’exemple observées sur le terrain : "openid,AdobeID"
  let scope = "openid,AdobeID";
  try {
    scope = (await getSecret("adobe-scope")) || scope;
  } catch (e) {
    // Secret facultatif. Conservez la portée par défaut.
  }

  // Votre `fetch` d’exécution gère les identifiants client OAuth et ajoute le jeton.
  // Cela évite d’appeler IMS manuellement puis de transmettre le jeton Bearer.
  const result = await fetch(ajoTriggerUrl, {
    Method: "POST",
    Authentication: {
      mode: "OAuth2.0",
      grantType: "clientCredentials",
      sendCredentialsAsFormParams: true,
      accessTokenUrl: IMS_TOKEN_URL,
      clientId,
      clientSecret,
      scope,
    },
    Headers: {
      "x-api-key": clientId,
      "x-gw-ims-org-id": orgId,
      "x-sandbox-name": sandboxName,
      "Content-Type": "application/json",
    },
    Corps: JSON.stringify({
      // La forme exacte de la charge utile doit correspondre à la configuration de votre campagne/parcours AJO déclenchée par API.
      // Gardez ce contrat stable entre votre script et votre ressource AJO.
      recipient: {
        email,
        language,
      },
      context: {
        // Variable minimale pour un modèle géré par Adobe :
        url,

        // Variables facultatives si vous voulez réutiliser le rendu de Wallet Crew dans Adobe :
        subject: rendered.Subject,
        body: rendered.Body,

        // Métadonnées utiles pour l’acheminement / le débogage :
        template: emailTemplate,
        customerId,
      },
    }),
    ThrowOnError: false,
  });

  if (result.StatusCode < 200 || result.StatusCode >= 300) {
    throw new Error(`L’appel au déclencheur AJO a échoué (${result.StatusCode}) : ${result.ResponseText}`);
  }
}

export default function (context) {
  context.register("runtime.scriptable.emailEngine", {
    SendEmail: sendEmail,
  });
}
```

{% endcode %}

### Ce qu’il faut valider

Déclenchez un vrai e-mail transactionnel, puis vérifiez ces points :

* AJO reçoit l’appel d’exécution et l’accepte.
* L’action e-mail AJO a accès aux champs de contexte que vous envoyez.
* Si vous transmettez du HTML, l’e-mail final s’affiche correctement dans les clients courants.

### FAQ

<details>

<summary><strong>A-t-on besoin d’un « parcours déclenché par API » dans AJO ?</strong></summary>

Oui. Votre script a besoin d’un élément AJO publié pouvant être déclenché par un appel API. Le type exact d’élément (parcours ou campagne) dépend de ce qu’utilise votre organisation Adobe.

</details>

<details>

<summary><strong>AJO peut-il envoyer un e-mail construit par le Wallet Crew ?</strong></summary>

Oui. Un schéma courant consiste à appeler `buildEmail()` dans votre script, puis à transmettre `subject` et `body` en tant que contexte à AJO. Votre action e-mail AJO doit être configurée pour utiliser ces champs.

</details>

<details>

<summary><strong>Comment tester sans envoyer d’e-mails à de vrais clients ?</strong></summary>

Utilisez un sandbox AJO si vous en avez un. Sinon, limitez les tests aux adresses internes et créez un parcours/campagne « test » dédié. Conservez le même contrat de charge utile qu’en production pour éviter les ruptures de schéma de dernière minute.

</details>

<details>

<summary><strong>Pourquoi avons-nous besoin d’autant d’en-têtes Adobe ?</strong></summary>

Les passerelles AJO exigent généralement des en-têtes d’organisation, de sandbox et de clé API pour le routage et l’autorisation. L’ensemble exact peut varier selon la configuration et la région Adobe ; considérez donc la documentation officielle Adobe comme la source de vérité pour votre locataire.

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.thewalletcrew.io/connectors/fr/email-provider/adobe-marketing-cloud-1/adobe-journey-optimizer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
