Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
WhatsappAPI
✓ import { WhatsappAPI } from 'whatsapp-api-js';
✗ const WhatsappAPI = require('whatsapp-api-js').WhatsappAPI;
This library is primarily designed for ES Modules (ESM). While CommonJS might work with specific transpilation, direct `require` of named exports can be problematic in modern Node.js environments.
Webhook
✓ import { Webhook } from 'whatsapp-api-js';
✗ import Webhook from 'whatsapp-api-js';
The `Webhook` interface represents the structure of incoming WhatsApp webhook payloads, providing strong typing for event handling.
verifyRequestSignature
✓ import { verifyRequestSignature } from 'whatsapp-api-js';
✗ import verifyRequestSignature from 'whatsapp-api-js';
This utility function is crucial for securing webhook endpoints by verifying the `X-Hub-Signature` header using your `APP_SECRET`.
This quickstart demonstrates how to initialize the WhatsappAPI client, send a basic text message, and set up a simple Node.js HTTP server to handle and verify incoming WhatsApp webhooks, replying to text messages.
import { WhatsappAPI } from 'whatsapp-api-js';
import http from 'http';
import { createHmac } from 'crypto';
// Environment variables (replace with your actual values)
const PHONE_NUMBER_ID = process.env.WHATSAPP_PHONE_NUMBER_ID ?? '';
const ACCESS_TOKEN = process.env.WHATSAPP_ACCESS_TOKEN ?? '';
const VERIFY_TOKEN = process.env.WHATSAPP_VERIFY_TOKEN ?? 'my-webhook-secret';
const APP_SECRET = process.env.WHATSAPP_APP_SECRET ?? ''; // For signature verification
if (!PHONE_NUMBER_ID || !ACCESS_TOKEN || !VERIFY_TOKEN || !APP_SECRET) {
console.error('Missing required environment variables. Please set WHATSAPP_PHONE_NUMBER_ID, WHATSAPP_ACCESS_TOKEN, WHATSAPP_VERIFY_TOKEN, and WHATSAPP_APP_SECRET.');
process.exit(1);
}
const whatsapp = new WhatsappAPI(PHONE_NUMBER_ID, ACCESS_TOKEN);
async function sendWelcomeMessage(to: string) {
try {
const message = await whatsapp.sendMessage({
to,
type: 'text',
text: { body: 'Hello from whatsapp-api-js! How can I help you today?' },
});
console.log('Message sent successfully:', message);
} catch (error) {
console.error('Error sending message:', error);
}
}
const server = http.createServer(async (req, res) => {
if (req.method === 'GET' && req.url?.startsWith('/webhook')) {
const query = new URLSearchParams(req.url.split('?')[1]);
const mode = query.get('hub.mode');
const token = query.get('hub.verify_token');
const challenge = query.get('hub.challenge');
if (mode === 'subscribe' && token === VERIFY_TOKEN) {
console.log('Webhook verified!');
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(challenge);
} else {
res.writeHead(403);
res.end('Forbidden');
}
} else if (req.method === 'POST' && req.url === '/webhook') {
let body = '';
req.on('data', chunk => { body += chunk.toString(); });
req.on('end', async () => {
const signature = req.headers['x-hub-signature'] as string;
const [algorithm, hash] = signature?.split('=') ?? [];
if (!signature || !algorithm || !hash || algorithm !== 'sha1') {
console.error('Missing or invalid X-Hub-Signature header');
res.writeHead(400); res.end('Missing X-Hub-Signature header'); return;
}
const expectedHash = createHmac('sha1', APP_SECRET)
.update(body)
.digest('hex');
if (hash !== expectedHash) {
console.error('Webhook signature verification failed!');
res.writeHead(403); res.end('Signature verification failed'); return;
}
console.log('Webhook signature verified successfully.');
try {
const webhookPayload = JSON.parse(body);
console.log('Received webhook event:', JSON.stringify(webhookPayload, null, 2));
if (webhookPayload.object === 'whatsapp_business_account' && webhookPayload.entry) {
for (const entry of webhookPayload.entry) {
for (const change of entry.changes) {
if (change.field === 'messages') {
const messages = change.value.messages;
for (const message of messages || []) {
if (message.type === 'text') {
console.log(`Received text message from ${message.from}: ${message.text?.body}`);
await whatsapp.sendMessage({
to: message.from,
type: 'text',
text: { body: `You said: "${message.text?.body}".` },
});
}
}
}
}
}
}
res.writeHead(200); res.end('Event received');
} catch (e) {
console.error('Error processing webhook:', e);
res.writeHead(500); res.end('Error processing event');
}
});
} else {
res.writeHead(404); res.end('Not Found');
}
});
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
console.log('Webhook endpoint: http://localhost:3000/webhook');
console.log('Make sure to set your WhatsApp Business Account API variables.');
// To send a test message, uncomment the line below and replace with a recipient phone number.
// sendWelcomeMessage('YOUR_TEST_PHONE_NUMBER');
});
Errors
Common errors & fixes
TypeError: WhatsappAPI is not a constructor
Attempting to instantiate `WhatsappAPI` using CommonJS `require` syntax when the library is published as ES Modules, or incorrect named import.
fixEnsure you are using ES Modules syntax: `import { WhatsappAPI } from 'whatsapp-api-js';`. If your project is CommonJS, consider adding `"type": "module"` to your `package.json` or configure your build system to transpile. Error: Request failed with status code 401 (Unauthorized)
Invalid or expired WhatsApp Cloud API access token, or incorrect phone number ID provided during client initialization or API calls.
fixVerify your `WHATSAPP_ACCESS_TOKEN` and `WHATSAPP_PHONE_NUMBER_ID` environment variables. Ensure the access token has the necessary permissions (e.g., `whatsapp_business_messaging`) and has not expired. Regenerate the token if needed from your Meta for Developers dashboard.
Webhook signature verification failed!
The `X-Hub-Signature` header from WhatsApp does not match the signature generated using your `APP_SECRET` and the raw request body. This indicates an incorrect `APP_SECRET`, an altered payload, or a mismatch in signature calculation.
fixDouble-check your `WHATSAPP_APP_SECRET` environment variable against the one in your Meta for Developers app settings. Ensure your webhook handler is correctly reading the *raw* request body *before* parsing it (e.g., `JSON.parse`) and using it to calculate the HMAC-SHA1 signature.
Error: (#100) The parameter 'message' is required.
Attempting to send a message with an invalid, incomplete, or missing `message` object structure according to the WhatsApp Cloud API specifications.
fixReview the `sendMessage` payload structure. Ensure `to`, `type`, and the specific message content (e.g., `text: { body: '...' }` for text messages, `image: { id: '...' }` for images) are correctly provided as per the `whatsapp-api-js` documentation and the official WhatsApp Cloud API reference. Audit
Dependencies
No dependency data recorded yet.