AutomationFlowsData & Sheets › Subflow — Wa Send

Subflow — Wa Send

Subflow — WA Send. Uses executeWorkflowTrigger, postgres, httpRequest, errorTrigger. Event-driven trigger; 10 nodes.

Event trigger★★★★☆ complexity10 nodesExecute Workflow TriggerPostgresHTTP RequestError Trigger
Data & Sheets Trigger: Event Nodes: 10 Complexity: ★★★★☆ Added:

This workflow follows the Error Trigger → 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 →

Download .json
{
  "name": "Subflow \u2014 WA Send",
  "nodes": [
    {
      "id": "was00001-0001-0001-0001-000000000001",
      "name": "WA Send Trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1,
      "position": [
        200,
        300
      ],
      "parameters": {}
    },
    {
      "id": "was00002-0002-0002-0002-000000000002",
      "name": "Fetch Last Inbound Time",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "alwaysOutputData": true,
      "position": [
        440,
        300
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT COALESCE(EXTRACT(EPOCH FROM (NOW() - MAX(created_at))), 0) AS seconds_since_last_inbound FROM conversation_message WHERE conversation_id = $1::uuid AND direction = 'IN'",
        "options": {
          "queryReplacement": "={{ [($('WA Send Trigger').first()?.json?.conversationId || '00000000-0000-0000-0000-000000000000')] }}"
        }
      }
    },
    {
      "id": "was00003-0003-0003-0003-000000000003",
      "name": "Route Free-Form vs Template",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        680,
        300
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-window",
              "leftValue": "={{ Number($json.seconds_since_last_inbound) }}",
              "rightValue": 86400,
              "operator": {
                "type": "number",
                "operation": "lt"
              }
            },
            {
              "id": "cond-no-template",
              "leftValue": "={{ $('WA Send Trigger').first()?.json?.templateName ?? '' }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "was00004-0004-0004-0004-000000000004",
      "name": "Send Free-Form Message",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        920,
        200
      ],
      "parameters": {
        "method": "POST",
        "url": "={{ 'https://graph.facebook.com/v20.0/' + $env.WHATSAPP_PHONE_NUMBER_ID + '/messages' }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "={{ 'Bearer ' + $env.WHATSAPP_ACCESS_TOKEN }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "contentType": "json",
        "jsonBody": "={{ { messaging_product: 'whatsapp', to: $('WA Send Trigger').first()?.json?.to, type: 'text', text: { body: $('WA Send Trigger').first()?.json?.body } } }}",
        "options": {
          "timeout": 20000,
          "retry": {
            "enabled": true,
            "maxTries": 2,
            "waitBetweenTries": 1000
          },
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      }
    },
    {
      "id": "was00005-0005-0005-0005-000000000005",
      "name": "Check Error 131047",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1160,
        200
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "cond-131047-a",
              "leftValue": "={{ ($json.error && $json.error.code) ?? 0 }}",
              "rightValue": 131047,
              "operator": {
                "type": "number",
                "operation": "equals"
              }
            },
            {
              "id": "cond-131047-b",
              "leftValue": "={{ ($json.errors && $json.errors[0] && $json.errors[0].code) ?? 0 }}",
              "rightValue": 131047,
              "operator": {
                "type": "number",
                "operation": "equals"
              }
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "was00006-0006-0006-0006-000000000006",
      "name": "Send Template Message",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1400,
        100
      ],
      "parameters": {
        "method": "POST",
        "url": "={{ 'https://graph.facebook.com/v20.0/' + $env.WHATSAPP_PHONE_NUMBER_ID + '/messages' }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "={{ 'Bearer ' + $env.WHATSAPP_ACCESS_TOKEN }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "contentType": "json",
        "jsonBody": "={{ (function() { const t = $('WA Send Trigger').first()?.json; const vars = (t?.templateVars || []); return { messaging_product: 'whatsapp', to: t?.to, type: 'template', template: { name: t?.templateName, language: { code: 'en' }, components: vars.length > 0 ? [{ type: 'body', parameters: vars.map(function(v) { return { type: 'text', text: String(v) }; }) }] : [] } }; })() }}",
        "options": {
          "timeout": 20000,
          "retry": {
            "enabled": true,
            "maxTries": 2,
            "waitBetweenTries": 1000
          }
        }
      }
    },
    {
      "id": "was00007-0007-0007-0007-000000000007",
      "name": "Force Template \u2014 Window Expired",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        920,
        400
      ],
      "parameters": {
        "method": "POST",
        "url": "={{ 'https://graph.facebook.com/v20.0/' + $env.WHATSAPP_PHONE_NUMBER_ID + '/messages' }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "={{ 'Bearer ' + $env.WHATSAPP_ACCESS_TOKEN }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "contentType": "json",
        "jsonBody": "={{ (function() { const t = $('WA Send Trigger').first()?.json; const vars = (t?.templateVars || []); return { messaging_product: 'whatsapp', to: t?.to, type: 'template', template: { name: t?.templateName || 'still_interested_10d', language: { code: 'en' }, components: vars.length > 0 ? [{ type: 'body', parameters: vars.map(function(v) { return { type: 'text', text: String(v) }; }) }] : [] } }; })() }}",
        "options": {
          "timeout": 20000,
          "retry": {
            "enabled": true,
            "maxTries": 2,
            "waitBetweenTries": 1000
          }
        }
      }
    },
    {
      "id": "was00008-0008-0008-0008-000000000008",
      "name": "Return Success",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1640,
        200
      ],
      "parameters": {
        "mode": "manual",
        "duplicateItem": false,
        "assignments": {
          "assignments": [
            {
              "id": "ws-success",
              "name": "success",
              "value": true,
              "type": "boolean"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "was00009-0009-0009-0009-000000000009",
      "name": "Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "typeVersion": 1,
      "position": [
        200,
        600
      ],
      "parameters": {}
    },
    {
      "id": "was00010-0010-0010-0010-000000000010",
      "name": "Log Unhandled Error",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "alwaysOutputData": true,
      "position": [
        440,
        600
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO workflow_errors (workflow_name, execution_id, node_name, error_message, error_stack, input_payload) VALUES ('subflow-wa-send', $1, $2, $3, $4, $5::jsonb)",
        "options": {
          "queryReplacement": "={{ [$json.execution.id, $json.execution.lastNodeExecuted || 'unknown', $json.execution.error.message || 'unknown error', ($json.execution.error.stack ? $json.execution.error.stack.split('\\n')[0] : ''), '{\"source\":\"error_trigger\"}'] }}"
        }
      }
    }
  ],
  "connections": {
    "WA Send Trigger": {
      "main": [
        [
          {
            "node": "Fetch Last Inbound Time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Last Inbound Time": {
      "main": [
        [
          {
            "node": "Route Free-Form vs Template",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route Free-Form vs Template": {
      "main": [
        [
          {
            "node": "Send Free-Form Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Force Template \u2014 Window Expired",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Free-Form Message": {
      "main": [
        [
          {
            "node": "Check Error 131047",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Error 131047": {
      "main": [
        [
          {
            "node": "Send Template Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Return Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Template Message": {
      "main": [
        [
          {
            "node": "Return Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Force Template \u2014 Window Expired": {
      "main": [
        [
          {
            "node": "Return Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Trigger": {
      "main": [
        [
          {
            "node": "Log Unhandled Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "tags": [
    {
      "name": "real-estate-automation"
    },
    {
      "name": "subflow"
    },
    {
      "name": "version-1.0"
    }
  ]
}

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

Subflow — WA Send. Uses executeWorkflowTrigger, postgres, httpRequest, errorTrigger. Event-driven trigger; 10 nodes.

Source: https://github.com/jameszokah/real-estate-n8n-workflow/blob/ff6c75dac6b332a260a52efcb695ac4f3c962ed3/n8n-workflows/subflows/wa-send.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

Subflow — PDF Generate. Uses executeWorkflowTrigger, httpRequest, postgres, errorTrigger. Event-driven trigger; 11 nodes.

Execute Workflow Trigger, HTTP Request, Postgres +1
Data & Sheets

Reagendamiento_v2. Uses executeWorkflowTrigger, redis, httpRequest, n8n-nodes-evolution-api. Event-driven trigger; 89 nodes.

Execute Workflow Trigger, Redis, HTTP Request +3
Data & Sheets

Agendamiento_v2. Uses n8n-nodes-evolution-api, redis, httpRequest, executeWorkflowTrigger. Event-driven trigger; 59 nodes.

N8N Nodes Evolution Api, Redis, HTTP Request +3
Data & Sheets

Cancelacion_v2. Uses executeWorkflowTrigger, redis, httpRequest, n8n-nodes-evolution-api. Event-driven trigger; 46 nodes.

Execute Workflow Trigger, Redis, HTTP Request +3
Data & Sheets

Save_Extraction. Uses executeWorkflowTrigger, postgres, httpRequest. Event-driven trigger; 22 nodes.

Execute Workflow Trigger, Postgres, HTTP Request