Premier workflow : déclenchement manuel → modification de champ → code
Le calcul des devis, je l'ai fait à la main dans un tableur pendant deux ans : quantité multipliée par prix unitaire, plus les frais de port, puis division pour obtenir le coût unitaire. Deux cents sacs, prix unitaire 1,85, frais de port 60, l'ensemble revient à 430, soit 2,15 l'unité. Les chiffres ne sont pas complexes, le problème c'est que j'ai oublié les frais de port deux fois, et le devis était déjà parti chez le client.
Ensuite, ce calcul a été transféré dans n8n, trois nœuds, on change un chiffre et on relance, deux secondes pour obtenir un nouveau prix. Cet article couvre les trois étapes, de la toile vierge au fonctionnement, y compris le piège où j'ai calculé 430 comme 37060 la première fois.
Il n'y a que deux prérequis : n8n est déjà installé et s'ouvre (si ce n'est pas le cas, voir《Comment installer n8n》), et les trois éléments que sont la toile, le panneau de nœuds et l'historique d'exécution vous sont familiers (sinon, consultez《Visite guidée de l'interface》). Pas besoin de savoir coder, il suffit de copier le bloc de code tel quel.
- Trois nœuds, chacun gère une chose
- Ce qui circule réellement entre les nœuds
- De la toile vierge aux trois nœuds
- Nœud Edit Fields : ajouter quatre champs à une donnée
- Nœud Code : prendre une entrée, calculer une fois, renvoyer une sortie
- Lancer une exécution, observer la sortie
- Annexe : le JSON complet du workflow
- Comment vérifier que ça fonctionne réellement
- Cinq erreurs qui se produisent vraiment
- Les trois limites du nœud Code
Trois nœuds, chacun responsable d'une chose
L'erreur la plus fréquente chez les débutants est de prendre ces trois nœuds pour « trois étapes ». Ce ne sont pas des étapes, ce sont trois rôles.
- Manual Trigger (déclenchement manuel): génère une donnée vide et la fait circuler vers le bas. Il n'interroge pas de base de données, ne reçoit pas de requête, ne regarde pas l'heure, c'est purement « tu cliques une fois, il s'exécute une fois ». On l'utilise dans le premier workflow pour réduire les variables à une seule — la question de l'origine des données n'a pas à être traitée pour l'instant.
- Edit Fields (édition de champs): ajoute des champs dans l'item, ou modifie ceux qui existent. Le nombre de lignes ne change pas : une entrée donne une sortie. Dans les anciens tutoriels il s'appelle Set, le renommage date d'un moment, le panneau de nœuds de la 2.43.7 affiche Edit Fields (Set), les deux noms sont trouvables.
- Code (code): la seule étape capable de modifier le nombre de lignes. Une ligne peut être divisée en plusieurs, plusieurs peuvent être compressées en une. C'est pourquoi sa valeur de retour doit être un tableau — c'est sa plus grande différence avec les autres nœuds, et aussi la source de la plupart des erreurs.
Mon instance est en 2.43.7, l'interface est passée en chinois simplifié. Une mise en garde : l'interface chinoise ne traduit que les textes descriptifs et les boutons, les noms de nœuds et de paramètres restent en anglais. Si tu cherches « 编辑字段 », tu ne trouveras rien, il faut chercher edit fields. Les tutoriels en ligne qui parlent du « nœud Set » ou du « Keep Only Set Fields du nœud Set » ne correspondent pas non plus à l'interface 2.x, ne doute pas de toi.
Ce qui circule réellement entre les nœuds
Sans clarifier cela, chaque erreur par la suite ne pourra être résolue qu'à l'aveugle.
Dans n8n, toutes les données qui circulent entre les nœuds forment un tableau, et chaque élément du tableau ressemble à ceci :
[
{ "json": { "qty": 200 } },
{ "json": { "qty": 150 } }
]
Les crochets externes représentent un « lot », à l'intérieur chaque objet est une donnée, que n8n appelle item. Les vrais champs métier sont insérés dans json cette clé. Donc « traiter 200 commandes » dans ce modèle ne signifie pas boucler 200 fois, mais fournir 200 items au nœud en une seule fois, et le nœud les traite un par un.
Cette conception a deux conséquences. La bonne nouvelle, c'est que le nœud traite naturellement en lot, vous n'avez pas à écrire de boucle. La mauvaise nouvelle, c'est que lorsque vous écrivez du code, vous avez entre les mains un tableau, pas un objet unique —row.qty cette syntaxe ne peut pas être appliquée directement sur un tableau, il faut d'abord extraire le premier élément.
Du canevas vide aux trois nœuds
- En haut à droite de la liste des workflows, « Nouveau workflow », ou tapez directement dans la barre d'adresse
/workflow/new. Je préfère la seconde méthode, plus rapide. - Sur le canevas vide, cliquez en haut à droite sur ce +(vous pouvez aussi cliquer sur le plus au centre du canevas), le panneau affiche « Que se passe-t-il ensuite ? ».
- Dans la barre de recherche, tapez
manual trigger, sélectionnez Manual Trigger. - Survolez le petit point à droite du nœud, un +apparaît, cliquez dessus, recherchez
edit fields, sélectionnez Edit Fields (Set). En procédant ainsi, les connexions se font automatiquement, sans avoir à les glisser manuellement. - Répétez l'opération une fois de plus, recherchez
code, sélectionnez Code. - Le nom du nœud est en anglais par défaut. Un double-clic sur le titre permet de le modifier ; je l'ai changé en chinois : déclenchement manuel, remplissage du devis, calcul du montant. Quand les nœuds se multiplient, les noms anglais se résument à Trigger, Set, Code au premier coup d'œil ; les renommer en chinois vise uniquement à ménager les yeux, sans aucun impact fonctionnel.

Éditer les champs : ajouter quatre champs à une entrée de données
Double-cliquez sur « remplissage du devis » pour ouvrir le panneau ; seuls deux paramètres sont à modifier.
Mode conservez Manual Mapping, c'est-à-dire la saisie sous forme de formulaire. L'autre option, JSON Output, consiste à écrire directement un bloc JSON, plus pratique pour les structures imbriquées ; au stade débutant, ne l'utilisez pas pour l'instant.
Fields to Set ajoutez-y quatre lignes. Pour chaque ligne, le nom du champ à gauche, la liste déroulante de type au milieu, la valeur à droite :
| nom du champ | type | 值 |
|---|---|---|
| product | chaîne de caractères | sac de compression sous vide 60x80cm |
| qty | nombre | 200 |
| unit_price | nombre | 1.85 |
| freight | nombre | 60 |
Le menu déroulant de type est par défaut sur « chaîne de caractères » ; les trois champs qty, unit_price et freight doivent être modifiés manuellement en « nombre ». L'interface ne vous bloquera pas ; si vous vous trompez, elle ne signalera aucune erreur et enregistrera tranquillement 200 sous la forme "200". Pour mesurer l'ampleur de ce piège, le calcul suivra plus bas.

row.unit_price, un caractère manquant et c'est undefined.Le dernier en bas du panneau Include Other Input Fields L'interrupteur, activé par défaut, signifie « les champs que je n'ai pas touchés dans l'entrée sont émis tels quels ». L'entrée de ce flux est vide, que l'interrupteur soit activé ou désactivé, cela ne change rien. Mais pour un flux contenant des données, le désactiver équivaut à supprimer tous les champs en amont, ne laissant que les quatre que vous avez saisis manuellement — à ce moment-là, si le code ne récupère pas product, ne croyez pas que le code est mal écrit.
Nœud Code : prendre un élément, calculer une fois, renvoyer un élément
Double-cliquez sur « Calculer le montant ».Mode Conserver Run Once for All Items(exécuter tout le tableau une fois),Language Conserver JavaScript. Collez ensuite le bloc suivant dans la zone d’édition :
const row = items[0].json;
const amount = row.qty * row.unit_price + row.freight;
const unitCost = Number((amount / row.qty).toFixed(2));
return [{
json: {
product: row.product,
qty: row.qty,
amount,
unitCost,
summary: row.product + ' ' + row.qty + ' 个,含运费合计 ' + amount + ' 元,单个成本 ' + unitCost + ' 元',
},
}];
Ligne par ligne, je ne signale que ce qui peut poser problème.
items[0].json On prend le premier élément. Ici il n’y a qu’une seule donnée, donc [0] suffit. Pour le cas multi-éléments, il faut écrire items.map(...), ce sera pour le prochain article.items est l’ancienne syntaxe, encore utilisable en 2.x ; la nouvelle syntaxe est $input.first().json, les deux donnent exactement le même résultat sur cette instance. Je garde items, parce que dans le mode « Run Once for All Items », vous avez déjà tout le tableau entre les mains, ce nom est plus honnête.
toFixed(2) Ce n’est pas pour faire joli. 430 divisé par 200 donne exactement 2.15, ça paraît propre ; avec des frais de port de 55, on obtient 2.175, et le calcul en virgule flottante peut donner 2.1749999999999998. Écrit dans un tableau ou envoyé à un client, ce genre de queue est difficile à présenter. La couche externe Number() C'est pour la reconvertir d'une chaîne de caractères en nombre —toFixed Ce qui est renvoyé est une chaîne de caractères ; sans conversion, unitCost sera aligné à gauche dans le tableau.
Le passage à la fin return est le point clé.Renvoie un array, chaque élément est enveloppé dans un json. n8n se sert de cette clé json pour distinguer « ce sont des données métier » de « ce sont des pièces jointes binaires ». Si le format est incorrect, le node passe directement au rouge.

Exécutez une fois, regardez la sortie
Cliquez sur le bouton orange « Exécuter » en bas du canevas. Une ou deux secondes plus tard, les bordures des trois nodes deviennent vertes, une petite coche apparaît en haut à droite de chaque node, et « 1 élément » est indiqué au milieu de la connexion.

Double-cliquez sur « Calculer le montant », puis dans la zone de sortie à droite, basculez sur l'onglet JSON :

Soit dit en passant, un point souvent mal compris : ce bouton « Exécuter » ne s'exécute que lorsque vous cliquez dessus. Un workflow Manual Trigger ne se met pas à tourner tout seul parce qu'il a été publié ; il n'a pas de mécanisme d'« exécution automatique ». Pour une exécution planifiée, il faut passer à un déclencheur du type Schedule Trigger.
Annexe : le JSON complet du workflow
Si vous ne voulez pas cliquer sur les nodes, vous pouvez tout importer. Copiez le passage ci-dessous, puis dans une zone vide du canevas, appuyez sur Ctrl+V, les trois nœuds tombent directement sur le canevas. Passer par le menu fonctionne aussi : en haut à droite ⋯ → Importer → Importer depuis un fichier, enregistrez d'abord le contenu sous .json。
J'ai moi-même collé ceci dans un workflow vide et l'ai exécuté une fois : trois nœuds, deux liens, positions correctes, et après exécution amount vaut bien 430.
{
"name": "第一个工作流",
"nodes": [
{"parameters":{},"id":"m1","name":"手动触发","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[-368,0]},
{"parameters":{"assignments":{"assignments":[
{"id":"a1","name":"product","value":"真空压缩袋 60x80cm","type":"string"},
{"id":"a2","name":"qty","value":200,"type":"number"},
{"id":"a3","name":"unit_price","value":1.85,"type":"number"},
{"id":"a4","name":"freight","value":60,"type":"number"}
]},"includeOtherFields":true,"options":{}},"id":"m2","name":"填写报价单","type":"n8n-nodes-base.set","typeVersion":3.5,"position":[-144,0]},
{"parameters":{"jsCode":"const row = items[0].json;nconst amount = row.qty * row.unit_price + row.freight;nconst unitCost = Number((amount / row.qty).toFixed(2));nnreturn [{n json: {n product: row.product,n qty: row.qty,n amount,n unitCost,n summary: row.product + ' ' + row.qty + ' 个,含运费合计 ' + amount + ' 元,单个成本 ' + unitCost + ' 元',n },n}];","mode":"runOnceForAllItems"},"id":"m3","name":"计算金额","type":"n8n-nodes-base.code","typeVersion":2,"position":[80,0]}
],
"connections": {
"手动触发": {"main": [[{"node": "填写报价单", "type": "main", "index": 0}]]},
"填写报价单": {"main": [[{"node": "计算金额", "type": "main", "index": 0}]]}
},
"settings": {"executionOrder": "v1"}
}
Comment savoir si ça a vraiment fonctionné
Quatre points, tous vérifiables soi-même ; s'il en manque un, ce n'est pas terminé.
- Les trois nœuds ont un cadre vert avec une coche, et les deux liens portent « 1 élément ». Si le chiffre n'est pas 1, cela signifie qu'un nœud intermédiaire a modifié le nombre d'éléments ; à vérifier.
- Dans le JSON de sortie du nœud Code, amount vaut 430 et unitCost vaut 2.15.
- On retrouve cette exécution dans l'historique. Les exécutions manuelles laissent aussi une trace ; ne croyez pas que seules les tâches planifiées apparaissent dans la liste.
- Passez freight de 60 à 100, relancez, et amount devrait devenir 470. Modifier une entrée et voir la sortie suivre, ce point est plus solide que les trois précédents — ne voir 430 qu'une seule fois pourrait être une coïncidence.
Je recommande de faire le quatrième point à chaque fois. Entre « ça tourne une fois » et « ça tourne correctement », il y a une différence.
Cinq erreurs que l'on rencontre vraiment
1. Code doesn't return items properly
Une chaîne a été retournée. Dans mon test, j'avais juste écrit une ligne return "共 430 元";, le nœud devient immédiatement rouge, et ce message apparaît en bas à droite.

Ce qui est intéressant, c'est quereturn { amount: 430 } cette écriture sans tableau englobant, sans json englobantfonctionne. Le nœud Code ajoute automatiquement la clé json et les crochets, la documentation précise ce comportement. Donc cette erreur n'est pas « le format n'est pas assez standard », c'est « ce que tu renvoies n'est pas du tout une donnée » — les chaînes, les nombres, null ne peuvent pas être complétés.
2. items is not defined [line 1]
Le Mode est réglé sur Run Once for Each Item, et le code utilise encore items. En mode élément par élément, n8n n'injecte qu'un seul élément à la fois, l'élément courant s'appelle $json, pour obtenir la quantité il faut écrire $json.qty. La différence entre les deux modes tient en une phrase : tout le tableau s'exécute une fois, ou chaque élément s'exécute une fois. Avant d'écrire du code, jette un œil à ce menu déroulant.
3. Un seul nœud "Manual Trigger" est autorisé par workflow
Ajouter un autre trigger à un workflow qui en possède déjà un. Cette fois j'ai fait encore plus bête : coller un JSON contenant un trigger dans le canevas d'un workflow existant, ce qui a fait apparaître « impossible d'insérer le nœud », suivi de cette phrase. Pour tester en parallèle, ouvre d'abord un nouveau workflow avant de coller.
4. Sortie d'un undefined, sans erreur
Dans Edit Fields, le champ s'appelle unit_price, dans le code on écrit row.unitPrice. Une différence d'un caractère entre majuscule/minuscule et underscore, n8n s'en fiche, JS aussi, résultat : undefined se propage de bout en bout, et le summary affiche « total frais de port inclus undefined yuan ». C'est le type d'erreur le plus difficile à traquer, parce que ça ne passe pas au rouge, ça ne sonne pas, c'est juste le chiffre qui est faux.
5. amount devient "37060"
Le type du champ est réglé sur chaîne. Soixante et "60" se ressemblent en JS, mais + dès qu'il rencontre une chaîne, il bascule en concaténation : 370 plus "60" donne "37060", pas 430.

Le cinquième point est le plus précieux de cet article. La première fois que j'ai obtenu ce nombre, j'ai fixé 37060 pendant une bonne trentaine de secondes avant de comprendre qu'il s'agissait d'une concaténation de chaînes — parce que le code semblait parfaitement correct, le problème était dans le menu déroulant de type du nœud précédent.
Les trois limites du nœud Code
Le nœud Code s'exécute dans le propre processus de n8n, mais avec un sandbox : impossible de lire des fichiers locaux, impossible d'envoyer des requêtes HTTP. Pour manipuler des fichiers, utilisez le nœud Read/Write File From Disk, pour envoyer des requêtes, le nœud HTTP Request. Ce n'est pas une lacune, c'est réduire au minimum « ce qu'un bout de JS collé à la va-vite peut faire ».
Mais il y a trois choses qu'il ne bloque pas, et qu'il faut gérer soi-même.
Ne collez pas à la légère un JSON de workflow fourni par quelqu'un d'autre.Le coller équivaut à exécuter le JS écrit par autrui sur votre propre instance. Sur mon instance, coller un JSON crée directement les nœuds, sans popup de confirmation, sans demander la provenance. Si vous voulez vraiment tester, commencez par le déposer dans une instance de test vide, lisez le code, puis décidez si vous l'exécutez.
Ne codez pas les clés en dur dans le code.Un workflow peut être exporté en entier, envoyé à un collègue, collé dans un groupe. Une api key codée en dur dans le code suivra le JSON. Il faut la placer dans un nœud de credentials, pour que n8n la stocke chiffrée.
L'auto-hébergement permet d'installer des paquets npm tiers.Désactivé par défaut, il faut activer manuellement une variable d'environnement. L'activer équivaut à ouvrir une brèche d'exécution de code arbitraire pour le nœud Code. Sur une instance à usage personnel, peu importe ; sur une instance partagée par plusieurs personnes, je recommande de le laisser désactivé en permanence.
Résumé
Trois nœuds, une chaîne : le trigger génère les données, Edit Fields les complète, le code les calcule. Ce qu'il faut vraiment retenir, ce n'est pas comment cliquer sur ces trois nœuds, c'est la forme « tableau contenant du json ». Ensuite, IF, Merge, les boucles, les branches d'erreur, tout n'est qu'une variante de cette forme.
Le code, à éviter autant que possible. Ce devis peut aussi se calculer avec Edit Fields plus des expressions,{{ $json.qty * $json.unit_price + $json.freight }} une ligne suffit, et un nœud de moins. J'ai finalement choisi Code parce qu'il fallait ensuite calculer simultanément des devis selon trois bases, et empiler des expressions dans un nœud est plus difficile à maintenir que d'écrire du code. Si vous ne calculez qu'un seul nombre, n'utilisez pas de code.
Le piège des types, je vous suggère de modifier volontairement freight en chaîne de caractères dès maintenant et de l'exécuter une fois, pour voir de vos propres yeux 430 devenir 37060. Lire dix fois un texte ne vaut pas se tromper une fois soi-même.
On continue
L'article précédent était« n8n, Zapier, Make : comment choisir ». À quoi ressemblent les nœuds, les connexions et les exécutions dans le JSON,cet articlel'a décortiqué. Un jour où le service ne démarre pas ou qu'un port entre en conflit, consultez« Comment diagnostiquer les erreurs de démarrage de n8n et les ports occupés ». Pour l'installation, voircet article, si l'interface ne vous est pas familière, consultezcet article. La table des matières du cours complet se trouveici。
Références
- Manual Trigger: s'exécute uniquement lorsque vous cliquez sur exécuter, ne fournit pas de déclenchement automatique ; un seul autorisé par workflow
- Edit Fields (Set): deux modes Manual Mapping et JSON Output, rôle de Include in Output
- Code: différence entre les deux Modes, options de langage, impossibilité d'accéder au système de fichiers et d'émettre des requêtes HTTP
- Understand n8n's data structure: origine des tableaux imbriqués dans du json, et explication de l'ajout automatique des clés json par le nœud Code
- Utiliser les raccourcis intégrés: les variables et méthodes intégrées dans les expressions, lesquelles ne s'appliquent pas dans le nœud Code
Dernière mise à jour : 28 octobre 2026, avec n8n 2.43.7.

