Workflows with Node.js code
WhatsApp in Pipedream: HTTP trigger, a Node.js step and environment variables
Pipedream creates an endpoint URL of its own for each workflow and lets you write steps in Node.js. According to its documentation (read on 2026-11-11), the JSON body arrives in steps.trigger.event, headers are lowercased and $.respond sets the response. Environment variables created in Settings are read with process.env and are secret by default.
Updated on
Why connect
It suits people who want real logic between the event and the reply without building a server: receive the message, query an API, call an AI model and reply through ZapZap, all in a few lines. ZapZap connects numbers through an unofficial channel: WhatsApp may limit or block any number, so pacing, consent and warm-up matter. It costs R$15 per active number per month, prepaid, with no per-message fee, and you start with a welcome credit when you verify your phone, subject to the current campaign.
Step by step
- 1
Create the environment variables
In Settings > Environment Variables (or Variables inside a project), create ZAPZAP_API_KEY, ZAPZAP_API_SECRET and ZAPZAP_INSTANCE_ID. The documentation says new variables are secret by default and the value cannot be changed afterwards. The keys come from Settings > API at app.zapzapapi.com.
- 2
Create the workflow with an HTTP trigger
Pipedream generates an endpoint URL just for the workflow. The documentation warns that, by default, HTTP triggers are public and require no authorization, and that bodies above 512 KB return 413.
- 3
Register the URL on the instance
Call PUT https://api.zapzapapi.com/api/v1/instances/{id}/webhook with webhook_url (the URL from the previous step) and events (for example, messages). The response carries the webhook_secret (whsec_). Test with POST /instances/{id}/webhook/test and watch the run in Pipedream.
- 4
Answer the webhook first
If $.respond is never called, the documentation says the endpoint returns a 400 error. Use $.respond with immediate: true to answer right away and let the other steps run afterwards. ZapZap retries when your endpoint fails.
- 5
Send the reply in a Node.js step
Use the example code: process.env for the keys, fetch for POST /{instanceId}/send/text with number and text. Replace the fixed number with the event's sender, reading the data fields of the envelope you receive.
- 6
Protect the endpoint
Since the trigger is public by default, validate the origin. ZapZap signs each delivery in the X-ZapZap-Signature header over the raw body; the documentation I read does not explain how to get the raw body in the trigger, so confirm that option in your account, or set up the authorization token Pipedream offers.
Example
// Pipedream Node.js code step. Environment variables (Settings > Environment Variables): ZAPZAP_API_KEY, ZAPZAP_API_SECRET, ZAPZAP_INSTANCE_ID
export default defineComponent({
async run({ steps, $ }) {
await $.respond({ status: 200, body: "ok", immediate: true }); // answer the webhook first
const base = "https://api.zapzapapi.com/api/v1/" + process.env.ZAPZAP_INSTANCE_ID;
const r = await fetch(base + "/send/text", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.ZAPZAP_API_KEY,
"x-api-secret": process.env.ZAPZAP_API_SECRET,
},
body: JSON.stringify({ number: "5511999999999", text: "Received: " + steps.trigger.event.body.event }),
});
return { status: r.status };
},
});Illustrative. The exact fields and endpoints are in the documentation.
Pipedream limits and points of attention (2026-11-11)
| Point | What the documentation says | What to do |
|---|---|---|
| Trigger authorization | Public by default; optional token sent as Bearer | Turn on the token or validate the signature |
| Body size | Above 512 KB returns 413 | Ask ZapZap only for the events you use |
| Response | Without $.respond, the endpoint returns 400 | Call $.respond at the start |
| Variables | Secret by default; process.env inside the component | Read inside run() |
Frequently asked questions
Does Pipedream have a ready ZapZap action?
Not that I confirmed. The route on this page is the HTTP trigger and a Node.js step calling the REST API.
How do I read the webhook body?
In steps.trigger.event. JSON payloads become JavaScript objects, according to the documentation read on 2026-11-11.
Why do I get a 400 from the endpoint?
If the workflow does not call $.respond, the endpoint returns 400. Respond at the start with $.respond.
How do I avoid processing the same delivery twice?
Store the envelope's delivery_id and ignore repeats. ZapZap repeats the delivery when the endpoint does not answer with success.
What does ZapZap cost?
It costs R$15 per active number per month, prepaid, with no per-message fee, and you start with a welcome credit when you verify your phone, subject to the current campaign.
Start now
Create your account, connect a number in minutes and test the API with warm-up and anti-ban. R$15 per active number/month, prepaid, no lock-in.
