This workflow follows the Google Sheets → HTTP Request 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": "Fluxo A - Opt-in (Luz da Lua)",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 13 * * 1-5"
}
]
}
},
"id": "a1",
"name": "Schedule 10h BRT (dias \u00fateis)",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
],
"notes": "Cron 0 13 * * 1-5 = 10h em America/Sao_Paulo se o n8n estiver em UTC. Ajuste se a env GENERIC_TIMEZONE=America/Sao_Paulo estiver setada (use 0 10 * * 1-5)."
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "PLACEHOLDER_SPREADSHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "PLACEHOLDER_SHEET_NAME",
"mode": "name"
},
"options": {}
},
"id": "a2",
"name": "Sheets - Get rows",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
460,
300
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "f1",
"leftValue": "={{ $json.opt_in }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
}
},
{
"id": "f2",
"leftValue": "={{ $json.status_contato }}",
"rightValue": "sem_consentimento",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "a3",
"name": "Filter - sem_consentimento",
"type": "n8n-nodes-base.filter",
"typeVersion": 2.2,
"position": [
680,
300
]
},
{
"parameters": {
"maxItems": 20
},
"id": "a4",
"name": "Limit (warm-up: 20/dia)",
"type": "n8n-nodes-base.limit",
"typeVersion": 1,
"position": [
900,
300
],
"notes": "Ajuste segundo o cronograma de warm-up (07-warmup-e-qualidade.md)."
},
{
"parameters": {
"batchSize": 1,
"options": {}
},
"id": "a5",
"name": "SplitInBatches",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
1120,
300
]
},
{
"parameters": {
"method": "POST",
"url": "=https://graph.facebook.com/v21.0/{{$env.WHATSAPP_PHONE_NUMBER_ID}}/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"messaging_product\": \"whatsapp\",\n \"to\": \"{{ $json.telefone }}\",\n \"type\": \"template\",\n \"template\": {\n \"name\": \"solicitar_consentimento\",\n \"language\": { \"code\": \"pt_BR\" },\n \"components\": [\n {\n \"type\": \"body\",\n \"parameters\": [\n { \"type\": \"text\", \"text\": \"{{ $json.nome }}\" }\n ]\n }\n ]\n }\n}",
"options": {
"response": {
"response": {
"fullResponse": false,
"neverError": true
}
}
}
},
"id": "a6",
"name": "WhatsApp - Send template",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1340,
300
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"onError": "continueRegularOutput",
"notes": "Header Authorization: Bearer <ACCESS_TOKEN> via credencial Header Auth (Name=Authorization, Value=Bearer SEU_TOKEN)."
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "ok",
"leftValue": "={{ $json.messages?.[0]?.id }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "ok"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "inv",
"leftValue": "={{ $json.error?.code }}",
"rightValue": "131026",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "numero_invalido"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "tp",
"leftValue": "={{ $json.error?.code }}",
"rightValue": "132000",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "template_paused"
}
]
},
"options": {
"fallbackOutput": "extra",
"renameFallbackOutput": "falha"
}
},
"id": "a7",
"name": "Switch - resultado API",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
1560,
300
]
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "PLACEHOLDER_SPREADSHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "PLACEHOLDER_SHEET_NAME",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"matchingColumns": [
"telefone"
],
"value": {
"telefone": "={{ $('SplitInBatches').item.json.telefone }}",
"status_contato": "aguardando_resposta_optin",
"data_ultimo_envio": "={{ $now.toISO() }}",
"versao_template_optin": "solicitar_consentimento_v1",
"tentativas_envio": 0,
"ultimo_erro": ""
}
},
"options": {}
},
"id": "a8",
"name": "Sheets - Update OK",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
1820,
140
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "PLACEHOLDER_SPREADSHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "PLACEHOLDER_SHEET_NAME",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"matchingColumns": [
"telefone"
],
"value": {
"telefone": "={{ $('SplitInBatches').item.json.telefone }}",
"status_contato": "numero_invalido",
"ultimo_erro": "131026 - not a WhatsApp user"
}
},
"options": {}
},
"id": "a9",
"name": "Sheets - numero_invalido",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
1820,
300
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"errorMessage": "Template solicitar_consentimento foi pausado pela Meta. Verifique no WhatsApp Manager."
},
"id": "a10",
"name": "Stop - template_paused",
"type": "n8n-nodes-base.stopAndError",
"typeVersion": 1,
"position": [
1820,
460
]
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "PLACEHOLDER_SPREADSHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "PLACEHOLDER_SHEET_NAME",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"matchingColumns": [
"telefone"
],
"value": {
"telefone": "={{ $('SplitInBatches').item.json.telefone }}",
"tentativas_envio": "={{ ($('SplitInBatches').item.json.tentativas_envio || 0) + 1 }}",
"ultimo_erro": "={{ ($json.error?.code || 'unknown') + ' - ' + ($json.error?.message || JSON.stringify($json)) }}",
"status_contato": "={{ (($('SplitInBatches').item.json.tentativas_envio || 0) + 1) >= 3 ? 'falha_envio' : $('SplitInBatches').item.json.status_contato }}"
}
},
"options": {}
},
"id": "a11",
"name": "Sheets - Falha gen\u00e9rica",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
1820,
620
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"amount": "={{ Math.floor(Math.random() * 40) + 20 }}",
"unit": "seconds"
},
"id": "a12",
"name": "Wait 20-60s (humanizar)",
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
2060,
300
]
}
],
"connections": {
"Schedule 10h BRT (dias \u00fateis)": {
"main": [
[
{
"node": "Sheets - Get rows",
"type": "main",
"index": 0
}
]
]
},
"Sheets - Get rows": {
"main": [
[
{
"node": "Filter - sem_consentimento",
"type": "main",
"index": 0
}
]
]
},
"Filter - sem_consentimento": {
"main": [
[
{
"node": "Limit (warm-up: 20/dia)",
"type": "main",
"index": 0
}
]
]
},
"Limit (warm-up: 20/dia)": {
"main": [
[
{
"node": "SplitInBatches",
"type": "main",
"index": 0
}
]
]
},
"SplitInBatches": {
"main": [
[
{
"node": "WhatsApp - Send template",
"type": "main",
"index": 0
}
]
]
},
"WhatsApp - Send template": {
"main": [
[
{
"node": "Switch - resultado API",
"type": "main",
"index": 0
}
]
]
},
"Switch - resultado API": {
"main": [
[
{
"node": "Sheets - Update OK",
"type": "main",
"index": 0
}
],
[
{
"node": "Sheets - numero_invalido",
"type": "main",
"index": 0
}
],
[
{
"node": "Stop - template_paused",
"type": "main",
"index": 0
}
],
[
{
"node": "Sheets - Falha gen\u00e9rica",
"type": "main",
"index": 0
}
]
]
},
"Sheets - Update OK": {
"main": [
[
{
"node": "Wait 20-60s (humanizar)",
"type": "main",
"index": 0
}
]
]
},
"Sheets - numero_invalido": {
"main": [
[
{
"node": "Wait 20-60s (humanizar)",
"type": "main",
"index": 0
}
]
]
},
"Sheets - Falha gen\u00e9rica": {
"main": [
[
{
"node": "Wait 20-60s (humanizar)",
"type": "main",
"index": 0
}
]
]
},
"Wait 20-60s (humanizar)": {
"main": [
[
{
"node": "SplitInBatches",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
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.
googleSheetsOAuth2ApihttpHeaderAuth
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Fluxo A - Opt-in (Luz da Lua). Uses googleSheets, httpRequest, stopAndError. Scheduled trigger; 12 nodes.
Source: https://github.com/rodrigogr/shared-projects/blob/3a68abe13ba87467d3fc5fa0e72f91a2686d4bd3/whatsapp-mvp/n8n-workflows/fluxo-a-opt-in.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.
YogiAI. Uses googleSheets, googleSheetsTool, httpRequest, stopAndError. Scheduled trigger; 61 nodes.
Anyone curating before/after text examples in a spreadsheet and wanting a push-button path to a fine-tuned GPT model—without touching curl. Works with Google Sheets or Airtable.
Complaint Triage Orchestrator (S2.3). Uses httpRequest, googleSheets. Scheduled trigger; 65 nodes.
This workflow automates video distribution to 9 social platforms simultaneously using Blotato's API. It includes both a scheduled publisher (checks Google Sheets for videos marked "Ready") and a subwo
This workflow monitors Google Calendar for events indicating that a customer will visit the company today or the next day, retrieves the required details, and sends reminder notifications to the relev