WhatsApp Cloud TS

Webhook Parsing API Reference

Detailed information on flattening Meta's deeply nested webhook payloads into clean, strongly-typed events.

Meta's webhooks natively look like this: entry[0].changes[0].value.messages[0]. This package provides parseWebhook() to flatten this into a strongly-typed WebhookEvent[] array.

Base Properties

Every message-based event (Text, Image, Location, etc.) includes these base properties:

PropertyTypeDescription
typestringThe event type (e.g. "text", "image", "status").
fromstringThe WhatsApp ID (phone number) of the user who sent the message.
displayPhoneNumberstringThe display phone number of the business account receiving the message.
phoneNumberIdstringThe WhatsApp Business Phone Number ID.
messageIdstringThe unique wamid for this message.
timestampDateA standard JavaScript Date object when the message was sent.

Event-Specific Properties

TextEvent (type: "text")

textstringThe text body sent by the user.

Media Events ("image", "video", "document")

imageId / videoId / documentIdstringThe ID of the media. Pass this to client.getMediaUrl(id) to download.
mimeTypestringThe MIME type of the media file.
captionstring?Optional text caption sent with the media.

StatusEvent (Delivery Receipts) (type: "status")

Note: Status events do not have a from property; they have a recipientId instead.

status"sent" | "delivered" | "read" | "failed"The current status of your outbound message.
recipientIdstringThe phone number of the user who received/read the message.
errorsArray?If status is "failed", this contains the error details (code, title, message).

Webhook Verification

When you first set up your webhook in the Meta App Dashboard, Meta sends a GET request with a challenge string to verify your endpoint. You can use verifyWebhook to handle this validation automatically.

First, ensure you have added your custom VERIFY_TOKEN (which you set in the Meta App Dashboard) to your .env file:

VERIFY_TOKEN=my_super_secret_verify_token
import { verifyWebhook } from "whatsapp-cloud-ts";

// Handle the GET request for initial verification
app.get("/webhook", (req, res) => {
  // Pass req.query and your secret verify token from Meta App Dashboard
  const challenge = verifyWebhook(req.query, process.env.VERIFY_TOKEN!);
  
  if (challenge) {
    res.send(challenge); // Validation successful
  } else {
    res.sendStatus(403); // Validation failed
  }
});

Express.js Example (Parsing)

import { parseWebhook, verifyWebhook } from "whatsapp-cloud-ts";
import express from "express";

const app = express();
app.use(express.json());

app.post("/webhook", (req, res) => {
  const events = parseWebhook(req.body);

  for (const event of events) {
    if (event.type === "text") {
      console.log(`Text from ${event.from}: ${event.text}`);
    } else if (event.type === "status") {
      console.log(`Message ${event.messageId} to ${event.recipientId} is ${event.status}`);
    }
  }

  res.sendStatus(200);
});