easy-connect-official-wpp-rc
v1.0.13
Published
Official WhatsApp Cloud API client for Node.js with Redis webhook distribution. Build scalable WhatsApp integrations with event listeners and distributed message handling.
Maintainers
Readme
easy-connect-official-wpp-rc
Official WhatsApp Cloud API client for Node.js with Redis webhook distribution. Build scalable, event-driven WhatsApp integrations with automatic Redis connection management.
Features
✨ Official WhatsApp Cloud API v25.0 — Latest WhatsApp Graph API
🚀 Automatic Initialization — Redis connects automatically on first listener
🎧 Event-Driven Architecture — Familiar callback pattern for all events
📦 Distributed Ready — Built-in Redis pub/sub for multiple client instances
📨 Full Message Support — Text, images, videos, audio, documents, location, contacts, reactions, templates
✅ Type-Safe — Full TypeScript support with comprehensive type definitions
🔄 Scalable — Handle webhooks across multiple servers with Redis
Installation
npm install easy-connect-official-wpp-rcPrerequisites
- Node.js 18+
- Redis (optional, but required for webhook distribution)
- WhatsApp Business Account with Cloud API access
- Phone Number ID and Access Token from Meta
Quick Start
import { WhatsAppOfficialClient } from 'easy-connect-official-wpp-rc';
// 1. Create client with Redis config (automatic connection)
const client = new WhatsAppOfficialClient('your_phone_number_id', 'your_access_token', {
host: 'localhost',
port: 6379,
db: 0,
});
// 2. Register listeners (✨ Redis connects automatically!)
client.onMessage((message) => {
console.log(`Message from ${message.from}: ${message.message}`);
});
client.onMessageAck((ack) => {
console.log(`Message ${ack.messageId} status: ${ack.status}`);
});
// 3. Handle errors and connection status
client.onError((error) => {
console.error('Error:', error);
});
client.onConnectionStatus((status) => {
console.log(`Connection status: ${status}`);
});API Reference
Constructor
new WhatsAppOfficialClient(
phoneNumberId: string,
accessToken: string,
redisConfig?: RedisConfig
)Parameters:
phoneNumberId— Your WhatsApp Business Phone Number IDaccessToken— Meta Access Token with WhatsApp permissionsredisConfig(optional) — Redis connection configuration
RedisConfig:
interface RedisConfig {
host?: string; // Default: 'localhost'
port?: number; // Default: 6379
db?: number; // Default: 0
password?: string; // Optional
}Sending Messages
sendText(identifier: string, message: string): Promise<Response>
Send a text message.
const response = await client.sendText('5511999999999', 'Hello!');
console.log('Message sent:', response.content);sendTextReply(identifier: string, message: string, options?: any): Promise<Response>
Send a reply to a specific message.
await client.sendTextReply(message.from, 'Thanks!', { content: { id: message.id } });sendImage(identifier: string, content: string, option?: ImageOption): Promise<Response>
Send an image with optional caption (auto-uploads from URL).
await client.sendImage('5511999999999', 'https://example.com/image.jpg', {
caption: 'Check this out!',
});sendVideo(identifier: string, content: string, option?: VideoOption): Promise<Response>
Send a video with optional caption (auto-uploads from URL).
await client.sendVideo('5511999999999', 'https://example.com/video.mp4', {
caption: 'My video',
});sendAudio(identifier: string, content: string, option?: AudioOption): Promise<Response>
Send an audio file (auto-uploads from URL).
await client.sendAudio('5511999999999', 'https://example.com/audio.mp3');sendVoice(identifier: string, content: string, option?: AudioOption): Promise<Response>
Send a voice message (same as sendAudio).
await client.sendVoice('5511999999999', 'https://example.com/voice.ogg');sendDocument(identifier: string, content: string, option?: FileOption): Promise<Response>
Send a document with optional filename (auto-uploads from URL).
await client.sendDocument('5511999999999', 'https://example.com/document.pdf', {
filename: 'Report.pdf',
});sendLocation(identifier: string, latitude: number, longitude: number): Promise<Response>
Send a location.
await client.sendLocation('5511999999999', -23.5505, -46.6333);sendContact(identifier: string, contactName: string, contactPhone: string, contactPhotoUrl?: string): Promise<Response>
Send a contact card.
await client.sendContact('5511999999999', 'John Doe', '5511988888888');sendReaction(identifier: string, reaction: string, messageId: string): Promise<Response>
Send a reaction emoji to a message.
await client.sendReaction('5511999999999', '👍', 'message_id');sendTemplate(identifier: string, templateName: string, language?: string, parameters?: any[]): Promise<Response>
Send a pre-approved template message.
await client.sendTemplate('5511999999999', 'hello_world', 'en_US');markReadAll(identifier: string): Promise<Response>
Mark a message as read.
await client.markReadAll('message_id');setPresence(identifier: string, type?: string): Promise<Response>
Set presence status (typing indicator).
await client.setPresence('5511999999999', 'typing');Event Listeners
onMessage(callback: (message: EventResponse) => void): void
Listen for incoming messages.
client.onMessage((message) => {
console.log('Type:', message.type);
if (message.type === 'text') {
console.log('Text:', message.message);
} else if (message.type === 'image') {
console.log('Image ID:', message.media?.id);
} else if (message.type === 'location') {
console.log('Location:', message.location);
}
});onMessageAck(callback: (ack: MessageStatusEvent) => void): void
Listen for message acknowledgments.
client.onMessageAck((ack) => {
console.log(`Message ${ack.messageId}: ${ack.status}`);
});onMessageStatus(callback: (status: any) => void): void
Listen for status updates.
client.onMessageStatus((status) => {
console.log('Status update:', status);
});onConnectionStatus(callback: (status: string) => void): void
Listen for connection changes.
client.onConnectionStatus((status) => {
if (status === 'connected') {
console.log('Connected to WhatsApp!');
}
});onError(callback: (error: any) => void): void
Listen for errors.
client.onError((error) => {
console.error('Error:', error);
});Media Management
downloadMedia(mediaId: string): Promise<Response>
Download media from WhatsApp (returns buffer).
const response = await client.downloadMedia(message.media.id);
const buffer = response.content; // Image/video/audio buffergetMediaUrl(mediaId: string): Promise<Response>
Get download URL for media.
const response = await client.getMediaUrl(message.media.id);
const mediaUrl = response.content.url;Profile Management
getProfile(): Promise<Response>
Get profile information.
const profile = await client.getProfile();updateProfile(profileName: string, aboutText?: string): Promise<Response>
Update profile name and about text.
await client.updateProfile('My Business', 'Welcome!');getPicture(identifier: string): Promise<Response>
Get profile picture URL.
const response = await client.getPicture('5511999999999');
const picUrl = response.content;updateProfilePicture(identifier: string, content: string): Promise<Response>
Update profile picture from URL.
await client.updateProfilePicture('5511999999999', 'https://example.com/profile.jpg');onWhatsApp(identifier: string): Promise<Response>
Check if a phone number is registered on WhatsApp.
const response = await client.onWhatsApp('5511999999999');
if (response.status === 200) {
console.log('Number is on WhatsApp');
}Redis Connection
initialize(): Promise<void>
Manually initialize Redis (already automatic).
await client.initialize();connectToRedis(config?: RedisConfig): Promise<void>
Connect with custom config.
await client.connectToRedis({
host: 'redis.example.com',
port: 6380,
password: 'secret',
});disconnectFromRedis(): Promise<void>
Disconnect from Redis.
await client.disconnectFromRedis();isRedisConnected(): boolean
Check connection status.
if (client.isRedisConnected()) {
console.log('Connected!');
}Webhook Integration
Setup Webhook Server
import express from 'express';
import redis from 'redis';
const app = express();
const redisClient = redis.createClient();
// Your webhook endpoint
app.post('/webhook', (req, res) => {
const { entry } = req.body;
for (const e of entry) {
for (const change of e.changes) {
const phoneId = change.value.metadata.phone_number_id;
// Publish to Redis
redisClient.publish(`whatsapp:${phoneId}`, JSON.stringify(change.value));
}
}
res.json({ success: true });
});
app.listen(3000);Distribute Across Servers
// Server A
const client1 = new WhatsAppOfficialClient('phone_id', 'token', {
host: 'redis.example.com',
});
// Server B
const client2 = new WhatsAppOfficialClient('phone_id', 'token', {
host: 'redis.example.com',
});
// Both receive events automaticallyComplete Example
import { WhatsAppOfficialClient } from 'easy-connect-official-wpp-rc';
async function main() {
const client = new WhatsAppOfficialClient('your_phone_id', 'your_access_token', {
host: 'localhost',
port: 6379,
db: 0,
});
// Handle messages
client.onMessage(async (message) => {
if (message.type === 'text') {
console.log(`📨 ${message.from}: ${message.message}`);
// Reply
await client.sendText(message.from, 'Thanks! 👋');
} else if (message.type === 'image') {
console.log(`📸 Image received: ${message.media?.id}`);
// Send back a reaction
await client.sendReaction(message.from, '👍', message.id);
}
});
// Handle acknowledgments
client.onMessageAck((ack) => {
console.log(`✔️ ${ack.status}`);
});
// Handle errors
client.onError((error) => {
console.error('❌ Error:', error);
});
// Connection status
client.onConnectionStatus((status) => {
console.log(`🔌 ${status}`);
});
// Graceful shutdown
process.on('SIGINT', async () => {
console.log('\n👋 Closing...');
await client.disconnectFromRedis();
process.exit(0);
});
console.log('🚀 Running...');
}
main().catch(console.error);Error Handling
All methods return a Response object:
const response = await client.sendText('recipient_phone_number_id', 'Hello');
if (response.status === 200) {
console.log('Success:', response.content);
} else {
console.error('Error:', response.message);
}Environment Variables
WHATSAPP_PHONE_ID=your_phone_id
WHATSAPP_ACCESS_TOKEN=your_access_token
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0
REDIS_PASSWORD=optionalPerformance Tips
- Reuse instances — One per phone number
- Use Redis — For multi-server setups
- Fast listeners — Offload heavy work to queues
- Monitor health — Use
onConnectionStatus - Clean shutdown — Call
disconnectFromRedis()
Common Issues
Redis connection timeout
- Ensure Redis is running
- Check host/port configuration
- Verify network connectivity
Channel subscription failed
- Confirm correct
phoneNumberId - Check Redis pub/sub is enabled
- Review logs
Webhook events not received
- Verify webhook URL is public
- Check Meta Dashboard configuration
- Ensure channel name:
whatsapp:${phoneId}
Documentation
License
ISC
Author
Send IO
Support
- Email: [email protected]
- GitHub: Report issues
