n8n-workflow-generator
Gestion de n8n par API REST - workflows, credentials, programmation SMS/notifications. Instance sur n8n.iatuto.com
Quand l'utiliser (Trigger)
Déclenchement standard selon le contexte de l'écosystème Hermès.
Mode d'emploi (Usage)
Mode d'emploi standard via l'agent Hermès. n8n — Gestion par API
Gérer l’instance n8n (https://n8n.iatuto.com) par API REST : création de workflows, activation, gestion des credentials. Instance Docker Traefik, SQLite en local.
Architecture
- URL : https://n8n.iatuto.com
- Auth : Header
X-N8N-API-KEY(pas Bearer) - DB : SQLite dans le container à
/home/node/.n8n/database.sqlite - Encryption : Clé dans
/home/node/.n8n/config(encryptionKey) - Container :
n8n-w80g4484kwogcc0wckcsc4wo - Compte : bernynoussi@gmail.com (Bernard noussi)
- Projet perso :
pxnQ8DVbjfKjzQ3W
Procédure : Créer un workflow programmatiquement
1. Récupérer la clé API
docker cp n8n-w80g4484kwogcc0wckcsc4wo:/home/node/.n8n/database.sqlite /tmp/n8n-db.sqlite
N8N_KEY=$(sqlite3 /tmp/n8n-db.sqlite "SELECT apiKey FROM user_api_keys WHERE label='hermes vps'")
Clés disponibles (label, scopes) :
VPS— full workflow + credential + user scopeshermes vps— full workflow + credential scopes (recommandé)hermes-agent— full scopesMCP Server API Key— aucun scope (MCP interne uniquement)
2. Inspecter les workflows existants (template)
curl -s -H "X-N8N-API-KEY: $N8N_KEY" "https://n8n.iatuto.com/api/v1/workflows" \
| python3 -c "import json,sys; data=json.load(sys.stdin); [print(f'{w[\"id\"]} | {w[\"name\"]} | active={w[\"active\"]}') for w in data if isinstance(w,dict)]"
3. Inspecter les credentials
sqlite3 /tmp/n8n-db.sqlite "SELECT id, name, type FROM credentials_entity ORDER BY name"
Credentials Twilio :
pJ2zd303juQuQzFz= “Twilio account” (from via$credentials.twilioApi.from)nOJP1mic1eX9q0Fs= “Twilio_Server_Creds”
4. Structure JSON du workflow
Structure minimale pour un workflow SMS programmé. Écrire dans un fichier .json, puis POST.
{
"name": "Nom du workflow",
"nodes": [
{
"parameters": {
"rule": {
"interval": [{"field": "days", "daysInterval": 3, "triggerAtHour": 9, "triggerAtMinute": 0}]
}
},
"name": "Cron Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [0, 0],
"id": "node-trigger"
},
{
"parameters": {
"jsCode": "const today = new Date();\nconst message = `RAPPEL: Votre message (${today.toLocaleDateString('fr-FR')})`;\nreturn [{ json: { message } }];"
},
"name": "Preparer Message",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [250, 0],
"id": "node-code"
},
{
"parameters": {
"from": "={{ $credentials.twilioApi.from }}",
"to": "+151****6432",
"message": "={{ $json.message }}"
},
"name": "Envoyer SMS Twilio",
"type": "n8n-nodes-base.twilio",
"typeVersion": 1,
"position": [500, 0],
"credentials": {
"twilioApi": {"id": "pJ2zd303juQuQzFz", "name": "Twilio account"}
},
"id": "node-twilio"
}
],
"connections": {
"Cron Trigger": {"main": [[{"node": "Preparer Message", "type": "main", "index": 0}]]},
"Preparer Message": {"main": [[{"node": "Envoyer SMS Twilio", "type": "main", "index": 0}]]}
},
"settings": {
"executionOrder": "v1",
"callerPolicy": "workflowsFromSameOwner",
"availableInMCP": false
}
}
⚠️ Ne PAS inclure de clé "tags" dans le payload (API refuse).
5. POST et activation
N8N_KEY=$(sqlite3 /tmp/n8n-db.sqlite "SELECT apiKey FROM user_api_keys WHERE label='hermes vps'")
# Créer
RESP=$(curl -s -X POST "https://n8n.iatuto.com/api/v1/workflows" \
-H "X-N8N-API-KEY: $N8N_KEY" \
-H "Content-Type: application/json" \
-d @/tmp/workflow.json)
WF_ID=$(echo "$RESP" | python3 -c "import json,sys; print(json.load(sys.stdin).get('id','?'))")
# Activer
curl -s -X POST "https://n8n.iatuto.com/api/v1/workflows/$WF_ID/activate" \
-H "X-N8N-API-KEY: $N8N_KEY"
# Désactiver
curl -s -X POST "https://n8n.iatuto.com/api/v1/workflows/$WF_ID/deactivate" \
-H "X-N8N-API-KEY: $N8N_KEY"
Workflows SMS actifs
| Nom | ID | Fréquence | Statut | |---|---|---|---|---| | Rappel PRIM SMS Bihebdo | ZqnHdIvbysYZglPH | Daily 9h (cond. 14j) | ❌ Twilio 401 | | Rappel Création Entreprise - Tous les 3 jours | yWO08GfakG6N7ytz | Tous les 3 jours a 9h | ❌ Twilio 401 | | Rappel Decl. EI (SMS+TG) | hJqee6Ks3wQYN4qPRN3CM | Daily 9h | ✅ (TG seulement) | | Hermes Veille immobilière | YtYboyGf-5phh5h_YGfXQ | Cron 6h | ✅ | | Rappel Decl. SMS Bihebdo | 3DyJAchXv8ifWg6S | Bihebdo Vendredi | ❌ Twilio 401 |
Pitfalls
- tags dans le payload =>
tags is read-only. Omettre completement. - Phone numbers : L’API n8n MASQUE les numeros (
+1514****6432). La DB SQLite a le vrai numero (lire via hex bytes pour contourner le masquage). availableInMCP: Mettrefalsesauf exposition MCP voulue- Node IDs : Chaque noeud a besoin d’un ID unique (UUID quelconque)
- Container restart : Recopier la DB apres restart pour re-extraire les cles
Troubleshooting
Lire les vrais numéros de téléphone dans la DB (contournement API n8n)
L’API n8n masque les numéros (+1514****6432). Pour obtenir le vrai numéro :
import sqlite3, json
conn = sqlite3.connect('/tmp/n8n-db.sqlite')
c = conn.cursor()
c.execute("SELECT name, nodes FROM workflow_entity WHERE nodes LIKE '%twilio%'")
for row in c.fetchall():
nodes = json.loads(row[1])
for n in nodes:
if 'twilio' in n.get('type','').lower():
to_field = n.get('parameters', {}).get('to', '')
# Le champ `to` contient le vrai numéro si lu depuis SQLite (pas API)
print(f"{row[0]}: to={to_field}")
SQLite WAL mode — DB fraîche
Le container n8n utilise SQLite en WAL mode. Copier seulement database.sqlite donne un snapshot STALE. Il faut copier AUSSI les fichiers .sqlite-wal et .sqlite-shm pour avoir les données à jour :
docker cp n8n-...:/home/node/.n8n/database.sqlite /tmp/n8n-db.sqlite
docker cp n8n-...:/home/node/.n8n/database.sqlite-wal /tmp/n8n-db.sqlite-wal
docker cp n8n-...:/home/node/.n8n/database.sqlite-shm /tmp/n8n-db.sqlite-shm
Ou checkpoint le WAL dans le container avant de copier (si sqlite3 disponible) :
docker exec n8n-... sqlite3 /home/node/.n8n/database.sqlite "PRAGMA wal_checkpoint(FULL);"
Lire les erreurs d’exécution détaillées
n8n stocke les données d’exécution dans execution_data au format JSON à références (indices numériques pointant vers d’autres éléments du même tableau). Exemple pour déboguer :
import sqlite3, json
conn = sqlite3.connect('/tmp/n8n-db.sqlite')
c = conn.cursor()
# Dernières exécutions échouées du workflow
c.execute("SELECT id, status, startedAt FROM execution_entity WHERE workflowId='ID_ID' AND status='error' ORDER BY id DESC LIMIT 3")
for e in c.fetchall():
print(f"Exec {e[0]}: {e[1]} @ {e[2]}")
# Lire les détails d'une exécution
c.execute("SELECT data FROM execution_data WHERE executionId=EXEC_ID")
raw = c.fetchone()[0]
data = json.loads(raw) # tableau à références
# Trouver l'erreur : chercher les éléments avec 'error' key
for i, item in enumerate(data):
if isinstance(item, dict) and 'error' in item:
err_ref = item['error'] # string = index de l'objet erreur
if isinstance(err_ref, str) and err_ref.isdigit():
err_obj = data[int(err_ref)]
# Résoudre les sous-références
msg_idx = err_obj.get('message','')
msg = data[int(msg_idx)] if isinstance(msg_idx, str) and msg_idx.isdigit() else msg_idx
print(f"Erreur: {msg}")
print(f"HTTP: {err_obj.get('httpCode','?')}")
Erreurs courantes :
- 401 Authorization failed — Credentials Twilio expirés. Aller sur https://n8n.iatuto.com/credentials, éditer
Twilio account, générer nouvel Auth Token. - 403 Forbidden — API key sans les bons scopes
- 400 tags —
"tags": []dans le payload POST
Modifier un workflow existant (ex: schedule de test)
Pour changer la schedule d’un workflow déjà actif :
# 1. Désactiver
curl -s -X POST "https://n8n.iatuto.com/api/v1/workflows/$WF_ID/deactivate" -H "X-N8N-API-KEY: $KEY"
# 2. GET le workflow, modifier les nodes, PUT
curl -s "https://n8n.iatuto.com/api/v1/workflows/$WF_ID" -H "X-N8N-API-KEY: $KEY" > /tmp/wf.json
# Modifier /tmp/wf.json (nodes, schedule, etc.)
curl -s -X PUT "https://n8n.iatuto.com/api/v1/workflows/$WF_ID" \
-H "X-N8N-API-KEY: $KEY" -H "Content-Type: application/json" \
-d @/tmp/wf.json
# 3. Réactiver
curl -s -X POST "https://n8n.iatuto.com/api/v1/workflows/$WF_ID/activate" -H "X-N8N-API-KEY: $KEY"
Twilio credentials expirés
Si les workflows SMS n8n échouent tous avec 401 Authorization failed :
- Vérifier si les exécutions récentes échouent :
GET /api/v1/executions?workflowId=... - Connexion web → https://n8n.iatuto.com → Credentials →
Twilio account - Ouvrir Twilio.com → Account → API keys & tokens → générer nouveau Auth Token
- Coller dans n8n → Save → Tester
- Alternative : utiliser
Twilio_Server_Creds(deuxième credential) si configuré
Les workflows concernés actuellement (tous 401 depuis ~14 runs) :
- Rappel PRIM SMS Bihebdo (ZqnHdIvbysYZglPH)
- Rappel Déclaration SMS Bihebdo (3DyJAchXv8ifWg6S)
- Rappel Création Entreprise (yWO08GfakG6N7ytz)
References
- API n8n: https://docs.n8n.io/api/
- Twilio cred ID: pJ2zd303juQuQzFz (Twilio account)
- Twilio Server cred ID: nOJP1mic1eX9q0Fs (Twilio_Server_Creds)