This workflow follows the Emailsend → Google Sheets recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Messenger Responder (FB + IG)",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "meta-messenger",
"responseMode": "responseNode",
"options": {
"rawBody": true
}
},
"id": "b1000000-0000-4000-8000-000000000001",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
460
]
},
{
"parameters": {
"jsCode": "// Extract Message \u2014 works for both Facebook Messenger and Instagram DMs\n// Meta sends the same webhook structure for both platforms.\n// Instagram entries have messaging[].recipient.id matching your IG page-scoped ID\n// and the object field is 'instagram' vs 'page' for Messenger.\n\nconst body = $input.item.json.body;\n\nconst objectType = body.object; // 'page' for FB Messenger, 'instagram' for IG\nconst entry = body.entry && body.entry[0];\n\nif (!entry) {\n return [{ json: { error: 'No entry in payload', skip: true } }];\n}\n\nconst messagingEvent = entry.messaging && entry.messaging[0];\n\nif (!messagingEvent || !messagingEvent.message) {\n // Could be a delivery/read receipt \u2014 ignore\n return [{ json: { skip: true, reason: 'No message event (delivery/read receipt)' } }];\n}\n\nconst senderId = messagingEvent.sender.id;\nconst recipientId = messagingEvent.recipient.id;\nconst timestamp = messagingEvent.timestamp;\nconst text = messagingEvent.message.text || '';\nconst messageId = messagingEvent.message.mid;\n\n// Determine channel\nlet channel;\nif (objectType === 'instagram') {\n channel = 'instagram';\n} else {\n channel = 'facebook_messenger';\n}\n\nreturn [{\n json: {\n senderId,\n recipientId,\n text,\n messageId,\n timestamp,\n channel,\n skip: false\n }\n}];\n"
},
"id": "b1000000-0000-4000-8000-000000000002",
"name": "Extract Message",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
480,
460
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={\"status\":\"ok\"}",
"options": {
"responseCode": 200
}
},
"id": "b1000000-0000-4000-8000-000000000003",
"name": "Respond OK",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
480,
660
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "skip-check",
"leftValue": "={{ $json.skip }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "notEqual"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "b1000000-0000-4000-8000-000000000004",
"name": "If Has Message",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
720,
460
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.anthropic.com/v1/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "x-api-key",
"value": "={{ $credentials.httpHeaderAuth.value }}"
},
{
"name": "anthropic-version",
"value": "2023-06-01"
},
{
"name": "anthropic-beta",
"value": "prompt-caching-2024-07-31"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"model\": \"claude-haiku-4-5-20251001\",\n \"max_tokens\": 300,\n \"temperature\": 0.3,\n \"system\": [{\"type\": \"text\", \"text\": \"SYSTEM_PROMPT_PLACEHOLDER\", \"cache_control\": {\"type\": \"ephemeral\"}}],\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Channel: {{ $json.channel }}\\nSender ID: {{ $json.senderId }}\\nMessage: {{ $json.text }}\"\n }\n ]\n}",
"options": {
"timeout": 30000,
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "b1000000-0000-4000-8000-000000000005",
"name": "Claude API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
960,
360
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Parse Claude's response.\n// Expected format in the assistant reply:\n// ---REPLY---\n// <the text to send back to the user>\n// ---META---\n// action: reply_only | rsvp | escalate\n// event_name: <optional, for rsvp>\n// event_date: <optional, for rsvp>\n// escalate_reason: <optional, for escalate>\n\nconst content = $input.item.json.content;\nconst assistantText = content && content[0] && content[0].text ? content[0].text : '';\n\n// Preserve the upstream fields\nconst senderId = $('Extract Message').item.json.senderId;\nconst channel = $('Extract Message').item.json.channel;\nconst text = $('Extract Message').item.json.text;\nconst timestamp = $('Extract Message').item.json.timestamp;\n\nlet replyText = assistantText;\nlet action = 'reply_only';\nlet eventName = '';\nlet eventDate = '';\nlet escalateReason = '';\n\nconst replySplit = assistantText.split('---REPLY---');\nif (replySplit.length > 1) {\n const afterReply = replySplit[1];\n const metaSplit = afterReply.split('---META---');\n replyText = metaSplit[0].trim();\n\n if (metaSplit.length > 1) {\n const metaBlock = metaSplit[1].trim();\n const lines = metaBlock.split('\\n');\n for (const line of lines) {\n const [key, ...vals] = line.split(':');\n const k = key.trim().toLowerCase();\n const v = vals.join(':').trim();\n if (k === 'action') action = v;\n if (k === 'event_name') eventName = v;\n if (k === 'event_date') eventDate = v;\n if (k === 'escalate_reason') escalateReason = v;\n }\n }\n}\n\nreturn [{\n json: {\n senderId,\n channel,\n incomingText: text,\n replyText,\n action,\n eventName,\n eventDate,\n escalateReason,\n timestamp\n }\n}];\n"
},
"id": "b1000000-0000-4000-8000-000000000006",
"name": "Parse Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1200,
360
]
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.action }}",
"rightValue": "rsvp",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": "RSVP"
},
{
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.action }}",
"rightValue": "escalate",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": "Escalate"
},
{
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.action }}",
"rightValue": "reply_only",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": "Reply Only"
}
],
"fallbackOutput": {
"label": "Reply Only (Fallback)"
}
},
"options": {
"allMatchingOutputs": false
}
},
"id": "b1000000-0000-4000-8000-000000000007",
"name": "Route Action",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
1440,
360
]
},
{
"parameters": {
"method": "POST",
"url": "https://graph.facebook.com/v19.0/me/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"recipient\": {\n \"id\": \"{{ $json.senderId }}\"\n },\n \"message\": {\n \"text\": \"{{ $json.replyText }}\"\n },\n \"messaging_type\": \"RESPONSE\"\n}",
"options": {
"timeout": 10000
}
},
"id": "b1000000-0000-4000-8000-000000000008",
"name": "Send Reply",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1920,
560
],
"credentials": {
"httpQueryAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "Sheet1",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"timestamp": "={{ $json.timestamp }}",
"channel": "={{ $json.channel }}",
"sender_id": "={{ $json.senderId }}",
"incoming_message": "={{ $json.incomingText }}",
"reply": "={{ $json.replyText }}",
"action": "={{ $json.action }}",
"event_name": "={{ $json.eventName }}",
"escalate_reason": "={{ $json.escalateReason }}"
},
"matchingColumns": [],
"schema": [
{
"id": "timestamp",
"displayName": "timestamp",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "channel",
"displayName": "channel",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "sender_id",
"displayName": "sender_id",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "incoming_message",
"displayName": "incoming_message",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "reply",
"displayName": "reply",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "action",
"displayName": "action",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "event_name",
"displayName": "event_name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "escalate_reason",
"displayName": "escalate_reason",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
}
]
},
"options": {}
},
"id": "b1000000-0000-4000-8000-000000000009",
"name": "Log to Google Sheet",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
2160,
560
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://www.googleapis.com/calendar/v3/calendars/primary/events",
"authentication": "genericCredentialType",
"genericAuthType": "oAuth2Api",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"summary\": \"RSVP: {{ $json.eventName }}\",\n \"description\": \"RSVP from {{ $json.channel }} user {{ $json.senderId }}. Original message: {{ $json.incomingText }}\",\n \"start\": {\n \"dateTime\": \"{{ $json.eventDate }}T09:00:00\",\n \"timeZone\": \"Europe/Lisbon\"\n },\n \"end\": {\n \"dateTime\": \"{{ $json.eventDate }}T10:00:00\",\n \"timeZone\": \"Europe/Lisbon\"\n }\n}",
"options": {
"timeout": 10000
}
},
"id": "b1000000-0000-4000-8000-000000000010",
"name": "Google Calendar RSVP",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1680,
200
],
"credentials": {
"oAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"fromEmail": "oporto.toastmasters.club@gmail.com",
"toEmail": "oporto.toastmasters.club@gmail.com",
"subject": "=Escalation from {{ $json.channel }} \u2014 {{ $json.senderId }}",
"emailType": "text",
"message": "=A message has been escalated.\n\nChannel: {{ $json.channel }}\nSender ID: {{ $json.senderId }}\nOriginal message: {{ $json.incomingText }}\n\nReason: {{ $json.escalateReason }}\n\nAuto-reply sent:\n{{ $json.replyText }}",
"options": {}
},
"id": "b1000000-0000-4000-8000-000000000011",
"name": "Email Escalation",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2.1,
"position": [
1680,
400
],
"credentials": {
"smtp": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://graph.facebook.com/v19.0/me/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"recipient\": {\n \"id\": \"{{ $json.senderId }}\"\n },\n \"message\": {\n \"text\": \"{{ $json.replyText }}\"\n },\n \"messaging_type\": \"RESPONSE\"\n}",
"options": {
"timeout": 10000
}
},
"id": "b1000000-0000-4000-8000-000000000012",
"name": "Send Reply (RSVP)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1920,
200
],
"credentials": {
"httpQueryAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://graph.facebook.com/v19.0/me/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"recipient\": {\n \"id\": \"{{ $json.senderId }}\"\n },\n \"message\": {\n \"text\": \"{{ $json.replyText }}\"\n },\n \"messaging_type\": \"RESPONSE\"\n}",
"options": {
"timeout": 10000
}
},
"id": "b1000000-0000-4000-8000-000000000013",
"name": "Send Reply (Escalate)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1920,
400
],
"credentials": {
"httpQueryAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "Sheet1",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"timestamp": "={{ $json.timestamp }}",
"channel": "={{ $json.channel }}",
"sender_id": "={{ $json.senderId }}",
"incoming_message": "={{ $json.incomingText }}",
"reply": "={{ $json.replyText }}",
"action": "={{ $json.action }}",
"event_name": "={{ $json.eventName }}",
"escalate_reason": "={{ $json.escalateReason }}"
},
"matchingColumns": [],
"schema": [
{
"id": "timestamp",
"displayName": "timestamp",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "channel",
"displayName": "channel",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "sender_id",
"displayName": "sender_id",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "incoming_message",
"displayName": "incoming_message",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "reply",
"displayName": "reply",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "action",
"displayName": "action",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "event_name",
"displayName": "event_name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "escalate_reason",
"displayName": "escalate_reason",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
}
]
},
"options": {}
},
"id": "b1000000-0000-4000-8000-000000000014",
"name": "Log to Google Sheet (RSVP)",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
2160,
200
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "Sheet1",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"timestamp": "={{ $json.timestamp }}",
"channel": "={{ $json.channel }}",
"sender_id": "={{ $json.senderId }}",
"incoming_message": "={{ $json.incomingText }}",
"reply": "={{ $json.replyText }}",
"action": "={{ $json.action }}",
"event_name": "={{ $json.eventName }}",
"escalate_reason": "={{ $json.escalateReason }}"
},
"matchingColumns": [],
"schema": [
{
"id": "timestamp",
"displayName": "timestamp",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "channel",
"displayName": "channel",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "sender_id",
"displayName": "sender_id",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "incoming_message",
"displayName": "incoming_message",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "reply",
"displayName": "reply",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "action",
"displayName": "action",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "event_name",
"displayName": "event_name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "escalate_reason",
"displayName": "escalate_reason",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
}
]
},
"options": {}
},
"id": "b1000000-0000-4000-8000-000000000015",
"name": "Log to Google Sheet (Escalate)",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
2160,
400
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Extract Message",
"type": "main",
"index": 0
},
{
"node": "Respond OK",
"type": "main",
"index": 0
}
]
]
},
"Extract Message": {
"main": [
[
{
"node": "If Has Message",
"type": "main",
"index": 0
}
]
]
},
"If Has Message": {
"main": [
[
{
"node": "Claude API",
"type": "main",
"index": 0
}
],
[]
]
},
"Claude API": {
"main": [
[
{
"node": "Parse Response",
"type": "main",
"index": 0
}
]
]
},
"Parse Response": {
"main": [
[
{
"node": "Route Action",
"type": "main",
"index": 0
}
]
]
},
"Route Action": {
"main": [
[
{
"node": "Google Calendar RSVP",
"type": "main",
"index": 0
}
],
[
{
"node": "Email Escalation",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Reply",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Reply",
"type": "main",
"index": 0
}
]
]
},
"Google Calendar RSVP": {
"main": [
[
{
"node": "Send Reply (RSVP)",
"type": "main",
"index": 0
}
]
]
},
"Send Reply (RSVP)": {
"main": [
[
{
"node": "Log to Google Sheet (RSVP)",
"type": "main",
"index": 0
}
]
]
},
"Email Escalation": {
"main": [
[
{
"node": "Send Reply (Escalate)",
"type": "main",
"index": 0
}
]
]
},
"Send Reply (Escalate)": {
"main": [
[
{
"node": "Log to Google Sheet (Escalate)",
"type": "main",
"index": 0
}
]
]
},
"Send Reply": {
"main": [
[
{
"node": "Log to Google Sheet",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [
{
"name": "Meta",
"createdAt": "2026-02-16T00:00:00.000Z",
"updatedAt": "2026-02-16T00:00:00.000Z"
},
{
"name": "Messenger",
"createdAt": "2026-02-16T00:00:00.000Z",
"updatedAt": "2026-02-16T00:00:00.000Z"
},
{
"name": "Instagram",
"createdAt": "2026-02-16T00:00:00.000Z",
"updatedAt": "2026-02-16T00:00:00.000Z"
}
],
"triggerCount": 1,
"updatedAt": "2026-02-16T00:00:00.000Z",
"versionId": "1"
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleSheetsOAuth2ApihttpHeaderAuthhttpQueryAuthoAuth2Apismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Messenger Responder (FB + IG). Uses httpRequest, googleSheets, emailSend. Webhook trigger; 15 nodes.
Source: https://github.com/rianino/ClubDesk/blob/049275ecaa7386dab213cd0d8b51babaa779f177/n8n-workflows/messenger-responder.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Convalidaciones Académicas - Estructura Base. Uses googleSheets, emailSend, googleDrive, httpRequest. Webhook trigger; 35 nodes.
Are you tired of manually entering open house visitor information into your CRM? Losing hot leads because you didn't follow up fast enough? This powerful n8n workflow automatically syncs every SignSna
This is a production-ready, end-to-end workflow that automatically compares hotel prices across multiple booking platforms and delivers beautiful email reports to users. Unlike basic building blocks,
WF_MAIN_orchestrator_v4. Uses httpRequest, googleSheets, emailSend. Webhook trigger; 12 nodes.
This workflow automates invoice generation from form submissions, ensuring unique order IDs, creating PDF invoices, storing files, emailing customers, and logging invoice data — all seamlessly integra