Main entry point for the API.
It's highly recommended reading the named parameters docs at
types.TheBasicConstructorArguments,
at least for token
, appSecret
and webhookVerifyToken
properties,
which are the most common in normal usage.
The other parameters are used for fine tunning the framework,
such as ponyfill
, which allows the code to execute on platforms
that are missing standard APIs such as fetch and crypto.
Make an authenticated request to any url. When using this method, be sure to pass a trusted url, since the request will be authenticated with the token.
It's strongly recommended NOT using this method as you might risk exposing your API key accidentally, but it's here in case you need a specific API operation which is not implemented by the library.
The url to fetch
The fetch options (headers.Authorization is already included)
The fetch response
Send a Whatsapp message to multiple phone numbers.
In order to avoid reaching the
API rate limit,
this method will send the messages in batches of 50 per second by default,
but this can be changed using the batch_size
and delay
parameters.
The API rate limit can be increased by contacting Facebook as explained here.
The bot's phone ID
The users' phone numbers
A Whatsapp message, built using the corresponding module for each type of message.
The number of messages to send per batch
The delay between each batch of messages in milliseconds
The server's responses
import { WhatsAppAPI } from "whatsapp-api-js";
import { Text } from "whatsapp-api-js/messages/text";
const Whatsapp = new WhatsAppAPI({
token: "YOUR_TOKEN",
appSecret: "YOUR_APP_SECRET"
});
const phoneID = "YOUR_BOT_NUMBER";
const users = ["YOUR_USER1_NUMBER", "YOUR_USER2_NUMBER"];
const message = new Text("Hello World");
const responses = Whatsapp.broadcastMessage(phoneID, users, message);
Promise.all(responses).then(console.log);
The bot's phone ID
The users' data
A Whatsapp message builder, it returns an array with the phone number and the message.
The number of messages to send per batch
The delay between each batch of messages in milliseconds
The server's responses
import { WhatsAppAPI } from "whatsapp-api-js";
import { Text } from "whatsapp-api-js/messages/text";
const Whatsapp = new WhatsAppAPI({
token: "YOUR_TOKEN",
appSecret: "YOUR_APP_SECRET"
});
const phoneID = "YOUR_BOT_NUMBER";
const users = [{ user: "USER1_ID" }, { user: "USER2_ID" }];
const message_builder = ({ user }) => [DB.fetch(user).phone, new Text(`Hello ${user}`)];
const responses = Whatsapp.broadcastMessage(phoneID, users, message);
Promise.all(responses).then(console.log);
Generate a QR code for sharing the bot
The bot's phone ID
The quick message on the QR code
The format of the QR code
The server response
Delete a Media object with an ID
The Media's ID
Optional
phoneID: stringBusiness phone number ID. If included, the operation will only be processed if the ID matches the ID of the business phone number that the media was uploaded on.
The server response
Delete a QR code of the bot
The bot's phone ID
The QR's id to delete
The server response
GET helper, must be called inside the get function of your code. Used once at the first webhook setup.
The request object sent by Whatsapp
The challenge string, it must be the http response body
// Simple http example implementation with Whatsapp.get() on Node@^19
import { WhatsAppAPI } from "whatsapp-api-js";
import { WhatsAppAPIError } from "whatsapp-api-js/errors";
import { NodeNext } from "whatsapp-api-js/setup/node";
import { createServer } from "http";
const token = "token";
const appSecret = "appSecret";
const Whatsapp = new WhatsAppAPI(NodeNext({ token, appSecret }));
function handler(req, res) {
if (req.method == "GET") {
const params = new URLSearchParams(req.url.split("?")[1]);
try {
const response = Whatsapp.get(Object.fromEntries(params));
res.writeHead(200, {"Content-Type": "text/html"});
res.write(response);
} catch (err) {
res.writeHead(err instanceof WhatsAppAPIError ? err.httpStatus : 500);
}
res.end();
} else res.writeHead(501).end();
};
const server = createServer(handler);
server.listen(3000);
Class WhatsAppAPIMissingVerifyTokenError if webhookVerifyToken is not specified
Class WhatsAppAPIMissingSearchParamsError if the request is missing data
Class WhatsAppAPIFailedToVerifyTokenError if the verification tokens don't match
GET request handler for Express.js
The request object from Express.js
The challenge string to be sent to the client
import express from "express";
import { WhatsAppAPI } from "whatsapp-api-js/middleware/express";
const app = express();
const Whatsapp = new WhatsAppAPI({
token: "YOUR_TOKEN",
appSecret: "YOUR_APP_SECRET",
webhookVerifyToken: "YOUR_WEBHOOK_VERIFY_TOKEN"
});
app.get("/message", (req, res) => {
try {
res.send(Whatsapp.handle_get(req));
} catch (e) {
res.sendStatus(e as number);
}
});
POST request handler for Express.js
The request object from Express.js
The status code to be sent to the client
import express from "express";
import { WhatsAppAPI } from "whatsapp-api-js/middleware/express";
const app = express();
const Whatsapp = new WhatsAppAPI({
token: "YOUR_TOKEN",
appSecret: "YOUR_APP_SECRET",
webhookVerifyToken: "YOUR_WEBHOOK_VERIFY_TOKEN"
});
// Your app shall use any express middleware, as long as the entry point where `handle_post`
// is called has the request body as a string, not a parsed body.
app.use(express.json());
// The `express.text({ type: '*/*' })` is optional if you are NOT using `express.json()`.
app.post("/message", express.text({ type: '*/*' }), async (req, res) => {
res.sendStatus(await Whatsapp.handle_post(req));
});
Mark a message as read
The bot's phone ID
The message ID
The server response
POST helper, must be called inside the post function of your code. When setting up the webhook, only subscribe to messages. Other subscritions support might be added later.
raw_body and signature are required when secure is true
on initialization (default).
The POSTed data object sent by Whatsapp
The raw body of the POST request
The x-hub-signature-256 header signature sent by Whatsapp
The emitter's return value, undefined if the corresponding emitter isn't set
// author arivanbastos on issue #114
// Simple http example implementation with Whatsapp.post() on Node@^19
import { WhatsAppAPI } from "whatsapp-api-js";
import { WhatsAppAPIError } from "whatsapp-api-js/errors";
import { NodeNext } from "whatsapp-api-js/setup/node";
import { createServer } from "http";
const token = "token";
const appSecret = "appSecret";
const Whatsapp = new WhatsAppAPI<number>(NodeNext({ token, appSecret }));
function handler(req, res) {
if (req.method == "POST") {
const chunks = [];
req.on("data", (chunk) => chunks.push(chunk));
req.on("end", async () => {
const body = Buffer.concat(chunks).toString();
try {
const response = await Whatsapp.post(JSON.parse(body), body, req.headers["x-hub-signature-256"]);
res.writeHead(response);
} catch (err) {
res.writeHead(err instanceof WhatsAppAPIError ? err.httpStatus : 500);
}
res.end();
});
} else res.writeHead(501).end();
};
Whatsapp.on.message = ({ phoneID, from, message, name, reply, offload }) => {
console.log(`User ${name} (${from}) sent to bot ${phoneID} a(n) ${message.type}`);
offload(() => reply(new Text("Hello!")));
return 202;
};
const server = createServer(handler);
server.listen(3000);
Class WhatsAppAPIMissingRawBodyError if the raw body is missing
Class WhatsAppAPIMissingSignatureError if the signature is missing
Class WhatsAppAPIMissingAppSecretError if the appSecret isn't defined
Class WhatsAppAPIMissingCryptoSubtleError if crypto.subtle or ponyfill isn't available
Class WhatsAppAPIFailedToVerifyError if the signature doesn't match the hash
Class WhatsAppAPIUnexpectedError if the POSTed data is not a valid Whatsapp API request
Class WhatsAppAPIUnexpectedError if the POSTed data is valid but not a message or status update (ignored)
POST helper, must be called inside the post function of your code. When setting up the webhook, only subscribe to messages. Other subscritions support might be added later.
raw_body and signature are NOT required when secure is false
on initialization.
The POSTed data object sent by Whatsapp
The emitter's return value, undefined if the corresponding emitter isn't set
The method isn't deprecated, but it's strongly discouraged to use the server without signature verification. It's a security risk.
Provide an appSecret
and set secure
to true on WhatsAppAPI initialization.
Class WhatsAppAPIUnexpectedError if the POSTed data is not a valid Whatsapp API request
Class WhatsAppAPIUnexpectedError if the POSTed data is valid but not a message or status update (ignored)
Get a Media object data with an ID
The Media's ID
Optional
phoneID: stringBusiness phone number ID. If included, the operation will only be processed if the ID matches the ID of the business phone number that the media was uploaded on.
The server response
Get one or many QR codes of the bot
The bot's phone ID
Optional
id: stringThe QR's id to find. If not specified, all QRs will be returned
The server response
Send a Whatsapp message
The bot's phone ID
The user's phone number
A Whatsapp message, built using the corresponding module for each type of message.
Optional
context: stringThe message ID of the message to reply to
Optional
biz_opaque_callback_data: stringAn arbitrary 512B string, useful for tracking (length not checked by the framework)
The server response
Update a QR code of the bot
The bot's phone ID
The QR's id to edit
The new quick message for the QR code
The server response
Upload a Media to the API server
The bot's phone ID
The Media's FormData. Must have a 'file' property with the file to upload as a blob and a valid mime-type in the 'type' field of the blob. Example for Node ^18: new FormData().set("file", new Blob([stringOrFileBuffer], "image/png"));
Previous versions of Node will need an external FormData, such as undici's. To use non spec complaints versions of FormData (eg: form-data) or Blob set the 'check' parameter to false.
If the FormData should be checked before uploading. The FormData must have the method .get("name") to work with the checks. If it doesn't (for example, using the module "form-data"), set this to false.
The server response
// author ekoeryanto on issue #322
import { WhatsAppAPI } from "whatsapp-api-js";
const token = "token";
const appSecret = "appSecret";
const Whatsapp = new WhatsAppAPI({ token, appSecret });
const url = "https://example.com/image.png";
const image = await fetch(url);
const blob = await image.blob();
// If required:
// import FormData from "undici";
const form = new FormData();
form.set("file", blob);
console.log(await Whatsapp.uploadMedia("phoneID", form));
// Expected output: { id: "mediaID" }
import { WhatsAppAPI } from "whatsapp-api-js";
const token = "token";
const appSecret = "appSecret";
const Whatsapp = new WhatsAppAPI({ token, appSecret });
// If required:
// import FormData from "undici";
// import { Blob } from "node:buffer";
const form = new FormData();
// If you don't mind reading the whole file into memory:
form.set("file", new Blob([fs.readFileSync("image.png")], "image/png"));
// If you do, you will need to use streams. The module "form-data",
// although not spec compliant (hence needing to set check to false),
// has an easy way to do this:
// form.append("file", fs.createReadStream("image.png"), { contentType: "image/png" });
console.log(await Whatsapp.uploadMedia("phoneID", form));
// Expected output: { id: "mediaID" }
Verify the signature of a request
The raw body of the request
The signature to validate
If the signature is valid
Class WhatsAppAPIMissingAppSecretError if the appSecret isn't defined
Class WhatsAppAPIMissingCryptoSubtleError if crypto.subtle or ponyfill isn't available
Static
offload
Express.js middleware for WhatsAppAPI