WhatsApp Automation with Node.js
अंतिम अपडेट:
Which Node.js approach to use
The npm registry holds many WhatsApp packages. They fall into three groups with very different risk.
| Approach | Official | Good for | Risk |
|---|---|---|---|
| Cloud API with fetch or axios | OfficialYes | Good forProduction bots, notifications, CRM sync | RiskYou build and host the webhook |
| Provider SDK (for example Twilio's Node.js library) | OfficialYes, through a Business Solution Provider | Good forTeams that prefer provider-managed infrastructure | RiskProvider fees and its own API shape |
| Packages that drive WhatsApp Web or reverse engineer it | OfficialNo | Good forPersonal experiments only | RiskNumber can be restricted or banned; breaks when WhatsApp changes |
What you need first
The setup matches the Python guide. The code reads these from environment variables.
- A Meta developer account and an app with the WhatsApp product.
- A phone number ID for the number you send from. A test number is available during development.
- An access token, ideally from a system user, since temporary tokens expire quickly.
- Your app secret, to verify webhook signatures.
- A public HTTPS URL for the webhook, and Node.js 18 or later for the built-in fetch.
Send a message
Sending is one authenticated POST. Free-form text works only inside the 24-hour customer service window. Outside it, send an approved template.
const API_VERSION = process.env.WA_API_VERSION ?? "v21.0"; // use a version Meta currently supports
const PHONE_NUMBER_ID = process.env.WA_PHONE_NUMBER_ID;
const TOKEN = process.env.WA_ACCESS_TOKEN;
const URL = `https://graph.facebook.com/${API_VERSION}/${PHONE_NUMBER_ID}/messages`;
async function post(payload) {
const response = await fetch(URL, {
method: "POST",
headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify(payload),
signal: AbortSignal.timeout(10_000),
});
if (!response.ok) throw new Error(`WhatsApp API ${response.status}: ${await response.text()}`);
return response.json();
}
/** Free-form text. Only valid inside the 24-hour customer service window. */
export function sendText(to, body) {
return post({ messaging_product: "whatsapp", to, type: "text", text: { body } });
}
/** Approved template. Required to start a conversation or after the 24-hour window. */
export function sendTemplate(to, name, language = "en") {
return post({
messaging_product: "whatsapp",
to,
type: "template",
template: { name, language: { code: language } },
});
}
Receive messages with an Express webhook
A GET request verifies the endpoint once; POST requests deliver messages. Capture the raw body so the X-Hub-Signature-256 header can be checked against exactly what Meta sent.
import crypto from "node:crypto";
import express from "express";
import { sendText } from "./send-message.mjs";
const VERIFY_TOKEN = process.env.WA_VERIFY_TOKEN;
const APP_SECRET = process.env.WA_APP_SECRET;
const seen = new Set(); // use Redis or a database in production
const app = express();
app.use(express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } }));
app.get("/webhook", (req, res) => {
if (req.query["hub.mode"] === "subscribe" && req.query["hub.verify_token"] === VERIFY_TOKEN) {
return res.status(200).send(req.query["hub.challenge"]);
}
res.sendStatus(403);
});
function validSignature(req) {
const header = req.get("X-Hub-Signature-256") ?? "";
if (!header.startsWith("sha256=") || !req.rawBody) return false;
const expected = crypto.createHmac("sha256", APP_SECRET).update(req.rawBody).digest("hex");
const received = header.slice("sha256=".length);
return received.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
}
app.post("/webhook", (req, res) => {
if (!validSignature(req)) return res.sendStatus(403);
res.sendStatus(200); // acknowledge fast; do slow work in a queue
for (const entry of req.body.entry ?? []) {
for (const change of entry.changes ?? []) {
for (const message of change.value?.messages ?? []) {
if (seen.has(message.id)) continue; // Meta may deliver the same message more than once
seen.add(message.id);
handleMessage(message).catch(console.error);
}
}
}
});
async function handleMessage(message) {
const text = (message.text?.body ?? "").trim().toLowerCase();
if (text === "price" || text === "pricing") {
await sendText(message.from, "Our pricing depends on your volume. Reply HUMAN to talk to a person.");
} else if (text === "human") {
await sendText(message.from, "Thanks, a team member will reply shortly.");
// notify your team here
} else {
await sendText(message.from, "Hi! Reply PRICE for pricing or HUMAN to talk to a person.");
}
}
app.listen(8000);
Judging an npm package before you depend on it
Searches for "whatsapp automation npm" and "whatsapp automation library" return packages of very different quality. Check these before installing:
- Does the README say it uses Meta's Cloud API or a provider API, or does it drive WhatsApp Web with a browser or reverse-engineered protocol?
- Does the project itself warn about number bans or say it is not endorsed by WhatsApp?
- When was the last release, and are security issues handled?
- Does it verify webhook signatures, or leave that to you?
- Is it a thin typed wrapper over the official API? Those are the lowest-risk to adopt, and you can also call the API directly as shown above.
Common errors and what they usually mean
The same causes appear in every language.
- Text messages rejected after a quiet day: the 24-hour window closed, so use an approved template.
- Signature check fails: the body was parsed before hashing, or the app secret is wrong.
- Webhook verifies but gets no messages: the app is not subscribed to the messages field.
- Duplicate replies: Meta retried because the response was slow, so respond with 200 first and deduplicate by message ID.
अपना 7-दिन का ट्रायल शुरू करें
देखें कि WhatsApp ऑटोमेशन आपके व्यवसाय को लीड जुटाने, बातचीत ऑटोमेट करने और तेज़ फ़ॉलो-अप करने में कैसे मदद कर सकता है।
अक्सर पूछे जाने वाले प्रश्न
How do I send a WhatsApp message with Node.js?
- Send an authenticated POST request to the Cloud API messages endpoint with fetch. The request carries your access token and a JSON body containing the recipient number and the message.
Is whatsapp-web.js safe for business use?
- It is an unofficial client that drives WhatsApp Web. That is not part of the official platform and carries a risk of the number being restricted, so it is not recommended for customer-facing business messaging.
Is there an official WhatsApp npm package?
- The official route is Meta's Cloud API over HTTP, which needs no special package. Some providers publish their own SDKs. Verify any package's approach before using it.
Should I use Node.js or Python?
- Both use the same API, so choose the language your team can maintain. The Python guide covers the same flow.
स्रोत
About this page
Published by WhatsAppAutomation.si.
Pages here are written and reviewed in-house, cite Meta's documentation for platform rules, and carry a last-updated date. WhatsApp's pricing and policies change, so confirm anything that affects a decision against Meta's current documentation.