> For the complete documentation index, see [llms.txt](https://docs.thewalletcrew.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.thewalletcrew.io/connectors/fr/email-provider/adobe-marketing-cloud/adobe-journey-optimizer.md).

# Adobe Journey Optimizer

Envoyez les e-mails transactionnels de The Wallet Crew via Adobe Journey Optimizer (AJO) à l’aide du fournisseur d’e-mails scripté.

Utilisez cette option lorsque **Adobe Journey Optimizer (AJO)** est disponible et **les envois déclenchés par API** s’intègrent au modèle d’orchestration de parcours déjà en place.

Avant d’aller plus loin, assurez-vous que le modèle du fournisseur de script utilisé par The Wallet Crew est clair. Commencez par [Adobe Marketing Cloud](/connectors/fr/email-provider/adobe-marketing-cloud.md) et la dépendance préalable [l’extensibilité EmailSender](/connectors/fr/custom-connector/emailsender-extensibility.md).

### Quand utiliser ceci

AJO est généralement le bon choix lorsque des envois quasi en temps réel sont nécessaires et que l’équipe marketing gère déjà des parcours dans AJO.

### Configuration requise dans Adobe

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

Au minimum, mettez-vous d’accord sur ce que le script envoie à AJO.

* **HTML entièrement rendu** de The Wallet Crew (`Objet`, `Corps`).
* 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 le templating à la fois dans The Wallet Crew et Adobe.
{% endhint %}

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

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

{% hint style="info" %}
Les points de terminaison Adobe et la forme des charges utiles dépendent de la configuration de l’organisation, de la région et de la fonctionnalité AJO utilisée (parcours vs campagne). Considérez l’extrait ci-dessous comme une base et alignez-le sur la documentation officielle Adobe pour la version du produit concernée.
{% 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 la 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 runtime fournit un `fetch` personnalisé capable d’exécuter 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.
 */

/**
 * Envoie 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 callback
 * pour construire 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 des cultures disponibles fournis par le fournisseur de cultures.
 * @param {(templateName: string) => Promise<EmailData>} buildEmail
 * Callback 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 disposition de distribution.
  const url = `https://${CUSTOM_DOMAIN}/${TENANTID}/Carte?id.customerId=${encodeURIComponent(customerId)}`;

  // Conservez éventuellement le rendu The 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 propres 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. Les différentes configurations Adobe exigent des portées différentes.
  // Exemples vus dans la pratique : "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 attache 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",
    },
    Body: 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 actif AJO.
      recipient: {
        email,
        language,
      },
      context: {
        // Variable minimale pour un modèle géré par Adobe :
        url,

        // Variables optionnelles si vous souhaitez réutiliser le rendu The Wallet Crew dans Adobe :
        subject: rendered.Subject,
        body: rendered.Body,

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

  if (result.StatusCode < 200 || result.StatusCode >= 300) {
    throw new Error(`L’appel du 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 véritable e-mail transactionnel, puis validez 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 qui ont été envoyés.
* Lorsque le HTML est transmis, l’e-mail final s’affiche correctement dans les clients courants.

### FAQ

<details>

<summary><strong>Un « parcours déclenché par API » est-il requis dans AJO ?</strong></summary>

Oui. Le script a besoin d’un actif AJO publié qui puisse être déclenché par un appel API. Le type d’actif exact (parcours vs campagne) dépend de ce que l’organisation Adobe utilise.

</details>

<details>

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

Oui. Une approche courante consiste à appeler `buildEmail()` dans le script, puis à transmettre `subject` et `body` comme contexte à AJO. L’action e-mail AJO doit être configurée pour utiliser ces champs.

</details>

<details>

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

Utilisez un sandbox AJO lorsqu’il est disponible. Sinon, limitez les tests aux adresses internes et créez un parcours ou une campagne « test » dédié(e). Conservez le même contrat de charge utile que la production afin d’éviter les ruptures de schéma de dernière minute.

</details>

<details>

<summary><strong>Pourquoi autant d’en-têtes Adobe sont-ils nécessaires ?</strong></summary>

Les passerelles AJO exigent généralement les 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, alors considérez la documentation officielle Adobe comme source de vérité pour le locataire.

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
