whatsapp-cloud-full

Full-coverage n8n community node for the WhatsApp Business Cloud API: messages, templates with dynamic parameter mapping, media, phone numbers, groups, analytics and a signature-verified webhook trigger

Package Information

Released: 1 mo ago
Downloads: 0 weekly / 0 monthly
Latest Version: 0.1.0
Author: Tim

Documentation

n8n-nodes-whatsapp-cloud-full

Community node for the WhatsApp Business Cloud API
(Graph API v26.0) that covers considerably more of the API than n8n's built-in WhatsApp node:
templates with dynamically generated parameter fields, media up- and download, phone number
registration, the Groups API, account analytics, and a webhook trigger with mandatory
signature verification.

npm version
license

Why this node

Built-in WhatsApp node This node
Send text, media, template ✅ ✅
Template parameters manual JSON generated input field per placeholder
Interactive messages ❌ buttons, list, CTA URL, location request, flow
Media download ❌ ✅ into a binary property
Phone number management ❌ list, verify, register, deregister
Groups API ❌ full management, messaging, join requests, invite links
Analytics ❌ conversation, message and pricing analytics
Trigger signature check optional mandatory, request is rejected with 401
Trigger output nested Meta payload flattened, with _raw kept

Installation

n8n Cloud and self-hosted UI

Settings → Community nodes → Install, then enter:

n8n-nodes-whatsapp-cloud-full

Self-hosted, manual

cd ~/.n8n
npm install n8n-nodes-whatsapp-cloud-full

Restart n8n afterwards. Requires n8n 1.60 or newer and Node.js 20.15 or newer.

Credentials

The credential only asks for an access token. WhatsApp Business Account and phone number
are chosen from dropdowns on the node itself, because n8n cannot render dynamic lists
inside credential fields.

  1. Open Meta App Dashboard → your app → WhatsApp.
  2. Create a system user token (Business Settings → Users → System users) with the
    permissions whatsapp_business_messaging and whatsapp_business_management.
    A temporary token from the WhatsApp → API Setup tab works too, but expires after 24 hours.
  3. In n8n, create a WhatsApp Cloud API credential:
    • Access Token — the token from step 2.
    • App Secret — App Settings → Basic → App Secret. Only needed for the trigger, which
      refuses to activate without it.
    • API Version — leave at v26.0 unless you want to move to a newer Graph API version.
  4. Click Test. The credential calls GET /me and reports a readable error if the token
    is invalid, expired or missing permissions.

Which token sees which accounts

The From List dropdowns resolve accounts through GET /me/businesses and the
owned_whatsapp_business_accounts / client_whatsapp_business_accounts edges. Tokens that
are scoped to a single WABA cannot enumerate that path — switch the resource locator to
By ID and paste the ID from the WhatsApp Manager. Every locator offers that fallback.

Resources and operations

Message — Send Text · Send Template · Send Interactive · Send Media · Send Location ·
Send Contact · Send Reaction · Mark as Read

Template — List · Get by Name · Create · Delete

Media — Upload · Download · Get URL · Delete

Phone Number — List · Get Details · Request Verification Code · Verify Code · Register ·
Deregister

Group — List Active Groups · Create · Get · Update · Delete · Send Message ·
List Join Requests · Approve or Reject Join Request · Get Invite Link · Revoke Invite Link

Business Account — List Business Accounts · Get Details · Get Analytics

Template parameters

Pick a template, and the node reads its components and builds one input field per
placeholder — numbered ({{1}}) as well as named ({{order_id}}), for body, header and
dynamic URL buttons. Media headers get a field that accepts either a media ID or a public
URL. Nothing has to be assembled by hand.

Groups

The Groups API only works for phone numbers of an Official Business Account that was
approved for groups. Every other number gets Meta error 131215; the node turns that into
a message explaining what is missing instead of passing the raw error through.

Group creation is asynchronous: Meta answers with a request_id and delivers the finished
group through the group_lifecycle_update webhook.

Trigger

The WhatsApp Cloud Trigger handles Meta's hub.challenge handshake and verifies the
X-Hub-Signature-256 header of every delivery against the app secret. Requests without a
valid signature are answered with 401 and never start a workflow.

Events: messages, message_status, message_template_status_update,
phone_number_quality_update, phone_number_name_update, account_alerts,
group_lifecycle_update, group_membership_update.

Output is flattened, so downstream nodes read {{ $json.from }} and {{ $json.text }}
rather than {{ $json.entry[0].changes[0].value.messages[0].from }}. The original payload
stays in _raw.

With Subscribe Automatically enabled (the default), activating the workflow subscribes
the app to the selected business account and registers this webhook URL as that account's
callback URL override. That is what lets several n8n workflows receive events even though
an app has only one global callback URL.

Quickstart workflow

Replies to every incoming message and marks it as read. Import via
Workflows → Import from clipboard, then select your credential and fill in the two IDs.

{
  "name": "WhatsApp quickstart",
  "nodes": [
    {
      "parameters": {
        "events": ["messages"],
        "verifyToken": "REPLACE_WITH_VERIFY_TOKEN",
        "wabaId": { "__rl": true, "value": "REPLACE_WITH_WABA_ID", "mode": "id" },
        "options": { "autoSubscribe": true }
      },
      "name": "On WhatsApp message",
      "type": "n8n-nodes-whatsapp-cloud-full.whatsAppCloudTrigger",
      "typeVersion": 1,
      "position": [0, 0]
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "sendText",
        "wabaId": { "__rl": true, "value": "REPLACE_WITH_WABA_ID", "mode": "id" },
        "phoneNumberId": { "__rl": true, "value": "REPLACE_WITH_PHONE_NUMBER_ID", "mode": "id" },
        "to": "={{ $json.from }}",
        "text": "=Thanks for your message, {{ $json.contactName }}. We will get back to you shortly.",
        "previewUrl": false,
        "messageOptions": { "replyToMessageId": "={{ $json.messageId }}" }
      },
      "name": "Send reply",
      "type": "n8n-nodes-whatsapp-cloud-full.whatsAppCloud",
      "typeVersion": 1,
      "position": [240, 0]
    }
  ],
  "connections": {
    "On WhatsApp message": {
      "main": [[{ "node": "Send reply", "type": "main", "index": 0 }]]
    }
  },
  "settings": { "executionOrder": "v1" },
  "pinData": {}
}

More examples live in .n8n/workflows/: keyword auto reply, template
broadcast from Google Sheets, group welcome message, and media backup to S3.

Error handling

WhatsApp error codes are translated into a readable title plus a hint that says what to
change — among them 100, 131026, 131047, 131215, 132001, 132015 and 133005.
Throttling errors (4, 80007, 130429) and HTTP 429/5xx are retried automatically
three times with exponential backoff.

Development

npm install --ignore-scripts   # isolated-vm, a transitive dev dependency, needs no build here
npm run lint
npm test
npm run build
npm run dev                    # starts a local n8n with this node linked

Run the live smoke test against a real number by setting WA_TEST_TOKEN,
WA_TEST_PHONE_NUMBER_ID and WA_TEST_RECIPIENT; without them it is skipped.

Contributing

Issues and pull requests are welcome.

  • Keep npm run lint, npm test and npm run build green.
  • Add or update tests for behaviour changes. Renaming a node parameter fails the snapshot
    test on purpose — parameter names are the contract that existing workflows depend on.
  • Note user-facing changes in CHANGELOG.md under ## [Unreleased].

Publishing steps are documented in PUBLISHING.md.

License

MIT

This project is not affiliated with, endorsed by, or sponsored by Meta Platforms, Inc.
WhatsApp is a trademark of Meta Platforms, Inc.

Discussion