Aller au contenu
#developpement-it

n8n tutoriel : créer sa première automatisation avec OpenAI en 4 nœuds

Un message arrive sur un Webhook, OpenAI le résume et le classe, n8n renvoie du JSON propre. Je l'ai monté en quatre nœuds sur n8n Cloud et exécuté pour de vrai : 7,962 secondes. Voici chaque réglage, les captures, le piège du premier lancement et le code complet du validateur.

Aymen Bouras14 min de lecture

Dans mes missions DevSecOps, j'utilise n8n pour automatiser ce qui gravite autour des déploiements. Le besoin est fort en ce moment. Pour ce tutoriel n8n, j'ai pris le scénario le plus court qui montre tout : un message arrive sur un Webhook, OpenAI le résume et le classe, un bout de JavaScript contrôle la réponse, et n8n la renvoie en JSON à l'appelant.

J'ai monté ce workflow sur une instance n8n Cloud et je l'ai exécuté avec un appel réel au modèle : 7,962 secondes pour les quatre nœuds, dont 5,3 passées chez OpenAI.

Workflow n8n avec quatre nœuds et résultat statusCode 200, ok true Le résultat : quatre nœuds au vert et, en bas, la réponse JSON avec son résumé, sa catégorie et son texte.

L'article suit l'ordre dans lequel vous le referez. À la fin, vous aurez un workflow qui tourne, le code complet du validateur et la commande curl pour l'appeler depuis un terminal.

n8n tutoriel : ce que l'on va construire

n8n est un outil d'automatisation qui relie des déclencheurs et des actions dans un workflow visuel : chaque nœud reçoit des données, fait une chose, et passe le résultat au suivant. Dans ce tutoriel, il reçoit un message par HTTP, interroge un modèle d'OpenAI et renvoie un objet JSON que n'importe quelle application peut lire. C'est le plus petit scénario qui fait passer par tout ce qui compte : un déclencheur, un appel d'IA, un contrôle, une réponse.

Quatre nœuds, dans cet ordre :

NœudSon rôleDonnée utile
Webhook POSTRecevoir la demandebody.message
OpenAI - Générer JSONRésumer, classer et répondreresume, categorie, reponse
Traiter et valider JSONExtraire et contrôler les champsstatusCode et body
Répondre en JSONRenvoyer la réponse à l'appelantCorps JSON et code HTTP

Le message de test est volontairement banal : « Explique simplement un déploiement automatisé ». Aucune donnée de client n'entre dans l'exemple. La réponse repart vers celui qui a appelé le Webhook. L'envoyer ailleurs (un courriel, un message Slack, un ticket) se fera ensuite en ajoutant un nœud.

Le canevas est visuel, mais le contrôle final tient dans un petit nœud JavaScript : c'est du low-code, pas du no-code pur. Pour situer la différence, notre comparatif vibe coding vs no-code aide à choisir entre configuration visuelle et code.

Étape 1 : créer le workflow et choisir la connexion OpenAI

Il vous faut une instance n8n (j'ai travaillé sur n8n Cloud) et un moyen d'appeler OpenAI depuis cette instance.

Sur la mienne, aucun credential OpenAI n'était configuré. L'éditeur proposait à la place Gateway credits, un crédit d'appel géré par n8n, et c'est lui que j'ai utilisé. Si votre instance ne le propose pas, créez une connexion OpenAI dans les credentials de n8n et sélectionnez-la dans le nœud. Dans les deux cas, la clé ne se colle jamais dans un prompt ni dans le code du workflow.

Créez un workflow et nommez-le « Première automatisation - Webhook OpenAI JSON ». Pour poser les quatre nœuds, j'ai décrit le scénario à l'assistant IA intégré à n8n, qui a généré la chaîne. On y gagne le câblage, pas la vérification : l'assistant m'a présenté une exécution simulée, et je ne m'en suis pas contenté. J'ai rouvert chaque nœud, contrôlé chaque réglage et lancé un vrai appel au modèle. Ce sont ces réglages que déroulent les étapes suivantes, et vous pouvez tout aussi bien les saisir à la main.

Avant de toucher au premier nœud, fixez le contrat. La demande reçue :

{
  "message": "Explique simplement un déploiement automatisé"
}

Et la réponse à renvoyer :

{
  "ok": true,
  "resume": "...",
  "categorie": "...",
  "reponse": "..."
}

OpenAI ne produit que resume, categorie et reponse. Le champ ok est ajouté par le validateur de l'étape 6.

Étape 2 : configurer le Webhook POST

Ajoutez un nœud Webhook et ouvrez ses paramètres :

ParamètreValeur
HTTP MethodPOST
Pathpremiere-automatisation
AuthenticationNone le temps de la mise au point
RespondUsing 'Respond to Webhook' Node

Paramètres du Webhook n8n avec méthode POST et réponse via Respond to Webhook Les quatre réglages du déclencheur. L'URL de test se copie en haut du panneau.

Le chemin donne la fin de l'URL. n8n affiche deux adresses : celle de test ne répond que pendant que l'éditeur écoute, celle de production répond quand le workflow est publié. La documentation du Webhook n8n détaille les deux modes. Copiez toujours l'adresse depuis votre propre nœud.

Le réglage qui compte est Respond. Avec Using 'Respond to Webhook' Node, c'est le dernier nœud du workflow qui décide du corps et du code de la réponse, pas le Webhook.

Authentication: None convient tant que le workflow n'est pas publié. Avec un appel d'IA derrière, on ne laisse pas une URL ouverte en production : j'y reviens à la fin.

Étape 3 : épingler une entrée pour tester sans client HTTP

Premier piège. J'ai lancé l'exécution depuis le nœud OpenAI, et n8n a répondu :

Waiting for you to call the Test URL

Logique : le workflow démarre par un Webhook, et personne ne l'avait appelé. Plutôt que de jongler entre l'éditeur et un terminal à chaque essai, j'ai arrêté l'écoute et donné au Webhook une entrée de démonstration, que n8n garde en mémoire. C'est l'épinglage.

Ouvrez Webhook POST, choisissez set mock data ou Edit Output selon l'état du panneau, puis enregistrez :

[
  {
    "headers": {},
    "query": {},
    "params": {},
    "body": {
      "message": "Explique simplement un déploiement automatisé"
    }
  }
]

Sortie JSON du Webhook avec body.message et bandeau de données épinglées Le bandeau violet signale que n8n réutilisera cette entrée à chaque exécution dans l'éditeur.

Regardez la structure. Le client HTTP n'envoie que le champ message, mais le nœud Webhook range ce contenu dans body, à côté de headers, query et params. D'où le chemin $json.body.message de l'étape suivante.

Tant que l'entrée est épinglée, chaque exécution repart de la même demande. On peut donc régler les trois nœuds suivants sans dépendre d'un appel extérieur. L'épinglage sautera à l'étape 9, pour l'appel par curl.

Étape 4 : brancher OpenAI sur le message entrant

Ajoutez le nœud OpenAI après le Webhook, avec Resource: Text et Operation: Message a Model. J'ai pris GPT-5-NANO dans la liste : pour résumer et classer une phrase, un petit modèle suffit. Si vous en choisissez un autre, vérifiez qu'il accepte les sorties structurées de l'étape 5.

Dans Messages, gardez un message de type Text, rôle User. Basculez le champ Prompt en expression et saisissez :

{{ $json.body.message }}

Nœud OpenAI avec Gateway credits, GPT-5-NANO et expression body.message Sous le champ, n8n affiche la valeur résolue de l'expression : le message épinglé. À droite, la sortie du modèle.

Dans Options, ajoutez les instructions. Les miennes, telles quelles :

Tu es un assistant pédagogique. Réponds UNIQUEMENT avec un objet JSON valide, sans texte autour, sans Markdown ni balises de code. L'objet doit contenir exactement trois clés de type string : "resume" (résumé de la demande en une phrase), "categorie" (catégorie courte du sujet, par ex. "DevOps", "Marketing", "Support"), "reponse" (réponse claire et simple en français).

Trois autres options : Maximum Number of Tokens: 2000, Reasoning Effort: Low et Summary: None. Un effort de raisonnement bas suffit pour cette tâche.

Options OpenAI avec plafond de 2000 tokens et effort de raisonnement Low Les options de génération. Le format de sortie se règle dans le même panneau, juste en dessous.

Étape 5 : imposer un schéma JSON strict

Demander du JSON dans les instructions ne suffit pas. Dans Output Format, sélectionnez JSON Schema (recommended), nommez le schéma reponse_tutoriel et activez Strict.

{
  "type": "object",
  "properties": {
    "resume": { "type": "string" },
    "categorie": { "type": "string" },
    "reponse": { "type": "string" }
  },
  "required": ["resume", "categorie", "reponse"],
  "additionalProperties": false
}

Format JSON Schema du nœud OpenAI avec trois champs obligatoires et Strict activé En mode strict, n8n le rappelle : toutes les propriétés doivent figurer dans required.

Un objet, trois chaînes, aucune propriété en plus. Avec ce réglage, le modèle n'a plus le choix de la forme : c'est le mécanisme des sorties structurées d'OpenAI, dont la documentation décrit aussi les cas particuliers, comme les refus.

Le schéma garantit la forme, pas le fond. Une réponse parfaitement structurée peut contenir un champ vide ou une explication fausse. D'où l'étape suivante.

Étape 6 : valider la réponse avec un nœud Code

Ajoutez un nœud Code, nommé Traiter et valider JSON, avec Language: JavaScript et Mode: Run Once for Each Item.

La réponse du modèle n'est pas à la racine de la sortie du nœud OpenAI. Elle est rangée dans output, puis dans content, dans une partie de type output_text. Le code commence donc par aller la chercher :

const messages = Array.isArray($json.output) ? $json.output : [];
const msg = messages.find((m) => m && m.type === "message") || messages[0] || {};
const parts = Array.isArray(msg.content) ? msg.content : [];
const part = parts.find((p) => p && p.type === "output_text") || parts[0] || {};
const raw = part.text;

Sur la capture de l'étape 4, on voit que n8n a déjà converti ce texte en objet. Le code accepte les deux cas : un objet est gardé tel quel, une chaîne passe par JSON.parse après retrait d'éventuelles balises de code Markdown.

Nœud Code JavaScript qui traite la réponse OpenAI et produit statusCode et body À droite, la sortie du nœud : un statusCode et un body prêts à être renvoyés.

Vient ensuite le contrôle des trois champs :

const champs = ["resume", "categorie", "reponse"];
const manquants = champs.filter((c) => typeof data[c] !== "string" || data[c].trim() === "");

Si tout est bon, le nœud prépare statusCode: 200 et un body avec ok: true et les trois champs nettoyés. Sinon, statusCode: 502, ok: false et un message qui dit ce qui cloche.

J'ai aussi passé ce validateur sur sept cas, hors de n8n :

EntréeCode préparé
Objet valide200
Chaîne JSON valide200
JSON entouré de balises Markdown200
JSON mal formé502
Contenu absent502
Champ vide502
Tableau à la place d'un objet502

Le code complet du nœud, à coller tel quel :

// Récupère le contenu texte renvoyé par OpenAI (objet déjà parsé ou chaîne)
const messages = Array.isArray($json.output) ? $json.output : [];
const msg = messages.find((m) => m && m.type === "message") || messages[0] || {};
const parts = Array.isArray(msg.content) ? msg.content : [];
const part = parts.find((p) => p && p.type === "output_text") || parts[0] || {};
const raw = part.text;

let data = null;
let erreur = null;
if (raw && typeof raw === "object") {
  data = raw;
} else if (typeof raw === "string") {
  // Nettoie un éventuel bloc Markdown de code autour du JSON
  const cleaned = raw
    .trim()
    .replace(/^\x60{3}(?:json)?\s*/i, "")
    .replace(/\s*\x60{3}$/, "");
  try {
    data = JSON.parse(cleaned);
  } catch (e) {
    erreur = "Réponse OpenAI non JSON : " + e.message;
  }
} else {
  erreur = "Aucun contenu texte dans la réponse OpenAI";
}

const champs = ["resume", "categorie", "reponse"];
if (!erreur) {
  if (!data || typeof data !== "object" || Array.isArray(data)) {
    erreur = "La réponse OpenAI n'est pas un objet JSON";
  } else {
    const manquants = champs.filter((c) => typeof data[c] !== "string" || data[c].trim() === "");
    if (manquants.length) erreur = "Champs manquants ou invalides : " + manquants.join(", ");
  }
}

if (erreur) {
  return { json: { statusCode: 502, body: { ok: false, erreur: erreur } } };
}

return {
  json: {
    statusCode: 200,
    body: {
      ok: true,
      resume: data.resume.trim(),
      categorie: data.categorie.trim(),
      reponse: data.reponse.trim(),
    },
  },
};

Ce validateur contrôle ce qui arrive jusqu'à lui. Une panne de l'API OpenAI en amont se traite ailleurs, j'y viens en fin d'article.

Étape 7 : renvoyer la réponse avec Respond to Webhook

Ajoutez un nœud Respond to Webhook, nommez-le Répondre en JSON et reliez-le au validateur.

ChampValeur
Respond WithJSON
Response Body, en expression{{ JSON.stringify($json.body) }}
Response Code, en expression{{ $json.statusCode }}
Response Headers, NameContent-Type
Response Headers, Valueapplication/json; charset=utf-8

Respond to Webhook configuré pour JSON avec code dynamique et Content-Type application/json Le corps et le code de la réponse viennent tous les deux du validateur.

Le code de réponse est dynamique : 200 quand le validateur est satisfait, 502 sinon. L'appelant sait donc, sans lire le corps, si la réponse est exploitable.

Ce nœud ne fonctionne qu'avec le réglage Using 'Respond to Webhook' Node de l'étape 2. La documentation Respond to Webhook liste ses cas limites, dont celui qui nous concerne : sans appel Webhook entrant, n8n ignore le nœud. Dans l'éditeur, avec l'entrée épinglée, vous voyez donc les données qui le traversent. La réponse HTTP, elle, part sur un appel réel, à l'étape 9.

Étape 8 : exécuter le workflow et lire les durées

Avec l'entrée épinglée, cliquez sur Execute workflow. Les quatre nœuds passent au vert. OpenAI classe la demande en DevOps, la résume (« Demande d'explication simple d'un déploiement automatisé. ») et rédige l'explication en français.

Journal n8n avec succès en 7,962 secondes et durée de chaque nœud Le journal donne la durée de chaque nœud. L'appel au modèle pèse les deux tiers du total.

NœudDurée relevée
Webhook (entrée épinglée)1 ms
OpenAI5,294 s
Validation JavaScript1,619 s
Répondre en JSON4 ms
Exécution complète7,962 s

C'est un relevé sur une exécution, pas une moyenne. L'ordre de grandeur reste le bon repère : dans un workflow de ce type, c'est le modèle qui fixe le temps de réponse, pas n8n. Plus surprenant, le nœud Code prend 1,6 seconde pour quelques lignes de JavaScript.

Pour essayer une autre demande, modifiez body.message dans l'entrée épinglée et relancez. Chaque exécution appelle le modèle, donc consomme du crédit.

Étape 9 : appeler le Webhook avec curl

Dernière étape : sortir de l'éditeur.

  1. Dans Webhook POST, retirez l'épinglage avec Unpin.
  2. Cliquez sur Listen for test event.
  3. Copiez l'URL de test complète affichée dans le nœud.
  4. Envoyez la demande depuis un terminal.
curl -i --request POST 'https://VOTRE-INSTANCE/webhook-test/premiere-automatisation' \
  --header 'Content-Type: application/json' \
  --data '{"message":"Explique simplement un déploiement automatisé"}'

Remplacez l'adresse par celle de votre nœud, telle quelle : elle contient déjà /webhook-test/premiere-automatisation, n'ajoutez rien derrière. La réponse attendue tient en trois éléments : un code 200, l'en-tête Content-Type: application/json; charset=utf-8 et le corps JSON à quatre champs. Côté n8n, une nouvelle exécution apparaît, avec cette fois les en-têtes de votre requête dans la sortie du Webhook.

L'URL de test sert à la mise au point. Pour une adresse permanente, publiez le workflow avec le bouton Publish : l'URL de production prend le relais, en /webhook/ au lieu de /webhook-test/.

Avant la production : trois réglages à ajouter

Le workflow fait ce qu'on lui demande : il reçoit, interroge, contrôle, répond. Côté sécurité applicative, trois points restent à traiter avant de l'exposer.

Fermer l'accès. Avec Authentication: None, quiconque connaît l'URL déclenche un appel payant au modèle. Le nœud Webhook propose Basic Auth, Header Auth et JWT Auth : choisissez-en un avant de publier, et décidez combien de requêtes un appelant peut envoyer.

Contrôler l'entrée. Le workflow transmet body.message au modèle sans le regarder. Un message vide part quand même chez OpenAI. Un nœud If placé avant l'appel refuse proprement ces demandes, avec un code 400.

Prévoir la panne du fournisseur. Le validateur ne couvre que les réponses qui lui parviennent. Un délai dépassé ou une erreur de l'API se règlent dans l'onglet Settings du nœud OpenAI, avec Retry On Fail et le comportement On Error.

Une précision pour éviter le malentendu : ce workflow explique un déploiement automatisé, il n'en lance aucun. Brancher n8n sur un pipeline ou sur une action d'administration est un autre chantier, avec ses permissions et ses validations.

Formation intra n8n

Vos propres workflows n8n, construits avec un formateur qui les utilise en mission

L'équipe travaille sur ses processus réels, en direct avec le formateur, dans vos locaux ou en classe virtuelle. Durée recommandée : 21 à 35 heures, ajustée au besoin. Formation intra sur mesure, finançable via votre OPCO, sous réserve de l'éligibilité de l'entreprise et de l'accord du conseiller OPCO.

  • Définir les entrées et les sorties de vos automatisations
  • Relier vos outils, tester les données et contrôler les réponses de l'IA
  • Sécuriser et documenter les workflows pour que l'équipe les reprenne

Passer de l'exemple à une formation n8n en équipe

Ce tutoriel donne le squelette : une entrée connue, une sortie attendue, un résultat qu'on peut inspecter. En entreprise, le travail commence quand on remplace le message de démonstration par un vrai processus, avec ses outils, ses droits d'accès et ses cas d'erreur.

C'est l'objet de la formation n8n de Mill-Forma : l'équipe construit ses propres workflows, sur ses propres outils, avec un formateur en direct. Le programme couvre les déclencheurs, les transformations, les connexions aux outils métiers, l'intégration de l'IA et la fiabilisation des automatisations. Le format est intra-entreprise, en présentiel ou en classe virtuelle, pour une durée recommandée de 21 à 35 heures, ajustée au contexte.

Pour une équipe de développeurs qui veut aller plus loin sur l'intégration d'API et de modèles, la fiche IA pour développeurs complète ce parcours.

Pour aller plus loin

FAQ : n8n tutoriel et première automatisation

Faut-il savoir coder pour suivre ce tutoriel n8n ?+

Non pour l'essentiel : les connexions et les paramètres se règlent dans l'interface. Le seul code est un nœud JavaScript d'une cinquantaine de lignes, donné en entier à l'étape 6 et à coller tel quel. Pour adapter le workflow, il faut comprendre ce qu'est un champ JSON et lire une expression comme body.message.

Pourquoi n8n affiche-t-il « Waiting for you to call the Test URL » ?+

Le workflow démarre par un Webhook, qui attend une demande entrante avant de passer des données aux nœuds suivants. Deux solutions : lancer l'écoute puis envoyer un POST à l'URL de test, ou épingler une entrée de démonstration dans le nœud Webhook pour travailler dans l'éditeur.

Une exécution verte dans l'éditeur prouve-t-elle que la réponse HTTP est partie ? +

Pas avec une entrée épinglée. Dans ce cas, n8n exécute les nœuds mais ignore l'envoi du nœud Respond to Webhook, faute d'appelant. Pour vérifier le retour HTTP, retirez l'épinglage, lancez l'écoute et appelez l'URL de test avec curl.

Faut-il une clé OpenAI pour utiliser OpenAI dans n8n ?+

Pas toujours. Sur l'instance n8n Cloud utilisée pour ce tutoriel, l'éditeur proposait des Gateway credits, un crédit d'appel géré par n8n. Si votre instance ne le propose pas, créez une connexion OpenAI dans les credentials de n8n et sélectionnez-la dans le nœud.

Un schéma JSON strict garantit-il que la réponse de l'IA est juste ?+

Non. Le schéma impose la forme de la sortie : un objet, trois chaînes, rien d'autre. Le validateur vérifie ensuite que les champs sont présents et non vides. Aucun des deux ne contrôle l'exactitude de ce que le modèle écrit : un contenu sensible se relit avant diffusion.

Aymen Bouras

Auteur

Aymen Bouras

Ingénieur DevSecOps et formateur (cybersécurité, Python, sécurité applicative)

Il travaille sur le développement Python, le DevSecOps et la sécurité applicative. Il utilise n8n pour automatiser des tâches dans ses missions, notamment autour des déploiements.

Profil LinkedIn

La formation sur ce sujet

n8n : automatisation en no code avec l'IA

Cette formation permet de concevoir des automatisations utiles avec n8n et d’intégrer des logiques d’IA dans des processus métiers sans développement avancé.

≈ 21 à 35 heuresIntra entreprise, sur-mesure