Node.js Examples
Complete examples for integrating the WhatsApp API with Node.js.
Installation
npm install axios
Helper Class
// whatsapp-api.js
const axios = require('axios');
class WhatsAppAPI {
constructor(baseUrl, apiKey, sessionId) {
this.baseUrl = baseUrl.replace(/\/$/, '');
this.apiKey = apiKey;
this.sessionId = sessionId;
this.client = axios.create({
baseURL: this.baseUrl,
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json'
}
});
}
async request(method, endpoint, data = null) {
try {
const response = await this.client({
method,
url: endpoint,
data
});
return response.data;
} catch (error) {
throw new Error(error.response?.data?.error || error.message);
}
}
// Session Management
async getStatus() {
return this.request('GET', `/sessions/${this.sessionId}/status`);
}
async getQR() {
return this.request('GET', `/sessions/${this.sessionId}/qr`);
}
// Messaging
async sendText(to, text, quotedMessageId = null) {
const data = { to, text };
if (quotedMessageId) data.quotedMessageId = quotedMessageId;
return this.request('POST', `/sessions/${this.sessionId}/send`, data);
}
async sendImage(to, image, caption = null, filename = null) {
const data = { to, image };
if (caption) data.caption = caption;
if (filename) data.filename = filename;
return this.request('POST', `/sessions/${this.sessionId}/send/image`, data);
}
async sendDocument(to, document, filename, caption = null) {
const data = { to, document, filename };
if (caption) data.caption = caption;
return this.request('POST', `/sessions/${this.sessionId}/send/document`, data);
}
async sendVideo(to, video, caption = null) {
const data = { to, video };
if (caption) data.caption = caption;
return this.request('POST', `/sessions/${this.sessionId}/send/video`, data);
}
async sendLocation(to, latitude, longitude, description = null) {
const data = { to, latitude, longitude };
if (description) data.description = description;
return this.request('POST', `/sessions/${this.sessionId}/send/location`, data);
}
// Utilities
async checkNumber(phone) {
return this.request('GET', `/sessions/${this.sessionId}/check-number/${phone}`);
}
async getContacts() {
return this.request('GET', `/sessions/${this.sessionId}/contacts`);
}
async getChats() {
return this.request('GET', `/sessions/${this.sessionId}/chats`);
}
// Groups
async createGroup(name, participants) {
return this.request('POST', `/sessions/${this.sessionId}/groups/create`, {
name,
participants
});
}
async getGroupInfo(groupId) {
return this.request('GET', `/sessions/${this.sessionId}/groups/${groupId}`);
}
async addParticipants(groupId, participants) {
return this.request('POST', `/sessions/${this.sessionId}/groups/${groupId}/participants/add`, {
participants
});
}
}
module.exports = WhatsAppAPI;
Basic Usage
Send Text Message
const WhatsAppAPI = require('./whatsapp-api');
const whatsapp = new WhatsAppAPI(
'http://localhost:3000',
'wask_your_api_key_here',
'your-session-id'
);
async function sendMessage() {
try {
const result = await whatsapp.sendText('919876543210', 'Hello from Node.js! 🚀');
console.log('Message sent successfully!');
console.log('Message ID:', result.messageId);
} catch (error) {
console.error('Error:', error.message);
}
}
sendMessage();
Send Image
async function sendImage() {
try {
const result = await whatsapp.sendImage(
'919876543210',
'https://example.com/image.jpg',
'Check out this image!',
'photo.jpg'
);
console.log('Image sent successfully!');
} catch (error) {
console.error('Error:', error.message);
}
}
sendImage();
Send Document
async function sendDocument() {
try {
const result = await whatsapp.sendDocument(
'919876543210',
'https://example.com/report.pdf',
'Monthly Report.pdf',
'Here is your monthly report'
);
console.log('Document sent successfully!');
} catch (error) {
console.error('Error:', error.message);
}
}
sendDocument();
Advanced Examples
Bulk Message Sender
class BulkMessageSender {
constructor(whatsapp, delayMs = 2000) {
this.whatsapp = whatsapp;
this.delayMs = delayMs;
}
async sendToMultiple(recipients, message) {
const results = [];
for (const recipient of recipients) {
try {
const result = await this.whatsapp.sendText(recipient, message);
results.push({
recipient,
success: true,
messageId: result.messageId
});
console.log(`✓ Sent to ${recipient}`);
} catch (error) {
results.push({
recipient,
success: false,
error: error.message
});
console.error(`✗ Failed to send to ${recipient}: ${error.message}`);
}
// Delay between messages
if (recipient !== recipients[recipients.length - 1]) {
await this.delay(this.delayMs);
}
}
return results;
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Usage
const bulkSender = new BulkMessageSender(whatsapp, 2000);
const recipients = [
'919876543210',
'919876543211',
'919876543212'
];
const message = 'Hello! This is a bulk message.';
bulkSender.sendToMultiple(recipients, message).then(results => {
const successful = results.filter(r => r.success).length;
const failed = results.length - successful;
console.log('\nSummary:');
console.log(`Successful: ${successful}`);
console.log(`Failed: ${failed}`);
});
Auto-Reply Bot with Express
const express = require('express');
const WhatsAppAPI = require('./whatsapp-api');
const app = express();
app.use(express.json());
const whatsapp = new WhatsAppAPI(
process.env.API_BASE_URL,
process.env.API_KEY,
process.env.SESSION_ID
);
app.post('/webhook', async (req, res) => {
const { event, message } = req.body;
// Respond immediately
res.json({ success: true });
if (event !== 'message' || message.fromMe) {
return;
}
const from = message.from;
const body = message.body.toLowerCase().trim();
// Auto-reply logic
let reply = null;
if (body.includes('hello') || body.includes('hi')) {
reply = 'Hello! How can I help you today?';
} else if (body.includes('help')) {
reply = 'Available commands:\n- hello - Greeting\n- help - Show this message\n- status - Check status';
} else if (body.includes('status')) {
reply = 'System is operational! ✅';
}
// Send reply
if (reply) {
try {
await whatsapp.sendText(from, reply);
console.log(`Auto-reply sent to ${from}`);
} catch (error) {
console.error('Failed to send auto-reply:', error.message);
}
}
});
app.listen(3001, () => {
console.log('Webhook server listening on port 3001');
});
Message Queue with Redis
const Redis = require('ioredis');
const WhatsAppAPI = require('./whatsapp-api');
class MessageQueue {
constructor(whatsapp, redisUrl = 'redis://localhost:6379') {
this.whatsapp = whatsapp;
this.redis = new Redis(redisUrl);
this.queueKey = 'whatsapp:message_queue';
}
async add(to, message, type = 'text', media = null) {
const item = {
id: Date.now() + '_' + Math.random().toString(36).substr(2, 9),
to,
message,
type,
media,
status: 'pending',
createdAt: new Date().toISOString(),
attempts: 0
};
await this.redis.rpush(this.queueKey, JSON.stringify(item));
console.log(`Added message ${item.id} to queue`);
}
async process(maxAttempts = 3) {
let processed = 0;
while (true) {
const item = await this.redis.lpop(this.queueKey);
if (!item) break;
const message = JSON.parse(item);
try {
let result;
if (message.type === 'text') {
result = await this.whatsapp.sendText(message.to, message.message);
} else if (message.type === 'image') {
result = await this.whatsapp.sendImage(message.to, message.media, message.message);
}
console.log(`✓ Sent message ${message.id} to ${message.to}`);
processed++;
// Store in processed list
await this.redis.rpush('whatsapp:processed', JSON.stringify({
...message,
status: 'sent',
messageId: result.messageId,
sentAt: new Date().toISOString()
}));
} catch (error) {
message.attempts++;
if (message.attempts >= maxAttempts) {
console.error(`✗ Failed message ${message.id}: ${error.message}`);
// Store in failed list
await this.redis.rpush('whatsapp:failed', JSON.stringify({
...message,
status: 'failed',
error: error.message
}));
} else {
console.log(`⚠ Retry ${message.attempts}/${maxAttempts} for message ${message.id}`);
// Re-add to queue
await this.redis.rpush(this.queueKey, JSON.stringify(message));
}
}
// Delay between messages
await new Promise(resolve => setTimeout(resolve, 2000));
}
return processed;
}
async getStats() {
const pending = await this.redis.llen(this.queueKey);
const processed = await this.redis.llen('whatsapp:processed');
const failed = await this.redis.llen('whatsapp:failed');
return { pending, processed, failed };
}
}
// Usage
const whatsapp = new WhatsAppAPI(
process.env.API_BASE_URL,
process.env.API_KEY,
process.env.SESSION_ID
);
const queue = new MessageQueue(whatsapp);
// Add messages to queue
async function addMessages() {
await queue.add('919876543210', 'Message 1');
await queue.add('919876543211', 'Message 2');
await queue.add('919876543212', 'Message 3');
}
// Process queue
async function processQueue() {
const processed = await queue.process();
console.log(`\nProcessed ${processed} messages`);
const stats = await queue.getStats();
console.log('Stats:', stats);
}
addMessages().then(processQueue);
Check Number Before Sending
async function sendSafe(whatsapp, phone, message) {
try {
// Check if number exists
const check = await whatsapp.checkNumber(phone);
if (!check.exists) {
console.log(`Number ${phone} is not on WhatsApp`);
return false;
}
// Send message
await whatsapp.sendText(phone, message);
console.log(`Message sent to ${phone}`);
return true;
} catch (error) {
console.error('Error:', error.message);
return false;
}
}
// Usage
sendSafe(whatsapp, '919876543210', 'Hello!');
Database Integration
Store Messages in MongoDB
const mongoose = require('mongoose');
// Message Schema
const messageSchema = new mongoose.Schema({
messageId: { type: String, unique: true, required: true },
direction: { type: String, enum: ['incoming', 'outgoing'], required: true },
sender: String,
recipient: String,
body: String,
type: { type: String, default: 'text' },
status: { type: String, default: 'sent' },
createdAt: { type: Date, default: Date.now },
updatedAt: Date
});
const Message = mongoose.model('Message', messageSchema);
// Database class
class MessageDatabase {
constructor(mongoUrl) {
mongoose.connect(mongoUrl);
}
async saveOutgoingMessage(to, message, messageId, type = 'text') {
const msg = new Message({
messageId,
direction: 'outgoing',
recipient: to,
body: message,
type,
status: 'sent'
});
await msg.save();
}
async saveIncomingMessage(messageId, from, body, type) {
await Message.findOneAndUpdate(
{ messageId },
{
messageId,
direction: 'incoming',
sender: from,
body,
type
},
{ upsert: true, new: true }
);
}
async updateMessageStatus(messageId, status) {
await Message.findOneAndUpdate(
{ messageId },
{ status, updatedAt: new Date() }
);
}
async getMessageHistory(contact, limit = 50) {
return Message.find({
$or: [
{ sender: contact },
{ recipient: contact }
]
})
.sort({ createdAt: -1 })
.limit(limit);
}
}
// Webhook with database
const db = new MessageDatabase('mongodb://localhost:27017/whatsapp');
app.post('/webhook', async (req, res) => {
const { event, message, statusUpdate } = req.body;
res.json({ success: true });
if (event === 'message') {
await db.saveIncomingMessage(
message.id,
message.from,
message.body,
message.type
);
}
if (event === 'message_status') {
await db.updateMessageStatus(
statusUpdate.messageId,
statusUpdate.status
);
}
});
Error Handling with Retry
async function sendWithRetry(whatsapp, to, message, maxRetries = 3) {
let attempt = 0;
while (attempt < maxRetries) {
try {
return await whatsapp.sendText(to, message);
} catch (error) {
attempt++;
if (attempt >= maxRetries) {
throw new Error(`Failed after ${maxRetries} attempts: ${error.message}`);
}
// Exponential backoff
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
// Usage
sendWithRetry(whatsapp, '919876543210', 'Hello!')
.then(result => console.log('Sent:', result.messageId))
.catch(error => console.error('Failed:', error.message));
TypeScript Support
// whatsapp-api.ts
import axios, { AxiosInstance } from 'axios';
interface SendTextResponse {
success: boolean;
messageId: string;
to: string;
type: string;
status: string;
timestamp: string;
}
class WhatsAppAPI {
private client: AxiosInstance;
constructor(
private baseUrl: string,
private apiKey: string,
private sessionId: string
) {
this.client = axios.create({
baseURL: this.baseUrl,
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json'
}
});
}
async sendText(to: string, text: string): Promise<SendTextResponse> {
const response = await this.client.post(
`/sessions/${this.sessionId}/send`,
{ to, text }
);
return response.data;
}
}
export default WhatsAppAPI;