{
  "name": "WhatsGo - receive customer replies",
  "nodes": [
    {
      "parameters": {
        "content": "## WhatsGo: receive customer replies\n1. Copy this workflow's PRODUCTION webhook URL into Dashboard → Device → Webhook, with event message.received.\n2. Paste the webhook secret (whsec_…) into the Code node.\n3. Self-hosted n8n only: set NODE_FUNCTION_ALLOW_BUILTIN=crypto so the signature can be verified.\nOutput fields: eventId (use it to de-duplicate), phone, pushName, text, messageType, id (WhatsApp message id).",
        "height": 240,
        "width": 440
      },
      "id": "5aa67d76-0694-4a62-9368-70440644c9f1",
      "name": "Read me",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -320
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "whatsgo-events",
        "options": {
          "rawBody": true
        }
      },
      "id": "dde56022-20dc-4f11-97ff-db9ac42f3922",
      "name": "Webhook (from WhatsGo)",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ],
      "webhookId": "330ddbb0-40d4-4430-a3b9-ed60a1028c7c"
    },
    {
      "parameters": {
        "jsCode": "// Verifies X-Watsgo-Signature (t=<unix>,v1=<hex>) on the RAW body. Needs NODE_FUNCTION_ALLOW_BUILTIN=crypto (self-hosted n8n).\nconst crypto = require('crypto');\nconst SECRET = 'whsec_REPLACE_WITH_YOUR_WEBHOOK_SECRET';\nconst item = $input.first();\nconst raw = Buffer.from(item.binary.data.data, 'base64').toString('utf8');\nconst sig = String(item.json.headers['x-watsgo-signature'] || '');\nconst t = (sig.match(/t=(\\d+)/) || [])[1];\nconst v1 = (sig.match(/v1=([a-f0-9]+)/) || [])[1];\nif (!t || !v1) throw new Error('missing signature');\nif (Math.abs(Date.now() / 1000 - Number(t)) > 300) throw new Error('stale request');\nconst expected = crypto.createHmac('sha256', SECRET).update(t + '.' + raw).digest('hex');\nif (expected.length !== v1.length || !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))) throw new Error('bad signature');\nconst event = JSON.parse(raw);\nreturn [{ json: { eventId: event.id, type: event.type, instanceId: event.instanceId, ...event.data } }];"
      },
      "id": "687a458a-3fa0-4de1-a70a-0fabfa39461d",
      "name": "Verify signature",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "313df3ce-40b6-46b6-b2e0-eae7845fd455",
              "leftValue": "={{ $json.type }}",
              "rightValue": "message.received",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "c5af79bc-3126-4272-916d-2e4a4b0990b4",
      "name": "Customer message?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {},
      "id": "c81483d8-45e7-491e-a07b-b8b91af523b2",
      "name": "Your logic here",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        900,
        -100
      ]
    }
  ],
  "connections": {
    "Webhook (from WhatsGo)": {
      "main": [
        [
          {
            "node": "Verify signature",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify signature": {
      "main": [
        [
          {
            "node": "Customer message?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Customer message?": {
      "main": [
        [
          {
            "node": "Your logic here",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {}
}