whatsapp-api-js - v5.2.0
    Preparing search index...

    Class ExpressMiddleware

    Express.js middleware for WhatsAppAPI

    Hierarchy (View Summary)

    Index

    Constructors

    • 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.

      Parameters

      Returns ExpressMiddleware

      import { WhatsAppAPI } from "whatsapp-api-js";

      const Whatsapp = new WhatsAppAPI({
      token: "YOUR_TOKEN",
      appSecret: "YOUR_APP_SECRET"
      });

      If fetch is not defined in the enviroment and the provided ponyfill isn't a function

      If secure is true, crypto.subtle is not defined in the enviroment and the provided ponyfill isn't an object

    Properties

    on: { message?: OnMessage<void>; sent?: OnSent; status?: OnStatus<void> } = {}

    The callbacks for the events (message, sent, status)

    const Whatsapp = new WhatsAppAPI({
    token: "my-token",
    appSecret: "my-app-secret"
    });

    // Set the callback
    Whatsapp.on.message = ({ from, phoneID }) => console.log(`Message from ${from} to bot ${phoneID}`);

    // If you need to disable the callback:
    // Whatsapp.on.message = undefined;

    Methods

    • 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.

      Parameters

      • url: string | URL | Request

        The url to fetch

      • options: RequestInit = {}

        The fetch options (headers.Authorization is already included)

      Returns Promise<Response>

      The fetch response

    • Block a user from sending messages to the bot

      The block API has 2 restrictions:

      • You can only block users that have messaged your business in the last 24 hours
      • You can only block up to 64k users

      Parameters

      • phoneID: string

        The bot's phone ID from which to block

      • ...users: string[]

        The user phone numbers to block (the API doesn't fail if it's empty)

      Returns Promise<ServerBlockResponse | Response>

      The server 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.

      Parameters

      • phoneID: string

        The bot's phone ID

      • to: string[]

        The users' phone numbers

      • message: ClientMessage

        A Whatsapp message, built using the corresponding module for each type of message.

      • batch_size: number

        The number of messages to send per batch

      • delay: number

        The delay between each batch of messages in milliseconds

      Returns Promise<ServerMessageResponse | Response>[]

      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);

      if batch_size is lower than 1

      if delay is lower than 0

    • Type Parameters

      • T

        The type of the data to be used in the message builder

      Parameters

      • phoneID: string

        The bot's phone ID

      • to: T[]

        The users' data

      • message_builder: (data: T) => [string, ClientMessage]

        A Whatsapp message builder, it returns an array with the phone number and the message.

      • batch_size: number

        The number of messages to send per batch

      • delay: number

        The delay between each batch of messages in milliseconds

      Returns Promise<ServerMessageResponse | Response>[]

      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);

      if batch_size is lower than 1

      if delay is lower than 0

    • Generate a QR code for sharing the bot

      Parameters

      • phoneID: string

        The bot's phone ID

      • message: string

        The quick message on the QR code

      • format: "png" | "svg" = "png"

        The format of the QR code

      Returns Promise<ServerCreateQRResponse | Response>

      The server response

    • Delete a Media object with an ID

      Parameters

      • id: string

        The Media's ID

      • OptionalphoneID: string

        Business 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.

      Returns Promise<ServerMediaDeleteResponse | Response>

      The server response

    • Get a Media fetch from an url. When using this method, be sure to pass a trusted url, since the request will be authenticated with the token.

      Parameters

      • url: string

        The Media's url

      Returns Promise<Response>

      The fetch raw response

      import { WhatsAppAPI } from "whatsapp-api-js";

      const token = "token";
      const appSecret = "appSecret";

      const Whatsapp = new WhatsAppAPI({ token, appSecret });

      const id = "mediaID";
      const { url } = await Whatsapp.retrieveMedia(id);
      const response = Whatsapp.fetchMedia(url);

      If url is not a valid url

    • GET helper, must be called inside the get function of your code. Used once at the first webhook setup.

      Parameters

      • params: GetParams

        The request object sent by Whatsapp

      Returns string

      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

      Parameters

      • req: Request

        The request object from Express.js

      Returns string

      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);
      }
      });

      The error code

    handle_post

    • handle_post(req: Request): Promise<number>

      POST request handler for Express.js

      Parameters

      • req: Request

        The request object from Express.js

      Returns Promise<number>

      The status code to be sent to the client

      This method expects the request body to be the original string, not a parsed body

      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));
      });

    post

    • post(
          data: PostData,
          raw_body: string,
          signature: string,
      ): Promise<undefined | void>

      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).

      Parameters

      • data: PostData

        The POSTed data object sent by Whatsapp

      • raw_body: string

        The raw body of the POST request

      • signature: string

        The x-hub-signature-256 header signature sent by Whatsapp

      Returns Promise<undefined | void>

      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

      Any error generated within the user's callbacks

      Class WhatsAppAPIUnexpectedError if the POSTed data is valid but not a message or status update (ignored)

    • post(data: PostData): Promise<undefined | void>

      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.

      Parameters

      • data: PostData

        The POSTed data object sent by Whatsapp

      Returns Promise<undefined | void>

      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

      Any error generated within the user's callbacks

      Class WhatsAppAPIUnexpectedError if the POSTed data is valid but not a message or status update (ignored)

    • Send a Whatsapp message

      Parameters

      • phoneID: string

        The bot's phone ID

      • to: string

        The user's phone number

      • message: ClientMessage

        A Whatsapp message, built using the corresponding module for each type of message.

      • Optionalcontext: string

        The message ID of the message to reply to

      • Optionalbiz_opaque_callback_data: string

        An arbitrary 512B string, useful for tracking (length not checked by the framework)

      Returns Promise<ServerMessageResponse | Response>

      The server response

      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"
      });

      Whatsapp.sendMessage(
      "BOT_PHONE_ID",
      "USER_PHONE",
      new Text("Hello World")
      ).then(console.log);
    • Unblock a user from the bot's block list

      Parameters

      • phoneID: string

        The bot's phone ID from which to unblock

      • ...users: string[]

        The user phone numbers to unblock (the API doesn't fail if it's empty)

      Returns Promise<ServerUnblockResponse | Response>

      The server response

      Contrary to blocking, unblocking isn't restricted by the 24 hours rule

    • Upload a Media to the API server

      Parameters

      • phoneID: string

        The bot's phone ID

      • form: unknown

        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.

      • check: boolean = true

        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.

      Returns Promise<ServerMediaUploadResponse | Response>

      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" }

      If check is set to true and form is not a FormData

      If check is set to true and the form doesn't have valid required properties (file, type)

      If check is set to true and the form file is too big for the file type

    • Offload a function to the next tick of the event loop

      Parameters

      • f: () => unknown

        The function to offload from the main thread

      Returns void