Webhook générique — recettes prêtes à l'emploi

Trois recettes copiables pour connecter votre bot à Notion, HubSpot ou Zapier/Make via le modèle webhook générique, quand aucun connecteur dédié n'existe.

Dernière mise à jour :

Pour qui est cet article

Vous cherchez à connecter votre bot à un outil pour lequel Sens-AI ne fournit pas encore de modèle dédié : Notion, HubSpot, Pipedrive, Airtable, votre CRM maison, ou plus généralement n’importe quel service exposant un webhook. Le webhook générique est fait pour ça.

Cet article complète Créer une action personnalisée avec trois recettes concrètes : Notion (créer une page), HubSpot (créer un contact), et Zapier / Make (déclencher un Zap ou un scénario qui fera le reste).

Avant de poursuivre : si un connecteur dédié existe pour votre outil (Jira, Slack, Calendly, etc.), utilisez-le. Il est mieux instrumenté, plus permissif sur les paramètres, et déjà validé. Le webhook générique reste la solution de repli.

Comment fonctionne le webhook générique

Côté connecteur, vous renseignez :

  • URL de base — l’URL exacte qui recevra l’appel (pas de ? ni de paramètres dynamiques).
  • Type d’authentificationnone, bearer ou header. Ce champ sert uniquement au test du connecteur depuis le dashboard ; à l’exécution réelle de l’action, c’est toujours un header Authorization dont la valeur est exactement la Valeur d’authentification ci-dessous qui est envoyé (voir l’encadré ci-dessous).
  • Valeur d’authentification — chiffrée au repos, jamais loggée en clair. À l’exécution, cette valeur est envoyée telle quelle dans le header Authorization. Si votre destination attend Bearer <token>, c’est à vous d’inclure le préfixe Bearer (avec l’espace) dans ce champ. Si elle attend Basic ... ou tout autre schéma, idem.
  • Nom du header — sert uniquement au test du connecteur. À l’exécution, le header est toujours nommé Authorization ; ce champ est ignoré.

Limitation actuelle du webhook générique à l’exécution. Le test du connecteur (bouton « Tester » du dashboard) honore bien Type d'authentification et Nom du header : un test bearer ajoute le préfixe Bearer et un test header utilise le nom de header personnalisé. Mais à l’exécution réelle de l’action (appel déclenché par le bot pendant une conversation), le descripteur envoie inconditionnellement un header Authorization contenant la valeur brute. Conséquence : un test peut réussir alors qu’un appel réel échoue en 401, et inversement. En attendant la mise en cohérence du descripteur, suivez ces deux règles : (1) pour une auth Bearer, incluez Bearer dans la valeur ; (2) si votre destination exige un header autre que Authorization (ex. X-API-Key), le webhook générique ne convient pas — passez par un relais (Zapier / Make / Cloudflare Worker) qui réémet la requête avec le bon header.

Côté action, vous choisissez seulement :

  • Méthode HTTPGET, POST, PUT, PATCH, DELETE (par défaut POST).
  • Body — un seul paramètre body de type chaîne que le bot remplit à la volée en fonction de la conversation.

À l’exécution, Sens-AI envoie une requête HTTP avec :

  • L’URL exacte du connecteur (pas de templating sur l’URL côté action).
  • Les headers Content-Type: application/json + le header d’authentification du connecteur.
  • Un corps JSON de la forme :
{ "data": "<contenu produit par le bot>" }

Le délai d’attente est de 10 secondes. Au-delà, l’action échoue.

Important — limitation structurelle du wrapper { "data": ... }. Le bot ne peut pas envoyer directement un JSON arbitraire au format attendu par une API tierce (par exemple le corps précis attendu par Notion ou HubSpot). Ce que le bot produit est toujours encapsulé dans { "data": "…" }. Pour les API qui exigent une structure JSON spécifique, vous avez deux options : (1) passer par Zapier / Make qui sait lire ce wrapper et reformater ; (2) écrire un petit relais (Cloudflare Worker, fonction serverless, mini-backend) qui reçoit { "data": "…" } et appelle l’API tierce avec le bon format.

Les recettes ci-dessous tiennent compte de cette contrainte.

Recette 1 — Notion (créer une page) via un relais

L’API Notion attend un corps JSON très structuré (parent, properties.Name.title[0].text.content, etc.). Le webhook générique ne peut pas produire cette structure directement. La méthode propre est d’utiliser Zapier ou Make en relais — c’est aussi le cas le plus simple.

Recette 1a — Via Zapier (recommandée)

  1. Dans Zapier, créez un Zap avec Trigger = Webhooks by ZapierCatch Hook. Copiez l’URL de webhook fournie par Zapier (ex. https://hooks.zapier.com/hooks/catch/12345/abcdef/).
  2. Dans Zapier, ajoutez une Action = NotionCreate Database Item. Connectez votre espace Notion, choisissez la base de données cible (ex. « Leads »), et mappez les champs depuis data (les valeurs envoyées par Sens-AI seront accessibles sous data dans l’éditeur Zapier).
  3. Côté Sens-AI :
    • Bot → Actions → onglet ConnecteursAjouter un connecteur → modèle Webhook générique.
    • URL de base : l’URL Zapier copiée à l’étape 1.
    • Type d’authentification : none (Zapier n’exige pas d’auth sur ses Catch Hook).
    • Nommez le connecteur : Zapier — Notion Leads.
  4. Bot → ActionsAjouter une action → modèle Webhook générique.
    • Sélectionnez le connecteur Zapier — Notion Leads.
    • Méthode HTTP : POST.
    • Nom de l’action : Enregistrer un lead dans Notion.
    • Description (pour l’IA) : indispensable pour que le bot déclenche l’action au bon moment. Exemple : « À utiliser quand un visiteur souhaite être contacté commercialement, ou laisse ses coordonnées. Construis le body au format JSON sérialisé avec les clés name, email, company, message. »
  5. Testez l’action depuis le dashboard (Tester et déboguer) : Zapier doit recevoir le hook, et une nouvelle ligne doit apparaître dans votre base Notion.

Côté contenu, le bot enverra typiquement :

{ "data": "{\"name\":\"Marie Dupont\",\"email\":\"marie@acme.fr\",\"company\":\"Acme\",\"message\":\"Demande de démo\"}" }

Dans l’éditeur Zapier, vous récupérez les champs via data → name, data → email, etc. (Zapier sait analyser le JSON imbriqué automatiquement, ou utilisez l’étape Code by ZapierRun JavaScript avec JSON.parse(inputData.data) si besoin).

Recette 1b — Via Make (Integromat)

Identique à Zapier, en remplaçant l’étape 1 par : créez un scénario Make avec un module WebhooksCustom webhook → copiez l’URL générée. Ajoutez ensuite un module NotionCreate a Database Item. Make analyse automatiquement le JSON imbriqué dans data.

Recette 1c — Sans relais (avancé)

Si vous ne voulez pas dépendre de Zapier ou Make, écrivez un petit Cloudflare Worker (ou une AWS Lambda, ou un endpoint sur votre backend) qui :

  1. Reçoit la requête POST de Sens-AI avec { "data": "…JSON…" }.
  2. Fait JSON.parse(body.data).
  3. Appelle l’API Notion https://api.notion.com/v1/pages avec le payload reformaté et votre Notion-Version + Authorization: Bearer secret_xxx.

Dans ce cas, le connecteur Sens-AI pointe vers l’URL de votre relais, pas vers Notion directement.

Recette 2 — HubSpot (créer un contact) via un relais

L’API HubSpot attend un corps de la forme { "properties": { "email": "...", "firstname": "..." } }. Comme pour Notion, le wrapper { "data": "..." } du webhook générique empêche un appel direct propre. Le scénario recommandé est exactement le même que pour Notion.

Recette 2a — Via Zapier (recommandée)

  1. Dans Zapier, créez un Zap avec Trigger = Webhooks by ZapierCatch Hook. Copiez l’URL.
  2. Action = HubSpotCreate or Update Contact. Connectez votre portail HubSpot, mappez les champs depuis data (email, firstname, lastname, phone, company, etc.).
  3. Côté Sens-AI :
    • Connecteur Webhook générique → URL = l’URL Zapier, auth none, nom Zapier — HubSpot Contacts.
    • Action → modèle Webhook générique, connecteur ci-dessus, méthode POST.
    • Description (pour l’IA) : « À déclencher quand un visiteur laisse ses coordonnées (email + nom). Construis le body au format JSON sérialisé avec les clés email, firstname, lastname, phone (optionnel), company (optionnel). »
  4. Testez depuis le dashboard. Vérifiez la création du contact dans HubSpot → Contacts.

Recette 2b — Appel direct HubSpot (déconseillé en l’état)

Techniquement, vous pouvez pointer le connecteur directement sur https://api.hubapi.com/crm/v3/objects/contacts avec une auth bearer (token privé HubSpot). Mais le corps envoyé sera { "data": "…chaîne JSON…" }, ce qui n’est pas accepté par l’API HubSpot : elle renverra une erreur 400. C’est précisément pour ce cas que le relais Zapier / Make est nécessaire.

Recette 3 — Zapier / Make (déclencher un Zap ou scénario)

C’est la recette la plus naturelle : Zapier et Make sont conçus pour recevoir un payload générique et l’orchestrer ensuite vers la destination finale. Le wrapper { "data": "..." } n’est pas un problème — vous le déballez côté Zapier / Make.

Recette 3a — Zapier (Catch Hook)

  1. Dans Zapier, créez un Zap avec Trigger = Webhooks by ZapierCatch Hook. Copiez l’URL.
  2. Ajoutez toutes les actions Zapier souhaitées : Slack, Google Sheets, Mailchimp, Salesforce, Trello, etc. Plus de 6000 intégrations disponibles.
  3. Côté Sens-AI :
    • Connecteur : modèle Webhook générique, URL = URL Zapier, auth none. Nom : Zapier — <nom du Zap>.
    • Action : modèle Webhook générique, méthode POST, description claire pour l’IA décrivant quand l’action doit être déclenchée.
  4. Lors du test côté Zapier (étape Test trigger), exécutez l’action depuis Sens-AI : Zapier capturera le payload réel { "data": "…" } et vous pourrez mapper les champs facilement.

Recette 3b — Make (Custom Webhook)

  1. Dans Make, créez un scénario avec un module WebhooksCustom webhookAdd → copiez l’URL générée.
  2. Cliquez sur Run once dans Make pour qu’il écoute.
  3. Côté Sens-AI : connecteur Webhook générique pointant vers l’URL Make, action Webhook générique en POST.
  4. Déclenchez l’action une fois depuis Sens-AI : Make enregistre la structure du payload et vous pouvez ensuite chaîner Notion, HubSpot, Airtable, Gmail, etc.

Recette 3c — n8n (auto-hébergé)

Si vous hébergez votre propre n8n, créez un workflow avec un nœud Webhook en mode POST. Pour sécuriser l’appel, activez l’authentification Header Auth côté n8n et configurez-la sur le header Authorization (et non un header personnalisé comme X-N8N-Token) : à l’exécution, le webhook générique envoie toujours un header Authorization, jamais un header personnalisé. Côté Sens-AI, mettez la valeur secrète attendue par n8n dans Valeur d’authentification (préfixée par Bearer si n8n est configuré en Bearer Auth).

Limitations à connaître avant de promettre quoi que ce soit

  • Body toujours encapsulé dans { "data": "<string>" }. Le bot ne peut pas produire un JSON arbitraire en racine. Conséquence : les API tierces qui exigent une structure JSON précise (Notion, HubSpot, Stripe, Airtable, etc.) ne peuvent pas être appelées directement par le webhook générique. Passez par Zapier / Make / un relais.
  • Une seule URL par connecteur. L’URL est fixée au niveau du connecteur, l’action ne peut pas la modifier. Pour cibler plusieurs endpoints, créez plusieurs connecteurs.
  • Pas de paramètres dynamiques dans l’URL. Pas de ?id={{...}} ni de segment de chemin variable. L’URL envoyée est exactement celle du connecteur.
  • Header d’auth figé à Authorization à l’exécution. Le bouton « Tester » du dashboard honore le Type d'authentification et le Nom du header du connecteur, mais à l’exécution réelle de l’action, le webhook envoie toujours un header Authorization contenant la Valeur d’authentification telle quelle (sans préfixe Bearer ajouté automatiquement). Pour Bearer, incluez Bearer dans la valeur. Pour un header autre que Authorization, passez par un relais (Zapier / Make / Worker).
  • Réponse non analysée. Le message de retour est figé à « Webhook exécuté avec succès » — le bot ne sait pas extraire un champ de la réponse pour le restituer au visiteur (ex. : impossible d’annoncer « Votre contact a été créé sous l’ID 1234 »). Si vous avez besoin d’un retour structuré, utilisez plutôt une action personnalisée où vous contrôlez le responseMapping.
  • Délai d’attente 10 s. Si votre destination (Zapier, Make, votre backend) ne répond pas en moins de 10 secondes, l’action échoue. Zapier répond généralement en moins d’une seconde sur un Catch Hook, donc ce n’est pas un problème en pratique.
  • Pas de retry applicatif côté webhook générique. En cas d’erreur 5xx ou de timeout, l’action est marquée en échec. Le bot informera le visiteur sans réessayer automatiquement.
  • Méthode GET peu utile. Avec GET, le body n’est pas envoyé, et l’URL étant fixe, il n’y a aucune façon de paramétrer la requête côté action. Réservez GET aux cas où l’URL fixe suffit (ex. : déclencher un endpoint « cron » côté serveur).

Dépannage

Erreur 400 — Bad Request

La destination refuse le corps de la requête. Cause la plus fréquente : vous avez pointé le connecteur directement sur l’API tierce (Notion, HubSpot, Airtable) au lieu de passer par un relais. Vérifiez avec votre destination quel format elle attend, et insérez un Zap / scénario Make si nécessaire.

Erreur 401 ou 403 — Unauthorized / Forbidden

L’authentification est refusée. À l’exécution, le webhook générique envoie toujours un header Authorization contenant la Valeur d’authentification telle quelle.

  • Le test du connecteur passe mais l’appel réel échoue en 401. Cas classique : vous avez choisi bearer et saisi uniquement le token. Le test ajoute Bearer automatiquement, mais l’exécution non. Correctif : préfixez la valeur par Bearer (avec l’espace), par exemple Bearer secret_xxx. Re-testez ensuite — le test marchera toujours.
  • Votre destination exige un header autre que Authorization (ex. X-API-Key, Api-Token, X-Auth-Token). Le webhook générique ne permet pas de changer le nom du header à l’exécution. Utilisez un relais (Zapier / Make / Cloudflare Worker) qui recevra l’appel et le réémettra avec le bon header.
  • Auth Basic : préfixez par Basic la valeur encodée en base64 (Basic dXNlcjpwYXNz).
  • Type none : votre destination attend une authentification que vous n’avez pas configurée. Reconfigurez la valeur avec le schéma complet (Bearer ..., Basic ..., etc.).

Erreur 404 — Not Found

L’URL de base du connecteur est incorrecte. Recopiez-la depuis Zapier / Make / votre backend. Attention aux espaces en début ou fin de chaîne.

Erreur ou timeout côté Zapier

Si le Zap échoue côté Zapier mais que Sens-AI reçoit un 200 : c’est normal, Zapier accuse réception du hook immédiatement et exécute les actions ensuite. Consultez l’historique du Zap dans Zap History pour voir l’erreur réelle (champ manquant, format incorrect, quota Zapier dépassé, etc.).

Le bot ne déclenche jamais l’action

C’est presque toujours un problème de description. Le modèle de langage lit la description pour décider quand utiliser l’action. Si elle est vague (« Webhook personnalisé »), il ne déclenchera jamais. Soyez précis sur le quand : « À utiliser quand le visiteur laisse ses coordonnées commerciales (email + nom) ». Voir aussi Configurer les champs à collecter.

Comment voir le contenu réel envoyé

Le moyen le plus simple est d’utiliser un service comme webhook.site ou requestbin.com :

  1. Créez une URL jetable.
  2. Configurez temporairement le connecteur Sens-AI sur cette URL.
  3. Exécutez un test depuis le dashboard.
  4. Vous voyez exactement le corps { "data": "…" } que reçoit votre destination.

Très utile pour valider la structure JSON produite par le bot avant de la connecter en production.

Bonnes pratiques

  • Un connecteur par destination. Plus simple à révoquer en cas de fuite de jeton et plus clair à auditer.
  • Nommez les connecteurs et actions par destination, pas par technologie. Zapier — HubSpot Contacts est plus parlant que Webhook 3.
  • Préférez Zapier / Make pour les vraies API. Vous évitez la limitation du wrapper { "data": ... } et vous bénéficiez du retry, du logging et de l’historique côté Zapier / Make.
  • Utilisez une action personnalisée plutôt que le webhook générique si vous avez besoin de paramètres typés (e-mail, téléphone, choix) collectés explicitement auprès du visiteur, ou si vous voulez restituer un champ de la réponse au visiteur. Voir Créer une action personnalisée.
  • Rotez vos jetons tous les 6 mois et après chaque départ d’employé qui y a eu accès.

Étape suivante

Cet article vous a-t-il été utile ?

À lire aussi dans cette section