
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
waba-toolkit
Advanced tools
Type-safe WhatsApp Business API toolkit with CLI for webhooks, media downloads, signature verification, and message sending
Type-safe WhatsApp Business API toolkit with CLI for Node.js 20+
TL;DR: Process webhooks, download media, send messages. Zero library dependencies. Fully typed. Works as library or CLI.
Zero library dependencies (CLI uses commander + inquirer). ESM + CommonJS. Full TypeScript support.
npm install waba-toolkit
# Or globally for CLI
npm install -g waba-toolkit
import { WABAClient, classifyWebhook, classifyMessage } from 'waba-toolkit';
const client = new WABAClient({
accessToken: process.env.META_ACCESS_TOKEN,
appSecret: process.env.META_APP_SECRET,
});
app.post('/webhook', async (req, res) => {
// 1. Verify signature
if (!client.verifyWebhook(req.headers['x-hub-signature-256'], req.rawBody)) {
return res.status(401).send('Invalid signature');
}
// 2. Classify webhook
const webhook = classifyWebhook(req.body);
if (webhook.type === 'message') {
const message = webhook.payload.messages?.[0];
const classified = classifyMessage(message);
if (classified.type === 'text') {
console.log('Text:', classified.message.text.body);
}
// 3. Download media if present
if (classified.type === 'image') {
const { stream, mimeType } = await client.getMedia(
classified.message.image.id
);
// Process stream...
}
}
res.sendStatus(200);
});
→ Learn more: Webhook Processing Guide | Media Downloads
import { WABAApiClient } from 'waba-toolkit';
const apiClient = new WABAApiClient({
accessToken: process.env.META_ACCESS_TOKEN,
phoneNumberId: '1234567890',
});
const response = await apiClient.sendTextMessage(
'1234567890',
'Hello from waba-toolkit!'
);
console.log('Sent:', response.messages[0].id);
→ Learn more: Sending Messages Guide
# Configure once
waba-toolkit configure
# Send a text message
waba-toolkit send text --to 1234567890 --message "Hello World"
# Register a phone number
waba-toolkit register --pin 123456
# List phone numbers
waba-toolkit list-phones --waba-id YOUR_WABA_ID
# List all flows
waba-toolkit list-flows --waba-id YOUR_WABA_ID
# Create a WhatsApp Flow
waba-toolkit create flow --name "My Flow" --categories LEAD_GENERATION
# Upload Flow JSON
waba-toolkit update flow --flow-id 123456789 --file ./my-flow.json
# Publish flow (irreversible)
waba-toolkit publish flow --flow-id 123456789
# List message templates
waba-toolkit list-templates --waba-id YOUR_WABA_ID
# Create a message template
waba-toolkit create template --name my_template --file ./template.json
# Delete a template
waba-toolkit delete template --name old_template
→ Learn more: CLI Guide
| Feature | Library | CLI |
|---|---|---|
| Verify webhook signatures | ✅ | - |
| Classify webhooks (message/status/call) | ✅ | - |
| Classify 15 message types | ✅ | - |
| Download media (stream/buffer) | ✅ | - |
| Send text messages | ✅ | ✅ |
| Send template messages | ✅ | ✅ |
| Send custom message payloads | ✅ | ✅ |
| Register/deregister phones | ✅ | ✅ |
| List phone numbers | ✅ | ✅ |
| List WhatsApp Flows | ✅ | ✅ |
| Create WhatsApp Flows | ✅ | ✅ |
| Update Flow JSON | ✅ | ✅ |
| Publish Flows | ✅ | ✅ |
| List message templates | ✅ | ✅ |
| Create message templates | ✅ | ✅ |
| Delete message templates | ✅ | ✅ |
| Encrypted config storage | - | ✅ |
| Topic | Guide |
|---|---|
| CLI Commands | docs/CLI.md |
| Webhook Processing | docs/WEBHOOKS.md |
| Sending Messages | docs/SENDING.md |
| Media Downloads | docs/MEDIA.md |
| Complete API Reference | API_REFERENCE.md |
| Architecture & Design | ARCHITECTURE.md |
| Troubleshooting | docs/TROUBLESHOOTING.md |
Type-safe webhook and message classification:
const webhook = classifyWebhook(payload);
switch (webhook.type) {
case 'message':
// webhook.payload is typed as MessageWebhookValue
break;
case 'status':
// webhook.payload is typed as StatusWebhookValue
break;
case 'call':
// webhook.payload is typed as CallWebhookValue
break;
}
Two-step flow with automatic URL refresh:
// Stream (default)
const { stream, mimeType, sha256, fileSize } = await client.getMedia(mediaId);
// Buffer
const { buffer, mimeType } = await client.getMedia(mediaId, { asBuffer: true });
Temporary URLs expire in 5 minutes. getMedia() fetches fresh URLs each time.
→ Learn more: Media Downloads Guide
Extract common data from webhooks:
import { getContactInfo, getMessageId, extractMediaId } from 'waba-toolkit';
// Get sender info
const contact = getContactInfo(webhookPayload);
console.log(contact?.waId, contact?.profileName);
// Get message ID for marking as read
const messageId = getMessageId(webhookPayload);
// Extract media ID from any media message
const mediaId = extractMediaId(message);
→ Learn more: Webhook Processing Guide
Typed error classes:
try {
const media = await client.getMedia(mediaId);
} catch (error) {
if (error instanceof WABAMediaError) {
console.error(`Media error for ${error.mediaId}: ${error.code}`);
} else if (error instanceof WABANetworkError) {
console.error('Network error:', error.cause);
}
}
Error Types:
WABAError - Base errorWABAMediaError - Media download failuresWABANetworkError - Network/connection issuesWABASignatureError - Invalid webhook signatureWABAConfigError - Configuration problemsWABAAuthError - Authentication failuresWABASendError - Message sending failures→ Learn more: Troubleshooting Guide
fetch)whatsapp_business_messaging permissionOption 1: Interactive setup
waba-toolkit configure
Option 2: Environment variables
export WABA_TOOLKIT_ACCESS_TOKEN="your-token"
export WABA_TOOLKIT_PHONE_NUMBER_ID="your-phone-id"
waba-toolkit send text --to 123 --message "Hello"
Priority: CLI flags > env vars > config file > defaults
Config is stored at ~/.waba-toolkit (encrypted, machine-locked).
→ Learn more: CLI Configuration
Supports all 15 WABA message types:
text | image | video | audio | document | sticker | location | contacts | interactive | reaction | button | order | system | referral | unsupported
Each type is a discriminated union with proper TypeScript narrowing.
const isValid = client.verifyWebhook(signature, rawBody);
if (!isValid) return res.status(401).send('Invalid signature');
const webhook = classifyWebhook(req.body);
if (webhook.type === 'message') {
// Handle message
}
if (isMediaMessage(message)) {
const mediaId = extractMediaId(message);
const { stream } = await client.getMedia(mediaId);
const file = fs.createWriteStream('./download.jpg');
Readable.fromWeb(stream).pipe(file);
}
await apiClient.sendTemplateMessage('1234567890', {
name: 'hello_world',
language: { code: 'en_US' },
components: [
{
type: 'body',
parameters: [{ type: 'text', text: 'John' }]
}
]
});
# template.json
{
"name": "order_confirmation",
"language": { "code": "en_US" },
"components": [...]
}
waba-toolkit send template --to 1234567890 --file template.json
# Create flow
waba-toolkit create flow --name "Lead Form" --categories LEAD_GENERATION
# Upload Flow JSON (returns validation errors if invalid)
waba-toolkit update flow --flow-id 123456789 --file ./lead-form.json
# Publish flow (irreversible - makes flow available for use)
waba-toolkit publish flow --flow-id 123456789
All types exported:
import type {
// Clients
WABAClientOptions,
WABAApiClientOptions,
// Webhooks
WebhookPayload,
WebhookClassification,
MessageWebhookValue,
StatusWebhookValue,
// Messages
IncomingMessage,
MessageClassification,
TextMessage,
ImageMessage,
MediaMessage,
// API
SendMessageResponse,
TemplateComponent,
PhoneNumber,
// Flows
FlowCategory,
FlowStatus,
FlowListItem,
ListFlowsResponse,
CreateFlowResponse,
UpdateFlowJsonResponse,
FlowValidationError,
PublishFlowResponse,
// Templates
TemplateCategory,
TemplateStatus,
TemplateListItem,
ListTemplatesResponse,
CreateTemplateRequest,
CreateTemplateResponse,
DeleteTemplateResponse,
} from 'waba-toolkit';
See API_REFERENCE.md for complete type documentation.
MIT
FAQs
Type-safe WhatsApp Business API toolkit with CLI for webhooks, media downloads, signature verification, and message sending
The npm package waba-toolkit receives a total of 11 weekly downloads. As such, waba-toolkit popularity was classified as not popular.
We found that waba-toolkit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.