# Déclencheur Event Listener

Le déclencheur Event Listener interroge une source externe sur un timer et exécute votre workflow **une fois par nouvel item**. Contrairement à Webhook (qui attend que la source push) ou Schedule (qui fire à l'aveugle), Event Listener tire activement les nouvelles données et les dédoublonne pour que vous ne voyiez chaque item qu'une seule fois.

Trois sources sont intégrées :

- **HTTP poll** — interroge tout endpoint GET JSON
- **Gmail** — interroge une boîte mail via une credential Gmail
- **Notion** — interroge une base via une intégration Notion

## Ajouter le déclencheur

1. Glissez un nœud **Event Listener** depuis la palette sur le canevas.
2. Choisissez une **Source** (HTTP poll / Gmail / Notion).
3. Renseignez les champs spécifiques à la source (ci-dessous).
4. Définissez l'**Intervalle de polling** (secondes, minimum **30**, défaut 300).
5. Choisissez une **Politique de rattrapage** — même sémantique que Schedule (`skip` / `fire_once` / `fire_all`).
6. Activez **Listener Enabled** et sauvegardez.

Le déclencheur n'est enregistré côté serveur qu'après **sauvegarde du workflow**. Le bouton **Poll now (smoke test)** reste désactivé jusque-là.

## HTTP poll

Appelle un endpoint GET (ou POST) qui retourne du JSON contenant un tableau d'items, et dédoublonne par un champ id.

| Champ          | Rôle                                                                                                   |
| -------------- | ------------------------------------------------------------------------------------------------------ |
| **URL**        | L'endpoint à appeler. Doit commencer par `http://` ou `https://`.                                   |
| **Méthode**    | `GET` (défaut) ou `POST`.                                                                            |
| **Headers JSON** | En-têtes supplémentaires comme objet JSON, ex. `{"Accept":"application/json"}`.                       |
| **Body**       | Corps de la requête (pour POST). Envoyé tel quel.                                                       |
| **Item path**  | Chemin pointé depuis la racine JSON vers le tableau d'items. `items` pour `{"items":[...]}`, `data.results` pour imbriqué, **vide** si le tableau est à la racine. |
| **ID field**   | Chemin pointé vers l'id unique dans chaque item — `id`, `uuid`, `message_id`, etc. Les items sans ce champ sont ignorés. |
| **Pagination** | Aucune, numéro de page, curseur ou URL suivante renvoyée par l'API. |
| **Taille de page** | Nombre d'éléments demandés par page (1–500). |
| **Pages maximum** | Limite de sécurité par cycle (1–50, défaut 10). Le traitement reprend au cycle suivant. |
| **Items maximum** | Nombre maximal de nouveaux workflows lancés par cycle (1–5000, défaut 500). |
| **Credential** | Credential sauvegardée optionnelle (`http_bearer` / `http_apikey` / `custom`) — override le token inline. |
| **Bearer token** | Fallback inline si aucune credential sélectionnée.                                                    |

La source doit retourner du JSON (pas XML/RSS/CSV), et chaque item doit avoir un id stable. La pagination par numéro s'arrête sur une page incomplète ou peut utiliser un chemin booléen **Has-more**. Le mode curseur lit le curseur suivant dans la réponse. Le mode URL suivante suit les liens relatifs ou absolus en validant leur sécurité à chaque requête. Si une limite est atteinte, la position est enregistrée et le traitement reprend au prochain cycle de polling.

## Gmail

Interroge une boîte Gmail et fire une fois par nouveau message.

| Champ            | Rôle                                                                       |
| ---------------- | -------------------------------------------------------------------------- |
| **Query**        | Requête de recherche Gmail, ex. `is:unread from:billing@`.                |
| **Label IDs**    | IDs de labels séparés par virgules (`INBOX`, `Label_123`).                |
| **Credential**   | Credential `gmail` sauvegardée. Requise en production.                    |
| **Bearer access token** | Fallback inline pour le test.                                         |

Le dédoublonnage est automatique via l'id Gmail du message.

## Notion

Interroge une base Notion et fire une fois par nouvelle page.

| Champ             | Rôle                                                                                  |
| ----------------- | ------------------------------------------------------------------------------------- |
| **Database ID**   | L'id Notion de la base (32 caractères, extrait de son URL).                            |
| **Filter JSON**   | Filtre Notion optionnel, ex. `{"property":"Status","status":{"equals":"To do"}}`.    |
| **Credential**    | Credential `notion` sauvegardée. Requise en production.                              |
| **Integration token** | Fallback inline pour le test.                                                      |

Le dédoublonnage est automatique via l'id de la page Notion.

## Ce que reçoit le workflow

Le listener exécute le workflow **une fois par nouvel item** trouvé. Chaque run voit :

```json
{
  "trigger_kind": "event_listener",
  "event": {
    "event_id": "msg_abc123",
    "payload": { ... }
  },
  "input":       { ... },
  "last_output": { ... }
}
```

`event.payload` est l'item brut — une ressource message Gmail, un objet page Notion, ou un élément de l'`item_path` HTTP poll. `input` et `last_output` reflètent le payload pour que les nœuds en aval puissent templater `{last_output}` directement. Référencez tout champ avec `{event.payload.subject}`, `{event.payload.properties.Status.status.name}`, etc.

Si 10 nouveaux items apparaissent entre deux polls, le workflow tourne 10 fois — une par item.

## Test : bouton "Poll now"

Le panneau de configuration a un bouton **Poll now (smoke test)**. Il lance l'adaptateur de polling **une fois, en synchrone**, contre votre configuration live et retourne :

- **URL reached — N event(s) found** avec un preview de jusqu'à 10 events, ou
- **Polling failed** avec l'erreur exacte.

Deux précautions :

1. Le bouton n'est activé qu'**après** la sauvegarde du workflow (sinon le déclencheur n'a pas d'id côté serveur).
2. Les items renvoyés par **Poll now** sont ajoutés à l'état de dédoublonnage — le prochain tick réel **ne les re-fire pas**. Pour rejouer, reset la source amont ou supprimez et recréez le déclencheur.

## Dépannage

- **0 events trouvés mais des items existent** — mauvais **Item path** (le tableau n'est pas où vous pensez) ou mauvais **ID field** (chaque item est ignoré). Vérifiez la forme de la réponse source.
- **`401` / `403` de l'amont** — credential expirée ou mauvais scope. Réauthentifiez depuis la page Credentials.
- **Le même item fire deux fois** — votre **ID field** n'est pas stable. Choisissez un champ qui ne change pas entre polls.
- **Le listener ne fire jamais** — workflow non sauvegardé, agent non **actif** (toggle Live dans l'espace Production), ou toggle **Enabled** désactivé. Le point de santé du déclencheur sur le nœud montre l'état live.
- **Les items apparaissent avec plusieurs minutes de retard** — c'est l'intervalle de polling. Réduisez-le (min 30s) pour des fires plus réactifs. Le dispatcher lui-même tick toutes les 15 s, donc les polls partent à ~15 s près de leur échéance.

---

*Source: https://agentbuilder.systalink.sn/docs/trigger-event-listener — human documentation.*
*Other language: [/docs-md/en/trigger-event-listener.md](/docs-md/en/trigger-event-listener.md).*
*Machine-readable index: [/llms.txt](/llms.txt).*
