Prompt copia-incolla per creare un bot WhatsApp con Claude Code e n8n
I prompt che usiamo per costruire bot WhatsApp su n8n in vibe coding con Claude Code. Ogni prompt genera un pezzo del workflow JSON, pronto per essere importato in n8n.
TL;DR
Prompt in sequenza pronti all'uso: contesto progetto, webhook receiver, logica di qualificazione, integrazione CRM, follow-up automatici. Si usano con Claude Code, si copia il JSON prodotto e si importa in n8n. Costruire in blocchi separati e testare ognuno prima del successivo.
Prompt copia-incolla per creare un bot WhatsApp con Claude Code e n8n
Questi sono i prompt che usiamo per costruire bot WhatsApp su n8n in vibe coding con Claude Code. Ogni prompt genera un pezzo del workflow JSON, pronto per essere importato in n8n.
Prima di usarli, leggi Come vibe-codare un bot WhatsApp con Claude Code e n8n per capire l'architettura (ManyChat → webhook → n8n) e Come collegare WhatsApp a ManyChat per il setup del canale.
Come usare questi prompt
- Crea una cartella sul tuo computer (es.
bot-whatsapp/) - Metti dentro il file
CONTESTO.mddescritto qui sotto con i tuoi dati reali - Apri il terminale in quella cartella e lancia
claude - Incolla i prompt in ordine, uno alla volta
- Copia il JSON prodotto, vai su n8n > Import > Paste JSON
- Testa ogni blocco prima di aggiungere il successivo
I prompt si costruiscono uno sull'altro: ogni prompt dice a Claude di aggiungere nodi al workflow esistente. Se importi ogni blocco separatamente invece di costruire un workflow unico, dovrai collegare i branch a mano in n8n.
File di contesto (crea questo file prima di tutto)
Salva questo come CONTESTO.md nella cartella del progetto. Sostituisci tutti i valori tra parentesi quadre con i tuoi dati reali. Claude legge questo file automaticamente e lo usa come riferimento per ogni prompt successivo.
# Architettura del bot
## Strumenti
- ManyChat: gestisce il canale WhatsApp, riceve messaggi dagli utenti e invia le risposte
- n8n: gestisce tutta la logica (self-hosted su [URL_N8N, es. https://n8n.miodominio.it])
- Google Sheets: CRM, una riga per lead
- ManyChat API: endpoint https://api.manychat.com/fb/sending/sendContent
- ManyChat API Key: [API_KEY_MANYCHAT — la trovi in ManyChat > Settings > API]
## Foglio Google Sheets
- ID foglio: [ID_FOGLIO — lo trovi nell'URL di Google Sheets, tra /d/ e /edit]
- Nome tab: [NOME_TAB, es. "Leads"]
- Colonne: telefono, nome, cognome, città, email, step, created_at
## Payload in arrivo da ManyChat (webhook POST)
{
"phone": "393331234567",
"message": "testo scritto dall'utente",
"fromMe": false,
"timestamp": 1712000000
}
## Come ManyChat invia messaggi
POST https://api.manychat.com/fb/sending/sendContent
Header: Authorization: Bearer [API_KEY_MANYCHAT]
Body:
{
"subscriber_id": "[phone]",
"data": {
"version": "v2",
"content": {
"messages": [{ "type": "text", "text": "testo da inviare" }]
}
}
}
## Flusso conversazionale
step 0: nuovo lead → benvenuto → chiedi nome
step 1: salva nome → chiedi cognome
step 2: salva cognome → chiedi città
step 3: salva città → chiedi email
step 4: salva email → ringrazia e avvisa che un operatore risponderà
Prompt 1: scheletro del workflow con webhook e filtri
Genera il JSON di un workflow n8n chiamato "Bot WhatsApp".
Il workflow inizia con un nodo Webhook che:
- ascolta in POST
- path: "whatsapp-inbound"
- risponde immediatamente con HTTP 200 e body { "status": "ok" } (usa un nodo
"Respond to Webhook" in parallelo all'esecuzione principale, non in sequenza)
Dopo il webhook, aggiungi un nodo Code chiamato "Parse Payload" che estrae dal body:
- phone: stringa (es. "393331234567")
- message: stringa (testo del messaggio)
- fromMe: booleano
Dopo il Parse, aggiungi un nodo IF chiamato "Filtro fromMe" che blocca l'esecuzione
se fromMe è true. Solo il branch false prosegue.
Restituisci solo il JSON del workflow, senza spiegazioni.
Prompt 2: lookup su Google Sheets con Safe Pass
Aggiungi al workflow esistente, dopo il nodo "Filtro fromMe", questi nodi in sequenza:
1. Nodo "Google Sheets" chiamato "Lookup Lead":
- operazione: getRows
- Document ID: [ID_FOGLIO_GOOGLE]
- Sheet Name: [NOME_TAB]
- filtro: colonna "telefono" uguale a {{ $json.phone }}
- credenziale: "Google Sheets account"
2. Nodo "Code" chiamato "Safe Pass" subito dopo il Lookup Lead.
Il codice deve restituire sempre esattamente 1 item.
Se il Lookup ha restituito 0 righe, restituisce:
{ _sheetsFound: false, phone: [prende phone dal nodo "Parse Payload"] }
Se ha restituito almeno 1 riga, restituisce i dati della riga con _sheetsFound: true
Restituisci il JSON aggiornato del workflow completo.
Prompt 3: gestione del nuovo lead
Dopo il nodo "Safe Pass", aggiungi:
1. Nodo IF chiamato "È nuovo lead?":
- condizione: _sheetsFound è false
- branch true = nuovo lead, branch false = lead esistente
2. Nel branch true (nuovo lead), nodo "Google Sheets" chiamato "Crea Riga Lead":
- operazione: appendRow
- Document ID: [ID_FOGLIO_GOOGLE]
- Sheet Name: [NOME_TAB]
- valori: telefono = {{ phone da Parse Payload }}, step = 0,
created_at = {{ data e ora correnti in formato ISO }}
3. Dopo "Crea Riga Lead", nodo "Code" chiamato "Inject Step 0" che restituisce
l'oggetto con i dati del nuovo lead più step=0, in modo che il branch successivo
possa usarli come se venissero dal Lookup.
4. Entrambi i branch convergono in un nodo "Merge" chiamato "State Pronto".
Restituisci il JSON aggiornato del workflow completo.
Prompt 4: router per step e messaggio di benvenuto
Dopo il nodo "State Pronto", aggiungi:
1. Nodo "Switch" chiamato "Router Step":
- legge il campo step dal nodo "State Pronto"
- case 0: branch "Step 0 - Benvenuto"
- case 1: branch "Step 1 - Salva Nome"
- case 2: branch "Step 2 - Salva Cognome"
- case 3: branch "Step 3 - Salva Città"
- case 4: branch "Step 4 - Salva Email"
- default: branch "Step Sconosciuto"
2. Nel branch "Step 0 - Benvenuto":
a. Nodo "Google Sheets" chiamato "Aggiorna Step 0→1":
- operazione: updateRow
- Document ID: [ID_FOGLIO_GOOGLE]
- Sheet Name: [NOME_TAB]
- matching column: telefono (mai row_number: non funziona su righe nuove)
- aggiorna: step = 1
b. Nodo "HTTP Request" chiamato "Invia Benvenuto":
- metodo: POST
- URL: https://api.manychat.com/fb/sending/sendContent
- header Authorization: Bearer [API_KEY_MANYCHAT]
- body: subscriber_id = {{ phone }}, messaggio di testo =
"Ciao! Sono qui per aiutarti. Come ti chiami?"
3. Nel branch "Step Sconosciuto", nodo "HTTP Request" che invia:
"Non ho capito. Scrivi al nostro team per assistenza."
(stesso formato degli altri nodi di invio)
Restituisci il JSON aggiornato del workflow completo.
Prompt 5: step di raccolta dati (1–4)
Aggiungi i branch mancanti nel Router Step.
Per ogni step il pattern è: leggi il messaggio, salvalo sul foglio, aggiorna lo step,
invia la domanda successiva.
Usa SEMPRE "telefono" come matching column negli aggiornamenti Google Sheets,
mai row_number.
Branch "Step 1 - Salva Nome":
- Aggiorna Google Sheets: colonna "nome" = {{ message }}, step = 2
- Invia: "Grazie {{ nome }}! Qual è il tuo cognome?"
Branch "Step 2 - Salva Cognome":
- Aggiorna Google Sheets: colonna "cognome" = {{ message }}, step = 3
- Invia: "In quale città ti trovi?"
Branch "Step 3 - Salva Città":
- Aggiorna Google Sheets: colonna "città" = {{ message }}, step = 4
- Invia: "Perfetto. Qual è la tua email? Ti servirà per ricevere i materiali."
Branch "Step 4 - Salva Email":
- Aggiorna Google Sheets: colonna "email" = {{ message }}, step = 5
- Invia: "Ottimo {{ nome }}, ho tutto quello che mi serve.
Un nostro consulente ti scriverà entro poche ore."
Restituisci il JSON aggiornato del workflow completo.
Prompt 6: classificazione AI con Groq (opzionale)
Aggiunge uno step di profilazione automatica: le risposte dell'utente vengono mandate a un modello linguistico che classifica il profilo e restituisce un valore strutturato. Funziona come nello step 9 del bot che abbiamo costruito per CPER, dove Groq sceglie la guida PDF giusta tra più varianti in base alle risposte al test di profilazione finanziaria.
Richiede un account Groq (gratuito fino a certi volumi su console.groq.com) e una API key.
Nel branch "Step 4 - Salva Email", dopo aver salvato l'email e prima del messaggio
finale, aggiungi:
1. Nodo "Google Sheets" chiamato "Leggi Profilo Completo":
- operazione: getRows
- Document ID: [ID_FOGLIO_GOOGLE]
- Sheet Name: [NOME_TAB]
- filtro: telefono uguale al telefono corrente
Serve per avere tutti i dati del lead in un unico oggetto.
2. Nodo "HTTP Request" chiamato "Classifica Profilo con Groq":
- metodo: POST
- URL: https://api.groq.com/openai/v1/chat/completions
- header Authorization: Bearer [API_KEY_GROQ — la trovi su console.groq.com]
- header Content-Type: application/json
- body:
{
"model": "llama-3.3-70b-versatile",
"messages": [
{
"role": "system",
"content": "Sei un assistente che classifica lead. Rispondi solo con JSON valido."
},
{
"role": "user",
"content": "Classifica questo lead:\nNome: {{ nome }}\nCittà: {{ città }}\nEmail: {{ email }}\n\nRispondi con: { \"profilo\": \"alto\" | \"medio\" | \"base\", \"motivazione\": \"una frase\" }"
}
],
"temperature": 0
}
3. Nodo "Code" chiamato "Parse Risposta Groq":
Estrae il campo "profilo" dal JSON restituito.
Se il parsing fallisce o Groq non risponde, usa "base" come fallback.
4. Nodo "Google Sheets": aggiorna colonna "profilo" con il valore estratto,
matching column: telefono.
Poi prosegui con il messaggio finale già configurato.
Restituisci il JSON aggiornato del workflow completo.
Prompt di debugging
Quando un nodo fallisce, vai su Executions in n8n, apri l'esecuzione con errore, e copia il messaggio di errore. Poi usa questo prompt:
Il workflow n8n che stiamo costruendo ha un errore.
Questo è il contesto del progetto (vedi CONTESTO.md).
Questo è il messaggio di errore che vedo nel log di n8n:
[INCOLLA QUI IL MESSAGGIO DI ERRORE ESATTO]
Questo è il JSON del nodo che ha fallito
(lo trovi cliccando i tre puntini del nodo → Copy):
[INCOLLA QUI IL JSON DEL NODO]
Dimmi cosa sta sbagliando e fornisci il JSON corretto del nodo.
Aggiornare il file di contesto dopo ogni correzione
Quando trovi un bug e lo risolvi, aggiungi una nota in CONTESTO.md nella sezione «Problemi noti e workaround». Così Claude non ripete lo stesso errore nelle sessioni successive.
Esempio:
## Problemi noti e workaround
- Non usare MAI row_number come matching column in Google Sheets update.
Usare sempre "telefono". row_number è null per le righe appena create con appendRow.
- Il nodo "Lookup Lead" restituisce 0 item per i nuovi lead: il Safe Pass node
è obbligatorio dopo ogni lookup per evitare che il workflow si fermi in silenzio.
- Non usare la forma abbreviata {{ .phone }} nelle espressioni n8n.
Usare sempre {{ $json.phone }} o {{ $('NomeNodo').first().json.phone }}.
Domande frequenti
I prompt funzionano senza il file CONTESTO.md? Funzionano, ma il JSON prodotto sarà generico: nomi di campi inventati, ID foglio placeholder, URL n8n di esempio. Con il file di contesto, Claude usa i tuoi dati reali e il risultato richiede molte meno correzioni dopo l'importazione.
Devo usare tutti i prompt in ordine? Sì, in sequenza: ogni prompt costruisce sul workflow del prompt precedente. Se salti un blocco (ad esempio il Safe Pass del Prompt 2), il workflow non gestirà correttamente i nuovi lead e n8n si bloccherà in silenzio quando il lookup Google Sheets restituisce 0 risultati.
Il Prompt 6 con Groq è obbligatorio? No. È utile solo se hai bisogno di classificare i lead in categorie non gestibili con regole fisse (come «se risponde X e Y va sulla guida Z»). Per flussi semplici di raccolta dati, i Prompt 1-5 bastano.
Cosa faccio se il JSON importato non funziona in n8n? Vai su Executions nel menu laterale di n8n, apri l'esecuzione con errore, copia il messaggio di errore del nodo che ha fallito, e usa il Prompt di debugging in fondo a questa pagina. Incolla l'errore esatto e il JSON del nodo: Claude Code identifica la causa e restituisce il nodo corretto.
Questo articolo fa parte del cluster su WhatsApp e Facebook Ads: Come integrare WhatsApp con Facebook Ads - guida pratica per aziende italiane