AutomationFlowsData & Sheets › Handle Button Callbacks & Send Messages

Handle Button Callbacks & Send Messages

Original n8n title: Otto - Épico 4: Callback Botão (gerar Mensagem / Já Falei)

OTTO - Épico 4: Callback Botão (Gerar Mensagem / Já Falei). Uses postgres, httpRequest. Webhook trigger; 7 nodes.

Webhook trigger★★★★☆ complexity7 nodesPostgresHTTP Request
Data & Sheets Trigger: Webhook Nodes: 7 Complexity: ★★★★☆ Added:

This workflow follows the HTTP Request → Postgres 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 →

Download .json
{
  "name": "OTTO - \u00c9pico 4: Callback Bot\u00e3o (Gerar Mensagem / J\u00e1 Falei)",
  "nodes": [
    {
      "parameters": {
        "content": "## \ud83d\udd18 Callback dos Bot\u00f5es do Nudge\n\n**Gerar Mensagem**: OTTO entrega texto pronto. Esfor\u00e7o = ZERO.\n**J\u00e1 falei com ele**: Registra intera\u00e7\u00e3o v\u00e1lida, reseta cron\u00f4metro.",
        "height": 150,
        "width": 420,
        "color": 3
      },
      "id": "note-docs",
      "name": "\ud83d\udccb Documenta\u00e7\u00e3o",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        40,
        40
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "otto_callback_botao",
        "authentication": "headerAuth",
        "responseMode": "lastNode",
        "options": {}
      },
      "id": "webhook-callback",
      "name": "Webhook: Callback Bot\u00e3o",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        260,
        340
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parsear resposta do bot\u00e3o interativo WhatsApp\nconst data = $input.first().json;\nconst buttonId = data.button_reply_id || data.interactive?.button_reply?.id || '';\nconst vendedorWhatsapp = data.from || data.vendedor_whatsapp;\n\nconst isGerarMsg = buttonId.startsWith('gerar_msg_');\nconst isJaFalei = buttonId.startsWith('ja_falei_');\n\nconst leadId = buttonId.replace('gerar_msg_', '').replace('ja_falei_', '');\n\nreturn [{ json: {\n  lead_id: leadId,\n  vendedor_whatsapp: vendedorWhatsapp,\n  acao: isGerarMsg ? 'GERAR_MENSAGEM' : isJaFalei ? 'JA_FALEI' : 'DESCONHECIDO',\n  button_id: buttonId\n}}];"
      },
      "id": "parse-callback",
      "name": "Parsear Callback",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        500,
        340
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "id": "is-gerar",
                    "leftValue": "={{ $json.acao }}",
                    "rightValue": "GERAR_MENSAGEM",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputLabel": "\ud83d\udcdd Gerar Mensagem"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "id": "is-ja-falei",
                    "leftValue": "={{ $json.acao }}",
                    "rightValue": "JA_FALEI",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputLabel": "\u2705 J\u00e1 Falei"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "id": "switch-acao",
      "name": "Qual A\u00e7\u00e3o?",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        740,
        340
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=SELECT l.nome_cliente, l.veiculo_interesse, l.estagio_atual, l.temperatura, l.metadata, ec.evidencia_ia FROM leads l LEFT JOIN eventos_comerciais ec ON ec.lead_id = l.id ORDER BY ec.criado_em DESC LIMIT 1 WHERE l.id = '{{ $json.lead_id }}';",
        "options": {}
      },
      "id": "buscar-lead-gerar",
      "name": "Buscar Dados do Lead",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        980,
        240
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://graph.facebook.com/v18.0/{{ $env.WHATSAPP_PHONE_ID }}/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"messaging_product\": \"whatsapp\",\n  \"to\": \"{{ $('Parsear Callback').first().json.vendedor_whatsapp }}\",\n  \"type\": \"text\",\n  \"text\": { \"body\": \"\ud83d\udccb Mensagem pronta para {{ $json.nome_cliente }}:\\n\\n{{ $('Montar Nudge com Bot\u00f5es').first().json.nudge.mensagem_sugerida_cliente || 'Ol\u00e1! Gostaria de saber se tem novidades. Estou \u00e0 disposi\u00e7\u00e3o!' }}\\n\\n_Copie e cole no WhatsApp do cliente_\" }\n}",
        "options": {}
      },
      "id": "enviar-mensagem-pronta",
      "name": "Enviar Mensagem Pronta",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1220,
        240
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=INSERT INTO eventos_comerciais (lead_id, vendedor_id, tipo_evento, evidencia_ia, state_version_at) SELECT '{{ $json.lead_id }}', l.vendedor_id, 'INTERACAO_VALIDA', '{\"origem\": \"botao_ja_falei\", \"canal\": \"whatsapp_otto\"}'::jsonb, l.state_version FROM leads l WHERE l.id = '{{ $json.lead_id }}';",
        "options": {}
      },
      "id": "registrar-ja-falei",
      "name": "Registrar Intera\u00e7\u00e3o + Reset Cron\u00f4metro",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        980,
        460
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Webhook: Callback Bot\u00e3o": {
      "main": [
        [
          {
            "node": "Parsear Callback",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parsear Callback": {
      "main": [
        [
          {
            "node": "Qual A\u00e7\u00e3o?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Qual A\u00e7\u00e3o?": {
      "main": [
        [
          {
            "node": "Buscar Dados do Lead",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Registrar Intera\u00e7\u00e3o + Reset Cron\u00f4metro",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Buscar Dados do Lead": {
      "main": [
        [
          {
            "node": "Enviar Mensagem Pronta",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [
    {
      "id": "otto-1",
      "name": "OTTO"
    },
    {
      "id": "otto-8",
      "name": "Nudge"
    },
    {
      "id": "otto-10",
      "name": "Callback"
    }
  ],
  "triggerCount": 1,
  "updatedAt": "2026-02-26T12: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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

OTTO - Épico 4: Callback Botão (Gerar Mensagem / Já Falei). Uses postgres, httpRequest. Webhook trigger; 7 nodes.

Source: https://github.com/paraisolorrayne/Attra/blob/6dd06914bf6be4654e2cb2b445995786aa402cd3/automations/epico-4-callback-botao.json — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

Scraping. Uses httpRequest, postgres, @apify/n8n-nodes-apify, respondToWebhook. Webhook trigger; 61 nodes.

HTTP Request, Postgres, @Apify/N8N Nodes Apify
Data & Sheets

Workflow B — AI Listing Engine. Uses httpRequest, postgres, errorTrigger. Webhook trigger; 47 nodes.

HTTP Request, Postgres, Error Trigger
Data & Sheets

Fluxo de voluntárias ZendeskXANXBD. Uses functionItem, zendesk, httpRequest, postgres. Webhook trigger; 25 nodes.

Function Item, Zendesk, HTTP Request +1
Data & Sheets

Fluxo de voluntárias ZendeskXANXBD. Uses functionItem, zendesk, httpRequest, postgres. Webhook trigger; 25 nodes.

Function Item, Zendesk, HTTP Request +1
Data & Sheets

Fluxo de voluntárias ZendeskXANXBD. Uses functionItem, zendesk, httpRequest, postgres. Webhook trigger; 25 nodes.

Function Item, Zendesk, HTTP Request +1