### Install WhatsApp Cloud API SDK Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Command to install the @kapso/whatsapp-cloud-api package via npm. ```bash npm install @kapso/whatsapp-cloud-api ``` -------------------------------- ### Handle WhatsApp Flow Events with Edge/Fetch API Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/docs/flows.md This example shows how to handle WhatsApp flow events using the standard Fetch API, suitable for serverless environments like Vercel Edge Functions. It processes incoming requests, extracts the raw body, and uses the SDK to receive and respond to flow events. ```typescript import { receiveFlowEvent, respondToFlow } from "@kapso/whatsapp-cloud-api/server"; export default async function handler(request: Request) { const buffer = new Uint8Array(await request.arrayBuffer()); const ctx = await receiveFlowEvent({ rawBody: buffer, phoneNumberId: process.env.PHONE_ID!, getPrivateKey: async () => process.env.FLOW_PRIVATE_KEY_PEM! }); const reply = respondToFlow({ screen: ctx.screen, data: {} }); return new Response(reply.body, { status: reply.status, headers: reply.headers }); } ``` -------------------------------- ### GET /templates Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Retrieves or lists message templates from the WhatsApp Business Account. ```APIDOC ## GET /templates ### Description Retrieves a list of templates or a specific template by ID. ### Method GET ### Endpoint /templates/list or /templates/get ### Parameters #### Query Parameters - **businessAccountId** (string) - Required - The WABA ID. - **status** (string) - Optional - Filter by status (e.g., APPROVED). - **templateId** (string) - Optional - Specific ID for retrieval. ### Response #### Success Response (200) - **data** (array) - List of template objects. ``` -------------------------------- ### Handle WhatsApp Flow Events with Express Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/docs/flows.md This Express.js example demonstrates how to set up a webhook to receive and respond to WhatsApp flow events. It uses the SDK's `receiveFlowEvent` to parse incoming requests and `respondToFlow` to generate responses. It handles both CSAT completion and general flow interactions, including error management. ```typescript import express from "express"; import { receiveFlowEvent, respondToFlow } from "@kapso/whatsapp-cloud-api/server"; const app = express(); const phoneNumberId = process.env.PHONE_ID!; const flowKey = process.env.FLOW_PRIVATE_KEY_PEM!; app.post("/flows/csat", express.raw({ type: "*/*" }), async (req, res) => { try { const ctx = await receiveFlowEvent({ rawBody: req.body as Buffer, phoneNumberId, getPrivateKey: async () => flowKey }); if (ctx.action === "COMPLETE") { console.log("CSAT rating:", ctx.form.rating); const reply = respondToFlow({ screen: ctx.screen, data: {} }); return res.status(reply.status).set(reply.headers).send(reply.body); } const reply = respondToFlow({ screen: ctx.screen, data: {} }); res.status(reply.status).set(reply.headers).send(reply.body); } catch (error) { if (error instanceof Error && "status" in error) { const flowError = error as any; return res.status(flowError.status).set(flowError.headers).send(flowError.body); } res.status(500).send({ error: "Unexpected error" }); } }); ``` -------------------------------- ### Create WhatsApp Message Template Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Defines and creates a new message template for the WhatsApp Cloud API using the `TemplateDefinition.buildTemplateDefinition` helper. This includes specifying header, body, footer, and button components with parameters and examples. ```typescript import { TemplateDefinition } from "@kapso/whatsapp-cloud-api"; const templateDefinition = TemplateDefinition.buildTemplateDefinition({ name: "seasonal_promo", language: "en_US", category: "MARKETING", parameterFormat: "NAMED", components: [ { type: "HEADER", format: "TEXT", text: "Our {{sale_name}} is on!", example: { headerTextNamedParams: [{ paramName: "sale_name", example: "Summer Sale" }] } }, { type: "BODY", text: "Shop now through {{end_date}} using code {{discount_code}}", example: { bodyTextNamedParams: [ { paramName: "end_date", example: "Aug 31" }, { paramName: "discount_code", example: "SALE25" } ] } }, { type: "FOOTER", text: "Tap a button below" }, { type: "BUTTONS", buttons: [ { type: "QUICK_REPLY", text: "Unsubscribe" }, { type: "URL", text: "Shop", url: "https://store.example/promo?code={{discount_code}}", example: ["SALE25"] } ] } ], }); await client.templates.create({ businessAccountId: "", name: templateDefinition.name, language: templateDefinition.language, category: templateDefinition.category, parameterFormat: templateDefinition.parameterFormat, components: templateDefinition.components, }); ``` -------------------------------- ### Business Profile Management Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Get and update WhatsApp Business profile information. ```APIDOC ## Business Profile Management Get and update WhatsApp Business profile information. ### Description This section covers how to retrieve and modify the business profile associated with a WhatsApp phone number, including details like 'about' text, description, email, websites, and business vertical. ### Methods - `get`: Retrieves the business profile information. - `update`: Updates the business profile information. ### Parameters #### `get` - **phoneNumberId** (string) - Required - The ID of the phone number. #### `update` - **phoneNumberId** (string) - Required - The ID of the phone number. - **about** (string) - Optional - The 'about' text for the business profile. - **description** (string) - Optional - A detailed description of the business. - **email** (string) - Optional - The business email address. - **websites** (array) - Optional - A list of website URLs for the business. - **vertical** (string) - Optional - The industry vertical of the business (e.g., 'RETAIL'). ### Example Usage (TypeScript) ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); // Get business profile const profile = await client.phoneNumbers.businessProfile.get({ phoneNumberId: "1234567890", }); console.log("About:", profile.data[0].about); // Update business profile await client.phoneNumbers.businessProfile.update({ phoneNumberId: "1234567890", about: "Your trusted partner for quality products", description: "We provide premium products with excellent customer service.", email: "support@example.com", websites: ["https://example.com", "https://shop.example.com"], vertical: "RETAIL", }); ``` ``` -------------------------------- ### GET /conversations Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt List, retrieve, and update the status of WhatsApp conversations managed through the Kapso proxy. ```APIDOC ## GET /conversations ### Description List active conversations or retrieve details for a specific conversation ID. ### Method GET ### Endpoint /conversations ### Parameters #### Query Parameters - **phoneNumberId** (string) - Required - The WhatsApp phone number ID. - **status** (string) - Optional - Filter by conversation status (e.g., active). - **lastActiveSince** (string) - Optional - ISO 8601 timestamp for filtering. - **limit** (number) - Optional - Max records to return. ### Response #### Success Response (200) - **data** (array) - List of conversation objects. ### Response Example { "data": [{ "id": "conv_123", "status": "active" }] } ``` -------------------------------- ### WhatsApp Flow Validation Error Structure Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/docs/flows.md This JSON example illustrates the structure of validation errors returned by Meta when authoring Flow JSON. It includes error codes, types, messages, pointers to the problematic fields (with line and column numbers), and helpful hints for correcting issues, particularly regarding camelCase naming conventions. ```json [ { "error": "INVALID_PROPERTY_VALUE", "errorType": "FLOW_JSON_ERROR", "message": "Invalid value for property", "pointers": [ { "path": "screens[0].layout.children[0].on-click-action", "lineStart": 10, "columnStart": 5 } ], "hint": "Use onClickAction (camelCase). We map it to on-click-action." } ] ``` -------------------------------- ### Initialize WhatsApp Client Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Demonstrates how to instantiate the WhatsAppClient using either a standard Meta access token or a Kapso proxy configuration. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; // Standard Meta setup const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN!, }); // Kapso proxy setup const proxyClient = new WhatsAppClient({ baseUrl: "https://api.kapso.ai/meta/whatsapp", kapsoApiKey: process.env.KAPSO_API_KEY!, }); ``` -------------------------------- ### Initialize WhatsAppClient Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Configure the client using either a Meta access token for direct API access or a Kapso API key for proxy-enhanced features. You can also provide a custom fetch implementation for specific runtime requirements. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; // Direct Meta Graph API access const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN!, graphVersion: "v23.0", }); // Via Kapso proxy const kapsoClient = new WhatsAppClient({ baseUrl: "https://api.kapso.ai/meta/whatsapp", kapsoApiKey: process.env.KAPSO_API_KEY!, }); // Custom fetch implementation const customClient = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN!, fetch: customFetchImplementation, }); ``` -------------------------------- ### Make Raw API Requests Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Shows how to use the `client.fetch()` helper to make requests to any absolute URL. This method automatically applies the client's authentication headers (either Meta's or Kapso's). It's useful for accessing resources directly, though `media.download()` often suffices for media. ```typescript // Sends Authorization (Meta) or X-API-Key (Kapso) automatically const response = await client.fetch("https://files.example/resource", { headers: { Accept: "image/*" }, }); ``` -------------------------------- ### Get a WhatsApp Message Template Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Retrieves a specific message template from the WhatsApp Cloud API using its unique ID. This operation requires the `businessAccountId` and `templateId`. ```typescript const template = await client.templates.get({ businessAccountId: "", templateId: "", }); ``` -------------------------------- ### Deploying and Previewing Flows Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/docs/flows.md Use the WhatsAppClient to deploy flow definitions to the WhatsApp Business Account. The deploy method is idempotent and supports automatic publishing and preview URL generation. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; import csatFlow from "./flows/csat.flow"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); const result = await client.flows.deploy(csatFlow, { wabaId: process.env.WABA_ID!, name: "csat-flow", publish: true, preview: true }); console.log("Flow ID:", result.flowId); console.log("Preview URL:", result.previewUrl); ``` -------------------------------- ### Receiving Media Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md This section details how to handle incoming media messages, offering two primary methods: URL-first with Kapso for direct rendering and a bytes fallback for raw data retrieval. ```APIDOC ## Receiving Media This section details how to handle incoming media messages, offering two primary methods: URL-first with Kapso for direct rendering and a bytes fallback for raw data retrieval. ### 1. URL-first with Kapso Kapso stores inbound media and mirrors outbound media. Retrieve media URLs using `kapso(media_url)` when listing messages. ```ts import { buildKapsoMessageFields } from "@kapso/whatsapp-cloud-api"; const fields = buildKapsoMessageFields("media_url"); const page = await client.messages.listByConversation({ phoneNumberId: "", conversationId: "", fields, }); const msg = page.data.find(m => m.type === "image"); const src = msg?.kapso?.mediaUrl ?? msg?.image?.link; // use direct URL when present ``` ### 2. Bytes Fallback (Universal) Use `download()` to get raw bytes if the URL is not yet mirrored or if raw data is needed. The SDK handles authentication headers automatically. - `client.media.download({ mediaId, ... })` resolves the short-lived URL and fetches bytes. - Return types: `ArrayBuffer` (default), `Blob` (with `as: "blob"`), `Response` (with `as: "response"`). - For Kapso proxy, pass `phoneNumberId`. #### Example: Downloading Media Bytes ```ts // 1) From a message record you loaded (e.g., via client.messages.query): const { data } = await client.messages.query({ phoneNumberId: "", limit: 1, }); const msg = data[0]; if (msg.type === "image" && msg.image?.id) { const mediaId = msg.image.id; const bytes = await client.media.download({ mediaId, phoneNumberId: "", }); // bytes is an ArrayBuffer; do what you need with it } ``` ``` -------------------------------- ### POST /templates/create Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Creates a new message template for a WhatsApp Business Account. ```APIDOC ## POST /templates/create ### Description Creates a new message template definition on the WhatsApp Business Account. ### Method POST ### Endpoint /templates/create ### Parameters #### Request Body - **businessAccountId** (string) - Required - The WABA ID. - **name** (string) - Required - Template name. - **language** (string) - Required - Language code. - **category** (string) - Required - Template category (e.g., MARKETING). - **components** (array) - Required - Array of template components (Header, Body, Footer, Buttons). ### Request Example { "businessAccountId": "WABA_ID", "name": "seasonal_promo", "language": "en_US", "category": "MARKETING" } ``` -------------------------------- ### Get and Delete WhatsApp Media Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Retrieves metadata for uploaded media or deletes media from your WhatsApp Business Account. Requires the media ID and phone number ID. Metadata includes URL, MIME type, file size, and SHA256 hash. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); // Get media metadata const metadata = await client.media.get({ mediaId: "media_id_here", phoneNumberId: "1234567890", // required for Kapso proxy }); console.log("Media URL:", metadata.url); console.log("MIME Type:", metadata.mimeType); // Output: { id: "...", url: "https://...", mime_type: "image/jpeg", sha256: "...", file_size: 12345 } // Delete media const deleteResult = await client.media.delete({ mediaId: "media_id_here", phoneNumberId: "1234567890", }); console.log("Deleted:", deleteResult.success); ``` -------------------------------- ### Receive Media using Kapso URL Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Demonstrates how to retrieve media URLs stored by Kapso when receiving messages. It suggests using `buildKapsoMessageFields` to fetch `media_url` and then rendering it directly. Includes a fallback to the direct image link if Kapso's URL is not available. ```typescript import { buildKapsoMessageFields } from "@kapso/whatsapp-cloud-api"; const fields = buildKapsoMessageFields("media_url"); const page = await client.messages.listByConversation({ phoneNumberId: "", conversationId: "", fields, }); const msg = page.data.find(m => m.type === "image"); const src = msg?.kapso?.mediaUrl ?? msg?.image?.link; // use direct URL when present ``` -------------------------------- ### List and Retrieve Templates Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Demonstrates how to fetch a list of templates with filters and retrieve details for a specific template ID. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); const templates = await client.templates.list({ businessAccountId: "WABA_ID", status: "APPROVED", category: "MARKETING", limit: 20, }); console.log("Templates:", templates.data); const template = await client.templates.get({ businessAccountId: "WABA_ID", templateId: "template_id", }); console.log("Template:", template.name, template.status); ``` -------------------------------- ### Deploy a Flow Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Deploys a WhatsApp Flow definition. Requires the flow JSON, WhatsApp Business Account ID (wabaId), a name for the flow, and flags for publishing and previewing. Imports the WhatsAppClient. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const flowJson = { version: "7.2", screens: [ { id: "CSAT", terminal: true, layout: { type: "SingleColumnLayout", children: [ { type: "RadioButtonsGroup", name: "rating", label: "Rate us", dataSource: [ { id: "up", title: "👍" }, { id: "down", title: "👎" } ] }, { type: "Footer", label: "Submit", onClickAction: { name: "complete", payload: { rating: "${form.rating}" } } } ] } } ] }; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); await client.flows.deploy(flowJson, { wabaId: process.env.WABA_ID!, name: "csat-flow", publish: true, preview: true }); ``` -------------------------------- ### Raw Fetch Helper Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Use the `client.fetch()` method to make authenticated requests to any absolute URL. ```APIDOC ## Raw Fetch Helper Use `client.fetch(url, init?)` to make a request to any absolute URL with the client’s auth headers applied. This is useful for fetching resources directly from external URLs or Kapso hosts. ### Example: Fetching a Resource ```ts // Sends Authorization (Meta) or X-API-Key (Kapso) automatically const response = await client.fetch("https://files.example/resource", { headers: { Accept: "image/*", }, }); if (response.ok) { const data = await response.arrayBuffer(); // Process the fetched data } else { console.error("Failed to fetch resource:", response.statusText); } ``` **Note:** Most users do not need this for media anymore because `media.download()` handles header policy automatically. ``` -------------------------------- ### Process Webhooks with Signature Verification Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Demonstrates setting up an Express.js server to handle incoming WhatsApp webhooks. It includes verifying the request signature using `verifySignature` and normalizing the payload with `normalizeWebhook` to easily access messages, statuses, and calls. The normalized events provide additional Kapso-specific fields like `kapso.direction`. ```typescript import express from "express"; import { normalizeWebhook, verifySignature } from "@kapso/whatsapp-cloud-api/server"; app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => { const ok = verifySignature({ appSecret: process.env.META_APP_SECRET!, rawBody: req.body, signatureHeader: req.headers["x-hub-signature-256"] as string, }); if (!ok) return res.status(401).end(); const payload = JSON.parse(req.body.toString("utf8")); const events = normalizeWebhook(payload); events.messages.forEach((message) => { // message matches the same shape returned by client.messages.query() }); events.statuses.forEach((status) => { // handle delivery receipts }); events.calls.forEach((call) => { // handle calling events }); res.sendStatus(200); }); // events.contacts contains the contact array from the webhook, already camelCased ``` -------------------------------- ### POST /calls Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Initiate, accept, reject, or terminate WhatsApp voice calls and check user call permissions. ```APIDOC ## POST /calls/connect ### Description Initiates an outbound voice call to a specific WhatsApp user. ### Method POST ### Endpoint /calls/connect ### Parameters #### Request Body - **phoneNumberId** (string) - Required - The WhatsApp phone number ID. - **to** (string) - Required - The recipient's WhatsApp ID. - **session** (object) - Required - SDP session details. - **bizOpaqueCallbackData** (string) - Optional - Custom reference data. ### Response #### Success Response (200) - **callId** (string) - The unique identifier for the initiated call. ``` -------------------------------- ### Manage WhatsApp Flows Lifecycle Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Demonstrates how to create, update, publish, preview, list, and deprecate WhatsApp Flows. Requires a valid WhatsApp Business Account ID and flow JSON structure. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); // Create a new flow const createResult = await client.flows.create({ wabaId: "WABA_ID", name: "my-flow", flowJson: { version: "7.2", screens: [] }, publish: false, }); // Update flow asset await client.flows.updateAsset({ flowId: createResult.id, json: { version: "7.2", screens: [] }, }); // Publish flow await client.flows.publish({ flowId: createResult.id }); // Get flow preview URL const preview = await client.flows.preview({ flowId: createResult.id, interactive: true, }); console.log("Preview:", preview.preview.previewUrl); // List flows const flows = await client.flows.list({ wabaId: "WABA_ID", limit: 20 }); // Deprecate flow await client.flows.deprecate({ flowId: createResult.id }); ``` -------------------------------- ### Typed Client Requests Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Illustrates how to make low-level client requests with specific response types using `client.request()`. This allows for strongly-typed responses from the API, improving code safety and developer experience. ```typescript const response = await client.request("GET", "", { responseType: "json", }); ``` -------------------------------- ### Webhooks Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Set up and handle incoming webhook events from WhatsApp, including message status updates and new messages. ```APIDOC ## Webhooks Set up and handle incoming webhook events from WhatsApp, including message status updates and new messages. ### Setting up a Webhook Endpoint This example demonstrates how to set up an Express.js endpoint to receive and process webhook events. ```ts import express from "express"; import { normalizeWebhook, verifySignature } from "@kapso/whatsapp-cloud-api/server"; const app = express(); app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => { const ok = verifySignature({ appSecret: process.env.META_APP_SECRET!, rawBody: req.body, signatureHeader: req.headers["x-hub-signature-256"] as string, }); if (!ok) { return res.status(401).end(); } const payload = JSON.parse(req.body.toString("utf8")); const events = normalizeWebhook(payload); // Process incoming messages events.messages.forEach((message) => { // message matches the same shape returned by client.messages.query() console.log("Received message:", message); }); // Process message statuses (e.g., delivery receipts) events.statuses.forEach((status) => { console.log("Message status update:", status); }); // Process calling events events.calls.forEach((call) => { console.log("Incoming call event:", call); }); // contacts contains the contact array from the webhook, already camelCased if (events.contacts && events.contacts.length > 0) { console.log("Received contacts:", events.contacts); } res.sendStatus(200); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Webhook server listening on port ${PORT}`); }); ``` ### Webhook Event Normalization `normalizeWebhook()` unwraps the raw Graph API payload into a structured object containing `messages`, `statuses`, `calls`, and `contacts`. Fields are camelCased for consistency. It also adds `kapso.direction` (`"inbound"`/`"outbound"`) to messages and tags SMB echoes with `kapso.source = "smb_message_echo"`. Other webhook fields are available under `events.raw.`. ``` -------------------------------- ### POST /templates/define Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Defines a new template structure for review and creation on the WhatsApp platform. ```APIDOC ## POST /templates/define ### Description Validates and defines a template structure, including support for authentication, named parameters, and marketing components. ### Method POST ### Parameters #### Request Body - **name** (string) - Required - Unique template name. - **category** (string) - Required - Template category (e.g., AUTHENTICATION, UTILITY, MARKETING). - **components** (array) - Required - List of template components. - **parameterFormat** (string) - Optional - Format of parameters (e.g., 'NAMED'). ### Request Example { "name": "authentication_code", "language": "en_US", "category": "AUTHENTICATION", "components": [ { "type": "BODY", "addSecurityRecommendation": true } ] } ``` -------------------------------- ### Query WhatsApp Data with Kapso Proxy Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Demonstrates how to query conversations, message history, contacts, and call logs using the Kapso proxy for the WhatsApp Cloud API. It requires initializing the client with Kapso's baseUrl and apiKey. The endpoints return Meta-compatible records with Graph paging, including Kapso extensions. ```typescript const client = new WhatsAppClient({ baseUrl: "https://api.kapso.ai/meta/whatsapp", kapsoApiKey: process.env.KAPSO_API_KEY!, }); // Conversations const conversations = await client.conversations.list({ phoneNumberId: "647015955153740", status: "active", limit: 50, }); const conversation = await client.conversations.get({ conversationId: conversations.data[0].id, }); await client.conversations.updateStatus({ conversationId: conversation.id, status: "ended", }); // Message history const history = await client.messages.query({ phoneNumberId: "647015955153740", direction: "inbound", since: "2025-01-01T00:00:00Z", limit: 50, after: conversations.paging.cursors.after, }); const message = await client.messages.get({ phoneNumberId: "647015955153740", messageId: history.data[0].id, fields: "kapso(default)", }); // Contacts const contacts = await client.contacts.list({ phoneNumberId: "647015955153740", customerId: "123", }); await client.contacts.update({ phoneNumberId: "647015955153740", waId: contacts.data[0].waId, metadata: { tags: ["vip"], source: "import" }, }); // Call logs const calls = await client.calls.list({ phoneNumberId: "647015955153740", direction: "INBOUND", limit: 20, }); const call = await client.calls.get({ phoneNumberId: "647015955153740", callId: calls.data[0].id, }); ``` -------------------------------- ### POST /templates/build Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Constructs a template payload for sending messages using Meta-style components. ```APIDOC ## POST /templates/build ### Description Builds a template payload for sending messages. It normalizes casing and enforces the required shape for components. ### Method POST ### Parameters #### Request Body - **name** (string) - Required - The name of the template. - **language** (string|object) - Required - The language code (e.g., 'en_US') or an object with code and policy. - **components** (array) - Required - Array of component objects containing type and parameters. ### Request Example { "name": "order_confirmation", "language": "en_US", "components": [ { "type": "body", "parameters": [{ "type": "text", "text": "Jessica", "parameter_name": "customer_name" }] } ] } ``` -------------------------------- ### Download Media using Bytes Fallback Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Provides a universal method to download raw media bytes when the URL is not yet mirrored or when raw data is needed. It uses `client.media.download()` which handles authentication for public CDNs and Kapso hosts. The function supports returning `ArrayBuffer`, `Blob`, or `Response`. ```typescript // 1) From a message record you loaded (e.g., via client.messages.query): const { data } = await client.messages.query({ phoneNumberId: "", limit: 1, }); const msg = data[0]; if (msg.type === "image" && msg.image?.id) { const mediaId = msg.image.id; const bytes = await client.media.download({ mediaId, phoneNumberId: "", }); // bytes is an ArrayBuffer; do what you need with it ``` -------------------------------- ### Initiate and Manage WhatsApp Voice Calls Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Provides methods to connect, accept, reject, and terminate voice calls, as well as checking user call permissions. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); // Initiate an outbound call const callResult = await client.calls.connect({ phoneNumberId: "1234567890", to: "+15551234567", session: { sdpType: "offer", sdp: "v=0\r\n..." }, bizOpaqueCallbackData: "call-ref-123", }); console.log("Call ID:", callResult.callId); // Accept an incoming call await client.calls.accept({ phoneNumberId: "1234567890", callId: "incoming_call_id", session: { sdpType: "answer", sdp: "v=0\r\n..." }, }); // Reject a call await client.calls.reject({ phoneNumberId: "1234567890", callId: "call_id", }); // Terminate an active call await client.calls.terminate({ phoneNumberId: "1234567890", callId: "call_id", }); // Check call permissions const permissions = await client.calls.permissions.get({ phoneNumberId: "1234567890", userWaId: "15551234567", }); console.log("Can call:", permissions.permission); ``` -------------------------------- ### Manage Conversations via Kapso Proxy Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Demonstrates how to list, retrieve, and update the status of WhatsApp conversations. Requires a configured WhatsAppClient instance with a valid Kapso API key. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ baseUrl: "https://api.kapso.ai/meta/whatsapp", kapsoApiKey: process.env.KAPSO_API_KEY!, }); // List conversations const conversations = await client.conversations.list({ phoneNumberId: "1234567890", status: "active", lastActiveSince: "2025-01-01T00:00:00Z", limit: 50, }); console.log("Active conversations:", conversations.data.length); // Get specific conversation const conversation = await client.conversations.get({ conversationId: conversations.data[0].id, }); console.log("Conversation:", conversation); // Update conversation status await client.conversations.updateStatus({ conversationId: conversation.id, status: "ended", }); ``` -------------------------------- ### Low-Level Request Helper Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Provides a flexible way to make custom API requests to the WhatsApp Business Platform API with automatic authentication. ```APIDOC ## Low-Level Request Helper ### Description Allows making custom HTTP requests to the WhatsApp Business Platform API. It handles authentication automatically using the provided access token and can manage different response types. ### Method GET, POST, PUT, DELETE, etc. ### Endpoint Any valid WhatsApp Business Platform API endpoint. ### Parameters #### Request Body (for methods like POST, PUT) - **body** (object) - The request payload. #### Query Parameters (for GET requests) - **query** (object) - Key-value pairs for query parameters. ### Request Example (Typed JSON Request) ```javascript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); interface CustomResponse { data: { id: string; name: string }[]; } const response = await client.request("GET", "WABA_ID/phone_numbers", { query: { fields: "id,display_phone_number,verified_name" }, responseType: "json" }); console.log("Phone numbers:", response.data); ``` ### Request Example (Raw Fetch) ```javascript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); const rawResponse = await client.fetch("https://graph.facebook.com/v23.0/some_endpoint", { headers: { Accept: "application/json" }, }); const data = await rawResponse.json(); ``` ### Response #### Success Response - **data** (object) - The parsed response data, typed if a generic type is provided to `request`. #### Response Example ```json { "data": [ { "id": "1234567890", "name": "My WhatsApp Number", "verified_name": "My Verified Business Name" } ] } ``` ``` -------------------------------- ### Deploy WhatsApp Flow Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Deploys a WhatsApp Flow to your account with idempotent handling, meaning it skips re-uploading if the content hasn't changed. Requires the flow JSON definition, WABA ID, flow name, and options for publishing and previewing. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); const flowJson = { version: "7.2", screens: [ { id: "CSAT", title: "Rate Your Experience", terminal: true, layout: { type: "SingleColumnLayout", children: [ { type: "RadioButtonsGroup", name: "rating", label: "How was your experience?", required: true, dataSource: [ { id: "excellent", title: "Excellent" }, { id: "good", title: "Good" }, { id: "poor", title: "Poor" }, ], }, { type: "Footer", label: "Submit", onClickAction: { name: "complete", payload: { rating: "${form.rating}" } }, }, ], }, }, ], }; const result = await client.flows.deploy(flowJson, { wabaId: process.env.WABA_ID!, name: "csat-flow", publish: true, preview: true, }); console.log("Flow ID:", result.flowId); console.log("Preview URL:", result.previewUrl); console.log("Validation Errors:", result.validationErrors); ``` -------------------------------- ### POST /templates/build-typed Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Constructs a template payload with compile-time guidance and automatic camelCase to snake_case conversion. ```APIDOC ## POST /templates/build-typed ### Description Provides a typed builder for template payloads, allowing the use of camelCase parameter names which are automatically converted to snake_case for the API. ### Method POST ### Parameters #### Request Body - **name** (string) - Required - The name of the template. - **language** (string) - Required - The language code. - **body** (array) - Optional - Array of body parameters. - **buttons** (array) - Optional - Array of button definitions. ### Request Example { "name": "order_confirmation", "language": "en_US", "body": [ { "type": "text", "text": "Jessica", "parameterName": "customerName" } ] } ``` -------------------------------- ### Define WhatsApp Template Structure Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Uses buildTemplateDefinition to create template definitions for submission to Meta. Supports various categories including Authentication, Utility, and Marketing, with specific handling for named parameters and catalog buttons. ```typescript import { buildTemplateDefinition } from '@kapso/whatsapp-cloud-api'; const authenticationTemplate = buildTemplateDefinition({ name: 'authentication_code', language: 'en_US', category: 'AUTHENTICATION', messageSendTtlSeconds: 60, components: [ { type: 'BODY', addSecurityRecommendation: true }, { type: 'FOOTER', codeExpirationMinutes: 10 }, { type: 'BUTTONS', buttons: [{ type: 'OTP', otpType: 'COPY_CODE' }] }, ], }); const namedOrderTemplate = buildTemplateDefinition({ name: 'order_confirmation_named', language: 'en_US', category: 'UTILITY', parameterFormat: 'NAMED', components: [ { type: 'BODY', text: 'Thank you, {{customer_name}}! Your order {{order_number}} ships {{ship_date}}.', example: { bodyTextNamedParams: [ { paramName: 'customer_name', example: 'Pablo' }, { paramName: 'order_number', example: '860198-230332' }, { paramName: 'ship_date', example: '2025-11-15' }, ], }, }, ], }); ``` -------------------------------- ### Typed Responses and Error Handling Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/README.md Understand how the SDK provides typed responses for API calls and how to handle errors gracefully. ```APIDOC ## Typed Responses and Error Handling ### Typed Responses All SDK helper methods return typed payloads (e.g., `SendMessageResponse`, `MediaUploadResponse`). You can also specify types for low-level client requests. ```ts // Example of using a custom type for a low-level request interface MyType { someField: string; someNumber: number; } const response = await client.request("GET", "", { responseType: "json" }); // 'response.data' will be of type MyType console.log(response.data.someField); ``` ### Error Handling When an API response is not successful (e.g., status code is not 2xx), the client throws an `Error`. The error message typically includes the HTTP status code and the response text from the API. **Example Error Message:** ``` Meta API request failed with status 400: {"error":{"message":"Invalid parameter","type":"OAuthException","code":190,"error_subcode":1363031,"fbtrace_id":"A1B2C3D4E5F6G7H"}} ``` To handle these errors, use a `try...catch` block around your API calls: ```ts try { await client.messages.sendMessage({ // ... message parameters }); } catch (error) { console.error("API Error:", error.message); // Handle the error appropriately (e.g., retry, log, inform user) } ``` ``` -------------------------------- ### Query Call History via Kapso Proxy Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Demonstrates how to retrieve logs for calls, including filtering by direction, status, and time range. ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ baseUrl: "https://api.kapso.ai/meta/whatsapp", kapsoApiKey: process.env.KAPSO_API_KEY!, }); // List calls const calls = await client.calls.list({ phoneNumberId: "1234567890", direction: "INBOUND", status: "completed", since: "2025-01-01T00:00:00Z", limit: 20, }); console.log("Calls:", calls.data); // Get specific call const call = await client.calls.get({ phoneNumberId: "1234567890", callId: "call_id", }); console.log("Call duration:", call?.duration); ``` -------------------------------- ### Build Template with Raw Components Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Constructs a template payload using Meta-style raw components, allowing for fine-grained control over body parameters. ```typescript import { buildTemplatePayload } from "@kapso/whatsapp-cloud-api"; const template = buildTemplatePayload({ name: "order_confirmation", language: "en_US", components: [ { type: "body", parameters: [ { type: "text", text: "Jessica", parameter_name: "customer_name" }, { type: "text", text: "ORD-12345", parameter_name: "order_id" }, ], }, ], }); await client.messages.sendTemplate({ phoneNumberId: "1234567890", to: "+15551234567", template, }); ``` -------------------------------- ### Flow Lifecycle Management Helpers Source: https://github.com/gokapso/whatsapp-cloud-api-js/blob/master/docs/flows.md Additional SDK methods for managing the lifecycle of flow assets, including creation, updating, publishing, and listing existing flows. ```typescript await client.flows.create({ wabaId, name, flowJson, publish: false }); await client.flows.updateAsset({ flowId, json: flowJson }); await client.flows.publish({ flowId }); await client.flows.list({ wabaId, limit: 20 }); ``` -------------------------------- ### Flow Lifecycle Operations Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Create, update, publish, and manage WhatsApp Flows using the client library. ```APIDOC ## Flow Lifecycle Operations Create, update, publish, and manage WhatsApp Flows. ### Description This section details how to perform lifecycle operations on WhatsApp Flows, including creation, updating assets, publishing, generating preview links, listing existing flows, and deprecating them. ### Methods - `create`: Creates a new WhatsApp Flow. - `updateAsset`: Updates the JSON asset of an existing flow. - `publish`: Publishes a flow, making it available for use. - `preview`: Generates a preview URL for a flow. - `list`: Retrieves a list of flows associated with a WhatsApp Business Account (WABA). - `deprecate`: Deprecates an existing flow. ### Example Usage (TypeScript) ```typescript import { WhatsAppClient } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); // Create a new flow const createResult = await client.flows.create({ wabaId: "WABA_ID", name: "my-flow", flowJson: { version: "7.2", screens: [/* ... */] }, publish: false, }); // Update flow asset await client.flows.updateAsset({ flowId: createResult.id, json: { version: "7.2", screens: [/* updated screens */] }, }); // Publish flow await client.flows.publish({ flowId: createResult.id }); // Get flow preview URL const preview = await client.flows.preview({ flowId: createResult.id, interactive: true, }); console.log("Preview:", preview.preview.previewUrl); // List flows const flows = await client.flows.list({ wabaId: "WABA_ID", limit: 20 }); // Deprecate flow await client.flows.deprecate({ flowId: createResult.id }); ``` ``` -------------------------------- ### Create Message Template Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Defines and creates a new message template on the WhatsApp Business Account, including headers, body text, footers, and buttons. ```typescript import { WhatsAppClient, TemplateDefinition } from "@kapso/whatsapp-cloud-api"; const client = new WhatsAppClient({ accessToken: process.env.WHATSAPP_TOKEN! }); const templateDefinition = TemplateDefinition.buildTemplateDefinition({ name: "seasonal_promo", language: "en_US", category: "MARKETING", parameterFormat: "NAMED", components: [ { type: "HEADER", format: "TEXT", text: "Our {{sale_name}} is on!", example: { headerTextNamedParams: [{ paramName: "sale_name", example: "Summer Sale" }] }, }, { type: "BODY", text: "Shop now through {{end_date}} using code {{discount_code}}", example: { bodyTextNamedParams: [ { paramName: "end_date", example: "Aug 31" }, { paramName: "discount_code", example: "SALE25" }, ], }, }, { type: "FOOTER", text: "Tap below to shop" }, { type: "BUTTONS", buttons: [ { type: "QUICK_REPLY", text: "Unsubscribe" }, { type: "URL", text: "Shop", url: "https://store.example/promo?code={{discount_code}}", example: ["SALE25"] }, ], }, ], }); const response = await client.templates.create({ businessAccountId: "WABA_ID", name: templateDefinition.name, language: templateDefinition.language, category: templateDefinition.category, parameterFormat: templateDefinition.parameterFormat, components: templateDefinition.components, }); console.log("Template ID:", response.id); ``` -------------------------------- ### POST /contacts Source: https://context7.com/gokapso/whatsapp-cloud-api-js/llms.txt Manage contact information, including listing, retrieving, and updating metadata for WhatsApp users. ```APIDOC ## POST /contacts/update ### Description Updates contact metadata, including display name and custom tags for CRM integration. ### Method POST ### Endpoint /contacts/update ### Parameters #### Request Body - **phoneNumberId** (string) - Required - The WhatsApp phone number ID. - **waId** (string) - Required - The WhatsApp ID of the contact. - **displayName** (string) - Optional - The name to display. - **metadata** (object) - Optional - Custom key-value pairs for contact tracking. ### Response #### Success Response (200) - **status** (string) - Update confirmation status. ```