# Adobe Campaign Transactional Messaging

Utilisez cette option lorsque votre organisation exécute **Adobe Campaign** et utilise déjà **Transactional Messaging** pour les envois en production.

Avant d'aller plus loin, assurez-vous de comprendre comment le fournisseur de script fonctionne dans The Wallet Crew. Commencez par [Adobe Marketing Cloud](https://app.gitbook.com/s/WLc8AHXW4tdrAXUBfrYF/connect/email-provider/adobe-marketing-cloud) et le préalable [Extensibilité EmailSender](https://app.gitbook.com/s/WLc8AHXW4tdrAXUBfrYF/connect/custom-connector/emailsender-extensibility).

### Quand l'utiliser

Ceci convient lorsque vous disposez déjà de la gouvernance, des rapports et des événements transactionnels préexistants d’Adobe Campaign.

### Configuration requise dans Adobe

Créez et publiez une **Transactional Message Event**.

Décidez ensuite si Adobe Campaign utilisera le HTML rendu par The Wallet Crew ou construira l’e-mail final en utilisant les modèles et variables d’Adobe Campaign.

Vous avez également besoin d’une méthode d’authentification sécurisée côté serveur prise en charge par votre déploiement Adobe Campaign. Cela repose souvent sur Adobe I/O ou IMS.

### Notes d’implémentation (appel d’événement)

Votre script génère généralement l’e-mail (si The Wallet Crew contrôle le HTML), puis appelle le point de terminaison de l’événement transactionnel avec le destinataire et le contexte.

Stockez ces valeurs en tant que secrets avant de tester :

* `adobe-clientId`
* `adobe-clientSecret`
* `adobe-campaign-transactionalUrl` (URL complète de l’événement Transactional Message)
* `adobe-orgId` (optionnel, dépend de votre configuration Campaign)
* `adobe-scope` (optionnel, dépend de votre configuration Adobe)

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

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

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

// Adobe IMS (OAuth2 client credentials)
const IMS_TOKEN_URL = "https://ims-na1.adobelogin.com/ims/token/v3";

async function getOptionalSecret(name, fallback) {
  try {
    return (await getSecret(name)) || fallback;
  } catch (e) {
    return fallback;
  }
}

/**
 * @typedef {Object} EmailData
 * @property {string} Subject
 * @property {string} Body
 */

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('Missing "id.customerId" in email data.');
  }

  const url = `https://${CUSTOM_DOMAIN}/${TENANTID}/pass?id.customerId=${encodeURIComponent(customerId)}`;

  // Conserver le rendu Wallet Crew disponible.
  // Si Adobe Campaign possède le modèle, vous pouvez supprimer ceci et n’envoyer que des variables.
  const rendered = await buildEmail(emailTemplate);

  const transactionalUrl = await getSecret("adobe-campaign-transactionalUrl");

  const clientId = await getSecret("adobe-clientId");
  const clientSecret = await getSecret("adobe-clientSecret");
  const scope = await getOptionalSecret("adobe-scope", "openid,AdobeID");

  // Optionnel. Certaines configurations exigent des en-têtes d’org id, d’autres non.
  const orgId = await getOptionalSecret("adobe-orgId", null);

  const headers = {
    "x-api-key": clientId,
    "Content-Type": "application/json",
  };
  if (orgId) headers["x-gw-ims-org-id"] = orgId;

  const result = await fetch(transactionalUrl, {
    Method: "POST",
    Authentication: {
      mode: "OAuth2.0",
      grantType: "clientCredentials",
      sendCredentialsAsFormParams: true,
      accessTokenUrl: IMS_TOKEN_URL,
      clientId,
      clientSecret,
      scope,
    },
    Headers: headers,
    Body: JSON.stringify({
      // La charge utile doit correspondre à la définition de votre Transactional Message Event.
      email,
      ctx: {
        url,
        language,

        // Optionnel si vous voulez que Campaign utilise le rendu Wallet Crew :
        subject: rendered.Subject,
        body: rendered.Body,

        // Métadonnées utiles :
        template: emailTemplate,
        customerId,
      },
    }),
    ThrowOnError: false,
  });

  if (result.StatusCode < 200 || result.StatusCode >= 300) {
    throw new Error(`Adobe Campaign call failed (${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 :

* Votre Transactional Message Event est publié et appelable.
* Le schéma de la charge utile correspond à la définition de l’événement.
* Adobe Campaign accepte la requête et traite le message.

### FAQ

<details>

<summary><strong>Avons-nous besoin d’un Transactional Message Event ?</strong></summary>

Oui. Votre script doit appeler un point de terminaison d’événement Transactional Messaging publié. Cet événement définit le schéma de la charge utile attendu et les variables disponibles dans votre modèle Adobe Campaign.

</details>

<details>

<summary><strong>Adobe Campaign peut-il rendre l’e-mail au lieu de The Wallet Crew ?</strong></summary>

Oui. Dans cette configuration, votre script envoie uniquement les variables (par exemple, l’URL de téléchargement de la carte et les métadonnées client). Adobe Campaign possède le HTML, l’objet et les traductions.

</details>

<details>

<summary><strong>Quelle méthode d’authentification devons-nous utiliser ?</strong></summary>

Cela dépend de votre déploiement Adobe Campaign et de la façon dont votre organisation Adobe gère l’accès serveur-à-serveur. Cette page montre une approche basée sur IMS parce qu’elle est courante, mais vous devriez aligner la méthode d’authentification finale avec votre équipe admin Adobe et la documentation officielle d’Adobe pour votre environnement.

</details>

<details>

<summary><strong>Quelle est la raison la plus courante de rejet de requête ?</strong></summary>

Incompatibilité de schéma. La définition de l’événement est stricte. Si les champs de votre charge utile ne correspondent pas à la structure attendue par l’événement, Campaign rejettera ou ignorera les champs et les modèles afficheront des valeurs vides.

</details>
