# Tutoriel - Comment créer une destination server avec le JS sandbox

Le Destination builder vous permet de créer des destinations server-side personnalisées en utilisant server-side **javascript** (alias Node.js), mais avec un **facile et simplifié** sous-ensemble de Node.js : le [***Javascript Sandbox***](https://doc.commandersact.com/fr/fonctionnalites/destinations/destination-builder/javascript-destination-builder/..#javascript-sandbox).

Ce tutoriel vous apprendra les bases pour écrire votre propre modèle de destination server-side et le publier dans votre ou vos catalogues de destinations.

{% hint style="success" %}
Une destination server-side reçoit les données d'événements entrantes depuis vos sources, les transforme et envoie les données où vous voulez. Tant que l'outil de destination accepte des requêtes HTTP, il peut accepter des données provenant d'une destination server-side.
{% endhint %}

## Exemple de base : Slack

Dans ce tutoriel, vous allez créer une destination qui envoie les données d'événements à Slack à l'aide d'un seul `webhook_url` paramètre. Slack est un outil de messagerie et de collaboration qui prend en charge l'intégration de webhooks. Le cas d'utilisation peut être : "Je veux recevoir sur un canal Slack un message à chaque fois qu'un événement "sign\_up" est reçu"

### Configuration de la destination

Pour commencer, créez le modèle de destination en allant dans la **Destination** section du menu et en cliquant sur la section **New** dans la **Destination Builder** . Donnez ensuite à votre destination un nom, un logo, une catégorie et une description.

<figure><img src="https://3282103337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mk6XpTQ2LaRLcr2tA-d%2Fuploads%2Fgit-blob-9182a6a108ce87e0bb37ee2e87b6a739e68b640d%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

Ensuite, allez dans la **Fields** section de l'éditeur pour ajouter des options de paramètres à votre destination. Vous avez trois options pour créer votre destination :

1. **Configuration totale**: Créez un champ de configuration pour chaque paramètre, afin de permettre à l'utilisateur de tout définir explicitement.
2. **Aucune configuration**: N'incluez aucune option de configuration de la destination. À la place, toutes les données sont prises directement depuis l'événement.
3. **Configuration partielle**: Incluez des champs pour certains paramètres mais pas pour d'autres.

Bien qu'avoir un champ pour chaque paramètre soit flexible, cela peut entraîner beaucoup de travail en double pour l'utilisateur. Par conséquent, il est préférable de laisser le code gérer la configuration des données non ambiguës et universelles.\
Par exemple, si vous créez une destination d'analyse, vous ne voulez pas demander à l'utilisateur de saisir l'URL de l'API d'analyse à chaque fois qu'il configurera cette destination. Vous préférerez coder en dur l'URL dans votre code sans demander à l'utilisateur de la saisir.\
\
En revanche, si vous créez votre destination pour obtenir les données uniquement à partir de l'événement, sans ajouter de champ dans les paramètres pour l'utilisateur, l'utilisateur ne pourra pas personnaliser la destination.\
Par exemple, si la destination nécessite un jeton, ce jeton peut varier selon le contexte (prod, dev, pays...), donc si vous codez en dur un jeton dans le code...\
Ou bien, peut-être que les hypothèses faites par la destination concernant la structure des données d'événements entrantes ne correspondent pas à la réalité des événements/propriétés personnalisés. Dans les deux cas, l'utilisateur ne peut pas continuer.

En conclusion, certaines données doivent toujours être extraites de l'événement tandis que d'autres doivent être configurées par l'utilisateur. C'est à vous de décider afin que le résultat final soit convivial pour l'utilisateur.

Dans le cas de notre destination Slack, nous voudrons ajouter un champ afin que l'utilisateur puisse copier/coller l'URL de son webhook Slack. Nous choisissons une saisie de texte comme celle-ci :

<figure><img src="https://3282103337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mk6XpTQ2LaRLcr2tA-d%2Fuploads%2Fgit-blob-dd54607875539f770b8c64071b874eb168236917%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

Maintenant, nous pouvons aller dans l'onglet *Code* pour commencer à écrire le code de notre modèle de destination.\\

<figure><img src="https://3282103337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mk6XpTQ2LaRLcr2tA-d%2Fuploads%2Fgit-blob-042a7de5d9437739afd3668095e9c3da59797fb8%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

### Comment obtenir les données dans votre code ?

Vous pouvez vouloir obtenir 2 types de données :

1. les données saisies par l'utilisateur (champs remplis dans l'onglet des paramètres)
2. les données d'événement (certaines propriétés de votre événement que vous souhaitez envoyer au partenaire)

#### 1. Données saisies par l'utilisateur

Toutes les données renseignées dans les différents champs par l'utilisateur sont accessibles dans l'objet `data` dans votre code.\
Dans votre exemple, nous n'avons qu'un seul champ nommé "url", et la valeur que l'utilisateur final saisira sera accessible via `data.url`

#### 2. Données d'événement

Vous voudrez obtenir certaines propriétés de vos événements pour les envoyer au serveur partenaire. Vous pouvez utiliser l'une de ces 2 fonctions pour obtenir les données de votre événement :

* [getAllEventData() ](https://doc.commandersact.com/fr/fonctionnalites/destinations/destination-builder/serverside-js-helpers#getalleventdata-2)=> renverra un objet avec toutes les propriétés de l'événement
* [getEventData(myProperty)](https://doc.commandersact.com/fr/fonctionnalites/destinations/destination-builder/serverside-js-helpers#geteventdata) => renverra la valeur d'une propriété spécifique de votre événement

### Implémentation de la destination

Après avoir configuré la destination, vous pouvez passer à l'implémentation de son comportement dans le Javascript Sandbox.

L'exemple Slack nécessite les quatre étapes suivantes :

1. Obtenir l'URL du webhook à partir des paramètres de la destination.
2. Créer le message qui sera envoyé à l'API Slack.
3. Envoyer une requête au serveur de collecte Slack pour transmettre les données.
4. Tester votre code, afin de vous assurer que la destination se comportera correctement en production.

Il est important de noter que le code ne doit pas effectuer certaines actions, car elles relèvent de la responsabilité de l'onglet de filtrage. Plus précisément, le code doit **ne pas**:

* **Gérer le consentement** pour déterminer si l'événement doit être envoyé ou non.\
  C'est la responsabilité de la liste déroulante de catégorie de consentement dans l'onglet *Filter* . Il est important de ne pas contourner cette fonctionnalité, afin de ne pas casser les rapports de Data Governance
* Analyser les propriétés de l'événement pour **déterminer s'il doit être exécuté**.\
  N'oubliez pas que l'utilisateur pourra choisir dans l' *onglet Filter* quel événement sera envoyé à la destination. Vous pouvez vouloir restreindre votre code à certains types d'événements, mais vous ne devez pas retirer à l'utilisateur la possibilité de filtrer ses événements selon certaines propriétés (par ex. : l'utilisateur peut vouloir envoyer uniquement les événements dont la propriété "country" est égale à "UK")
* Retourner une erreur globale (`data.onFailure()`) lorsqu'un certain type d'événement ne convient pas à la destination. Préférez utiliser une erreur silencieuse avec `data.onFailure({ status: 'filtered'})`

Si vous créez un modèle de destination qui effectue l'une de ces actions, cela peut prêter à confusion pour les utilisateurs de votre destination. Par exemple, une destination qui envoie des erreurs à Event Delivery chaque fois que des événements non pris en charge sont détectés peut conduire à des avertissements inutiles dans les rapports Health. Cela irait à l'encontre des attentes des utilisateurs concernant le comportement attendu de la destination.

Dans cet esprit, voici un exemple annoté de l'implémentation du tag dans le Javascript Sandbox :

```javascript
const sendHttpRequest = require('sendHttpRequest');
const getAllEventData = require('getAllEventData');

// Nous récupérons les données de l'événement (toutes les propriétés de l'événement)
const eventModel = getAllEventData();

if (eventModel.event_name == 'sign_up') {
    // récupérer l'url à partir de ce que l'utilisateur a écrit dans le champ webhook url
    // Les données des paramètres entrent dans le code sandboxé sous la forme d'une 
    // variable prédéfinie appelée 'data'.
    const url = data.url; 
    // Construire le message du corps, en concaténant le nom de l'utilisateur dans la phrase à envoyer
    const postBody = '{"text": "' + eventModel.user.firstname + ' ' + eventModel.user.lastname + 'just signed up!"}';

    // Envoyer les données au serveur Slack
    // La fonction sendHttpRequest prend une URL, une fonction de rappel de résultat, éventuellement un en-tête, une méthode et un corps.
    sendHttpRequest(url, (statusCode, headers, body) => {
        if (statusCode >= 200 && statusCode < 300) {
            // envoyer une information de succès au rapport Event Delivery
            data.onSuccess();
        } else {
           // envoyer une erreur au rapport Event Delivery
            data.onFailure();
        }
    }, { headers: { 'Content-Type': 'application/json' }, method: 'POST', timeout: 1000 }, postBody);
}
else {
    // échec silencieux qui n'enverra pas d'erreur dans le rapport Event Delivery
    data.onFailure({ status: 'filtered', detail: 'unsupported_event' });
}
```

{% hint style="success" %}
Notez que le `data.onSuccess()` est obligatoire dans votre code.\
Les `data.onSuccess()`et `data.onFailure()` valeurs indiquent à la plateforme quand la destination a terminé ou échoué sa tâche, et sont ensuite utilisées comme signal pour *Event Delivery* le tableau de bord et *Destination Live Invent Inspector*
{% endhint %}


---

# 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://doc.commandersact.com/fr/fonctionnalites/destinations/destination-builder/javascript-destination-builder/tutorial-how-to-build-a-server-destination-with-the-js-sandbox.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.
