Wabot Documentation
Complete integration guide for the Wabot WhatsApp Web automation library. This guide covers installation, authentication, all API methods, the REST API gateway, security, and deployment.
Installation
Install Wabot via any package manager:
# npm
npm install wabot
# yarn
yarn add wabot
# pnpm
pnpm add wabot
Or download the zip package and install locally:
# After extracting wabot-x.x.x.zip
npm install ./wabot
Wabot requires Node.js 18 or higher and a Chromium browser (installed automatically via Playwright).
Quick Start
import { Wabot } from 'wabot';
const bot = await Wabot.create({
session: 'my-bot',
connectionMode: 'qr',
onReady: () => console.log('Bot is ready!'),
onMessage: (msg) => {
console.log('From:', msg.senderName);
console.log('Message:', msg.body);
},
});
// Send a text message
await bot.sendText('2348012345678@c.us', 'Hello from Wabot!');
QR Code Authentication
QR mode displays a QR code that you scan with your phone. The onQR callback receives a base64 image and ASCII art.
const bot = await Wabot.create({
session: 'qr-bot',
connectionMode: 'qr',
onQR: (qrBase64, asciiQR, attempts) => {
// Display QR in terminal
console.log(asciiQR);
// Or send qrBase64 to a web UI for rendering
},
onReady: () => console.log('Authenticated!'),
});
Phone Pairing Code
Pairing mode generates an 8-character code. Enter it on your phone under Settings > Linked Devices > Link a Device.
const bot = await Wabot.create({
session: 'pairing-bot',
connectionMode: 'pairing',
phoneNumber: '2348012345678', // E.164 format, no +
onPairingCode: (code) => {
console.log('Enter this code on your phone:', code);
},
onReady: () => console.log('Authenticated!'),
});
Session Persistence
Save session data to reconnect without re-authenticating. Sessions are encrypted with AES-256-GCM.
import { Wabot } from 'wabot';
const bot = await Wabot.create({
session: 'persistent-bot',
connectionMode: 'qr',
sessionEncryptionKey: 'your-32-char-secret-key-here!!',
sessionPath: './sessions',
onReady: () => console.log('Ready (session restored!)'),
});
Sending Text Messages
// Simple text
await bot.sendText(chatId, 'Hello!');
// Reply to a message
await bot.sendText(chatId, 'Replying!', { quotedMessageId: msgId });
// With mentions
await bot.sendText(groupId, 'Hey @user!', {
mentionedJids: ['2348012345678@c.us'],
});
// Reply shorthand
await bot.reply(chatId, messageId, 'Replied!');
Sending Media
All media methods accept file paths, URLs, or base64 data URLs.
// Image
await bot.sendImage(chatId, '/path/to/image.jpg', 'Caption');
await bot.sendImage(chatId, 'https://example.com/image.jpg');
await bot.sendImage(chatId, 'data:image/jpeg;base64,...', 'Caption');
// Video
await bot.sendVideo(chatId, '/path/to/video.mp4', 'Video caption');
// Audio (voice note or file)
await bot.sendVoice(chatId, '/path/to/audio.ogg'); // As PTT
await bot.sendAudio(chatId, '/path/to/audio.mp3'); // As file
// Document
await bot.sendFile(chatId, '/path/to/doc.pdf', 'document.pdf', 'Caption');
// Sticker
await bot.sendSticker(chatId, '/path/to/sticker.webp');
Rich Messages
// Location
await bot.sendLocation(chatId, {
latitude: 6.5244,
longitude: 3.3792,
name: 'Lagos, Nigeria',
});
// Contact card
await bot.sendContact(chatId, ['2348012345678@c.us']);
// Interactive buttons (max 3)
await bot.sendButtons(chatId, 'Choose an option:', [
{ id: 'opt1', text: 'Option 1' },
{ id: 'opt2', text: 'Option 2' },
], 'Title', 'Footer');
// List message
await bot.sendList(chatId, {
title: 'Menu',
description: 'Select an item',
buttonText: 'View Options',
sections: [{
title: 'Section 1',
rows: [
{ id: 'item1', title: 'Item 1', description: 'Desc 1' },
],
}],
});
// Link preview
await bot.sendLinkPreview(chatId, 'https://example.com', 'Check this!');
// Poll
await bot.sendPoll(chatId, 'Vote?', ['Yes', 'No']);
// Reaction
await bot.sendReaction(messageId, 'thumbsup');
Broadcast (Bulk Sending)
Wabot respects WhatsApp's natural 5-recipient broadcast limit. The sendBroadcast helper manages batches automatically.
const result = await bot.sendBroadcast(
['2348012345678', '2348012345679', '2348012345680'],
'Hello everyone!',
{
delayBetweenBatches: 5000,
onBatchSent: (batch, remaining) => {
console.log(${remaining} recipients remaining);
},
}
);
console.log(Sent: ${result.sent}, Failed: ${result.failed});
Receiving Messages & Events
bot.on('message', (msg) => {
console.log(msg.id, msg.senderName, msg.body, msg.type);
});
bot.on('message.ack', (ack) => {
console.log(ack.status); // sent | delivered | read
});
bot.on('message.reaction', (r) => {
console.log(r.reaction, r.sender);
});
bot.on('presence', (p) => {
console.log(p.sender, p.isOnline ? 'online' : 'offline');
});
bot.on('participants.changed', (c) => {
console.log(c.groupId, c.action, c.participants);
});
bot.on('call', (call) => {
console.log('Incoming call from', call.caller);
});
Chat Management
// List all chats
const chats = await bot.getAllChats();
// Get messages (paginated)
const messages = await bot.getMessages(chatId, { count: 50 });
// Search messages
const results = await bot.searchMessages('keyword');
// Mark read, archive, pin, mute
await bot.markChatRead(chatId);
await bot.archiveChat(chatId);
await bot.pinChat(chatId);
await bot.muteChat(chatId, { duration: 86400 });
// Download media
const buffer = await bot.downloadMedia(messageId);
Contact Management
const contacts = await bot.getAllContacts();
const contact = await bot.getContact('2348012345678');
const status = await bot.checkNumberStatus('2348012345678');
const picUrl = await bot.getProfilePic(chatId);
Group Management
// Create a group
const group = await bot.createGroup('My Group', ['2348012345678']);
// Get all groups
const groups = await bot.getAllGroups();
// Manage participants
await bot.addParticipant(group.id, ['2348012345679']);
await bot.removeParticipant(group.id, ['2348012345679']);
await bot.promoteParticipant(group.id, ['2348012345678']);
// Group settings
await bot.setGroupName(group.id, 'New Name');
await bot.setGroupDescription(group.id, 'Description');
// Invite links
const link = await bot.getGroupInviteLink(group.id);
await bot.joinGroupViaLink('https://chat.whatsapp.com/...');
Profile Management
await bot.setProfileName('My Bot');
await bot.setProfileStatus('Available');
await bot.setProfilePicture('/path/to/avatar.jpg');
await bot.setPresence('available');
const me = await bot.getMe();
REST API Gateway
The Wabot API gateway is hosted on Cloudflare Pages. It proxies requests to your Wabot host instance.
Authentication
Authorization: Bearer wabot_your_api_key_here
X-Wabot-Host: https://your-bot-host.example.com
Example: Send Text via API
curl -X POST https://wabot.pages.dev/api/v1/send/text \
-H "Authorization: Bearer wabot_your_key" \
-H "X-Wabot-Host: https://your-host.com" \
-H "Content-Type: application/json" \
-d '{"chatId":"2348012345678@c.us","body":"Hello!"}'
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/session/start | Start a new bot session |
| GET | /api/v1/session/status?sessionId=X | Get session status |
| POST | /api/v1/session/qr | Get QR code |
| POST | /api/v1/session/pairing-code | Get pairing code |
| POST | /api/v1/send/text | Send text message |
| POST | /api/v1/send/media | Send media message |
| POST | /api/v1/send/broadcast | Send broadcast |
| GET | /api/v1/chats | List all chats |
| GET | /api/v1/contacts | List all contacts |
| GET | /api/v1/groups | List all groups |
| GET | /api/v1/health | Health check |
Configuration Reference
interface WabotConfig {
// Session
session: string;
connectionMode: 'qr' | 'pairing';
phoneNumber?: string; // For pairing (E.164)
sessionData?: WabotSessionData;
sessionEncryptionKey?: string;
sessionPath?: string;
// Browser
headless?: boolean; // Default: true
browserPath?: string;
viewport?: { width: number; height: number };
userAgent?: string;
browserArgs?: string[];
devtools?: boolean;
slowMo?: number;
// Rate limiting
rateLimit?: {
messagesPerMinute?: number; // Default: 20
broadcastBatchesPerMinute?: number; // Default: 5
sendDelay?: number; // Default: 1000ms
jitter?: boolean; // Default: true
};
// QR settings
qrRefreshInterval?: number; // Default: 20000ms
maxQrAttempts?: number; // Default: 10
// Event callbacks
onQR?: QRCallback;
onPairingCode?: PairingCodeCallback;
onReady?: () => void;
onMessage?: (msg: WabotMessage) => void;
onMessageAck?: (ack: WabotAck) => void;
onReaction?: (r: WabotReactionEvent) => void;
onPresence?: (p: WabotPresenceEvent) => void;
onParticipantsChanged?: (c: WabotParticipantChange) => void;
onCall?: (call: WabotCall) => void;
onDisconnected?: (reason: string) => void;
}
Security
- Input Validation: Every public API method validates inputs (chat IDs, phone numbers, URLs, file paths, message bodies). Path traversal is blocked.
- Session Encryption: Session data encrypted with AES-256-GCM using scrypt-derived keys. The encryption key never leaves your application.
- Rate Limiting: Token bucket algorithm prevents API abuse. Configurable per-method limits with jitter for anti-detection.
- Anti-Detection: Browser stealth measures (webdriver property removal, plugin mocking, WebGL spoofing, user agent override).
- Circuit Breaker: Automatic failure detection. After 5 consecutive failures, the circuit opens and blocks calls for 60 seconds.
- CORS Protection: The REST API gateway enforces CORS policies and rate limits per API key.
- WhatsApp Limits: The library respects WhatsApp's natural limits (5-recipient broadcast, rate limits on sending).
Deployment
Running the Wabot Host
The Wabot library runs on a Node.js host (VPS, Docker, or local machine). It cannot run on Cloudflare Pages directly because WhatsApp Web automation requires a persistent browser process.
// host.js - Run this on your server
import { Wabot } from 'wabot';
import express from 'express';
const app = express();
app.use(express.json());
const bot = await Wabot.create({
session: 'api-bot',
connectionMode: 'pairing',
phoneNumber: process.env.PHONE_NUMBER,
});
app.post('/api/send/text', async (req, res) => {
const result = await bot.sendText(req.body.chatId, req.body.body);
res.json(result);
});
app.listen(3000);
Deploying the API Gateway to Cloudflare Pages
The site/ directory contains the Cloudflare Pages deployment. Deploy it with Wrangler:
cd site
npx wrangler pages deploy . --project-name wabot