Skip to content

Repository files navigation

WuzAPI Client

A comprehensive TypeScript client library for the WuzAPI WhatsApp API. This library provides a simple and intuitive interface to interact with WhatsApp through the WuzAPI service.

🚀 Features

  • 🔥 Full TypeScript Support - Complete type definitions for all API endpoints
  • 🏗️ Modular Architecture - Organized by functionality (admin, session, chat, user, group, webhook)
  • 🚀 Promise-based - Modern async/await support
  • 🛡️ Error Handling - Comprehensive error handling with detailed error types
  • 📦 Tree Shakable - Import only what you need
  • 🔧 Easy Configuration - Simple setup with minimal configuration
  • 📖 Well Documented - Extensive documentation and examples
  • 📞 Call Management - Reject incoming calls
  • 📝 Status Updates - Set WhatsApp status text

📦 Installation

bun add wuzapi

or with npm

npm install wuzapi

or with Yarn

yarn add wuzapi

⚡ Quick Start

Basic Setup

importWuzapiClientfrom"wuzapi";constclient=newWuzapiClient({apiUrl: "http://localhost:8080",token: "your-user-token",});// Connect to WhatsAppawaitclient.session.connect({Subscribe: ["Message","ReadReceipt"],Immediate: false,});// Send a messageawaitclient.chat.sendText({Phone: "5491155554444",Body: "Hello from WuzAPI! 🎉",});

Login Options

Option 1: QR Code (Traditional)

// Get QR code for scanningconstqr=awaitclient.session.getQRCode();console.log("Scan this QR code:",qr.QRCode);

Option 2: Phone Pairing (New!)

// Pair using phone number (generates verification code)awaitclient.session.pairPhone("5491155554444");

🔧 Configuration

interfaceWuzapiConfig{apiUrl: string;// Your WuzAPI server URLtoken?: string;// Authentication token (can be provided per request)}// Global token approachconstclient=newWuzapiClient({apiUrl: "http://localhost:8080",token: "your-token",});// Flexible token approachconstclient=newWuzapiClient({apiUrl: "http://localhost:8080",});// Use different tokens for different operationsawaitclient.chat.sendText({Phone: "123",Body: "Hello"},{token: "user-specific-token"});

💬 Essential Chat Operations

// Send text messageawaitclient.chat.sendText({Phone: "5491155554444",Body: "Hello World!",});// Send imageawaitclient.chat.sendImage({Phone: "5491155554444",Image: "data:image/jpeg;base64,/9j/4AAQ...",Caption: "Check this out!",});// Send interactive buttonsawaitclient.chat.sendButtons({Phone: "5491155554444",Body: "Choose an option:",Buttons: [{ButtonId: "yes",ButtonText: {DisplayText: "Yes"},Type: 1},{ButtonId: "no",ButtonText: {DisplayText: "No"},Type: 1},],});// Send list menuawaitclient.chat.sendList("5491155554444",// Phone"View Menu",// Button text"Select from menu:",// Description"Options",// Top text/title[{// SectionsTitle: "Main Options",Rows: [{Title: "Option 1",Desc: "First choice",RowId: "opt1"},{Title: "Option 2",Desc: "Second choice",RowId: "opt2"},],},]);// Send poll (for groups only)awaitclient.chat.sendPoll("120362023605733675@g.us",// Group JID"What's your favorite color?",// Header["Red","Blue","Green"]// Options array);

👥 Group Management

// Create groupconstgroup=awaitclient.group.create("My Group",["5491155553934","5491155553935",]);// Get group infoconstinfo=awaitclient.group.getInfo(group.JID);// Add participantsawaitclient.group.updateParticipants(group.JID,"add",["5491155553936"]);// Set group settingsawaitclient.group.setName(group.JID,"New Group Name");awaitclient.group.setTopic(group.JID,"Welcome message");awaitclient.group.setAnnounce(group.JID,true);// Only admins can send

👤 User Operations

// Check if numbers are WhatsApp usersconstcheck=awaitclient.user.check(["5491155554444"]);// Get user infoconstinfo=awaitclient.user.getInfo(["5491155554444"]);// Get contactsconstcontacts=awaitclient.user.getContacts();// Send presence statusawaitclient.user.sendPresence("available");

🔗 Webhook Setup

// Set webhook URL with eventsawaitclient.webhook.setWebhook("https://your-server.com/webhook",["Message","ReadReceipt",]);// Get webhook configconstconfig=awaitclient.webhook.getWebhook();// Update webhook with new URL, events, and statusawaitclient.webhook.updateWebhook("https://new-server.com/webhook",["Message","ReadReceipt"],true);

📚 Examples

Check out the complete examples in the examples/ directory:

Run Examples

# Basic usage
node examples/basic-usage.js
# Advanced features
node examples/advanced-features.js
# Start chatbot
node examples/chatbot-example.js
# Webhook types example (with complete type safety)
node examples/webhook-types-example.js

🤖 Simple Bot Example

importWuzapiClientfrom"wuzapi";constclient=newWuzapiClient({apiUrl: "http://localhost:8080",token: "your-token",});// Connect and wait for messagesawaitclient.session.connect({Subscribe: ["Message"]});awaitclient.webhook.setWebhook("https://your-server.com/webhook",["Message"]);// In your webhook handler:app.post("/webhook",async(req,res)=>{constwebhookPayload=req.body;// Validate payload structureif(webhookPayload.token!=="your-expected-token"){returnres.status(401).json({error: "Invalid token"});}// Handle by event typeswitch(webhookPayload.type){case"Message":
const{ event }=webhookPayload;if(event.Message?.conversation){constmessage=event.Message.conversation;constfrom=event.Info.RemoteJid.replace("@s.whatsapp.net","");if(message.toLowerCase().includes("hello")){awaitclient.chat.sendText({Phone: from,Body: "Hello! 👋 How can I help you?",});}}break;case"Connected":
console.log("✅ WhatsApp connected");break;case"QR":
console.log("📱 QR Code:",webhookPayload.event.Codes);break;}res.json({success: true});});

📖 Complete API Reference

📱 Session Module - Connection and authentication

Connection

// Connect to WhatsAppawaitclient.session.connect({Subscribe: ["Message","ReadReceipt","HistorySync"],Immediate: false,});// Get connection statusconststatus=awaitclient.session.getStatus();// Disconnect (keeps session)awaitclient.session.disconnect();// Logout (destroys session)awaitclient.session.logout();

Authentication

// Get QR code for scanningconstqr=awaitclient.session.getQRCode();// Pair phone using phone number (generates verification code)awaitclient.session.pairPhone("5491155554444");// Request message history syncawaitclient.session.requestHistory();// Configure proxyawaitclient.session.setProxy("socks5://user:pass@proxy:port",true);// Set historyfor userawaitclient.session.setHistoryCount(100);// use 0 for disabled

S3 Storage

// Configure S3 storageawaitclient.session.configureS3({enabled: true,endpoint: "https://s3.amazonaws.com",region: "us-east-1",bucket: "my-bucket",accessKey: "AKIAIOSFODNN7EXAMPLE",secretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",pathStyle: false,mediaDelivery: "both",retentionDays: 30,});// Get S3 configurationconsts3Config=awaitclient.session.getS3Config();// Test S3 connectionawaitclient.session.testS3();// Delete S3 configurationawaitclient.session.deleteS3Config();

HMAC Configuration

// Configure HMAC key for webhook signing (minimum 32 characters)awaitclient.session.configureHmac("your_hmac_key_minimum_32_characters_long");// Get HMAC configuration statusconsthmacConfig=awaitclient.session.getHmacConfig();// Delete HMAC configurationawaitclient.session.deleteHmacConfig();
💬 Chat Module - Send and manage messages

Basic Messages

// Send text messageawaitclient.chat.sendText({Phone: "5491155554444",Body: "Hello World!",Id: "optional-message-id",});// Reply to a messageawaitclient.chat.sendText({Phone: "5491155554444",Body: "This is a reply",ContextInfo: {StanzaId: "original-message-id",Participant: "5491155553935@s.whatsapp.net",},});

Media Messages

// Send imageawaitclient.chat.sendImage({Phone: "5491155554444",Image: "data:image/jpeg;base64,/9j/4AAQ...",Caption: "Check this out!",});// Send audioawaitclient.chat.sendAudio({Phone: "5491155554444",Audio: "data:audio/ogg;base64,T2dnUw...",});// Send videoawaitclient.chat.sendVideo({Phone: "5491155554444",Video: "data:video/mp4;base64,AAAAIGZ0eXA...",Caption: "Video caption",});// Send documentawaitclient.chat.sendDocument({Phone: "5491155554444",Document: "data:application/pdf;base64,JVBERi0x...",FileName: "document.pdf",});// Send stickerawaitclient.chat.sendSticker({Phone: "5491155554444",Sticker: "data:image/webp;base64,UklGRuI...",});

Interactive Messages

// Send buttonsawaitclient.chat.sendButtons({Phone: "5491155554444",Body: "Choose an option:",Footer: "Select one:",Buttons: [{ButtonId: "option1",ButtonText: {DisplayText: "Option 1"},Type: 1},{ButtonId: "option2",ButtonText: {DisplayText: "Option 2"},Type: 1},],});// Send list messageawaitclient.chat.sendList("5491155554444",// Phone"View Menu",// Button text"Please select from the menu:",// Description"Menu Options",// Top text/title[{// SectionsTitle: "Main Course",Rows: [{Title: "Pizza",Desc: "Delicious pizza",RowId: "pizza"},{Title: "Burger",Desc: "Tasty burger",RowId: "burger"},],},]);// Send poll (for groups only)awaitclient.chat.sendPoll("120362023605733675@g.us",// Group JID"What's your favorite color?",// Header["Red","Blue","Green"]// Options array);

Message Management

// Delete a message (revoke for everyone)awaitclient.chat.deleteMessage("message-id-to-delete","5491155554444");// Edit a messageawaitclient.chat.editMessage("message-id-to-edit","5491155554444","This is the updated message text");// React to messageawaitclient.chat.react({Phone: "5491155554444",Body: "❤️",id: "message-id-to-react-to",});// Mark messages as readawaitclient.chat.markRead({id: ["message-id-1","message-id-2"],Chat: "5491155553934@s.whatsapp.net",});// Send chat presence (typing indicator)awaitclient.chat.sendPresence({Phone: "5491155554444",State: "composing",// or "paused"});// Send chat presence (recording indicator)awaitclient.chat.sendPresence({Phone: "5491155554444",State: "composing",Media: "audio",});

Chat History

// Get chat message history (requires message history to be enabled on server)consthistory=awaitclient.chat.getChatHistory("5491155553333@s.whatsapp.net",// Chat JID100// Optional: limit (default 50, max 1000));// History contains array of messages in reverse chronological order (newest first)history.data.forEach((message)=>{console.log(`Message ${message.id}:`);console.log(`From: ${message.sender_jid}`);console.log(`Time: ${message.timestamp}`);console.log(`Type: ${message.message_type}`);console.log(`Content: ${message.text_content}`);if(message.media_link){console.log(`Media: ${message.media_link}`);}});

Location and Contacts

// Send locationawaitclient.chat.sendLocation({Phone: "5491155554444",Latitude: 48.85837,Longitude: 2.294481,Name: "Eiffel Tower, Paris",});// Send contactawaitclient.chat.sendContact({Phone: "5491155554444",Name: "John Doe",Vcard:
"BEGIN:VCARD\nVERSION:3.0\nN:Doe;John;;;\nFN:John Doe\nTEL:+1234567890\nEND:VCARD",});

Media Download

// Download imageconstimage=awaitclient.chat.downloadImage({Url: "https://mmg.whatsapp.net/d/f/...",MediaKey: "media-key...",Mimetype: "image/jpeg",FileSHA256: "file-hash...",FileLength: 2039,});// Download stickerconststicker=awaitclient.chat.downloadSticker({Url: "https://mmg.whatsapp.net/d/f/...",MediaKey: "media-key...",Mimetype: "image/webp",FileSHA256: "file-hash...",FileLength: 1024,});

Chat Management

// Archive a chatawaitclient.chat.archiveChat("5491155554444@s.whatsapp.net",true);// Unarchive a chatawaitclient.chat.archiveChat("5491155554444@s.whatsapp.net",false);// Request unavailable message (for messages that couldn't be decrypted)awaitclient.chat.requestUnavailableMessage("5491155554444@s.whatsapp.net",// chat JID"5491155554444@s.whatsapp.net",// sender JID"ABCD1234"// message ID);
👤 User Module - User information and contacts
// Check if numbers are WhatsApp usersconstcheck=awaitclient.user.check(["5491155554444","5491155554445"]);// Get user informationconstinfo=awaitclient.user.getInfo(["5491155554444"]);// Get user avatarconstavatar=awaitclient.user.getAvatar("5491155554444",true);// true for preview// Get all contactsconstcontacts=awaitclient.user.getContacts();// Send user presence (online/offline status)awaitclient.user.sendPresence("available");// or "unavailable"// Get LID (Linked ID) from phone numberconstlid=awaitclient.user.getLid("5491155554444");console.log("LID:",lid.LID);// Get user privacy settingsconstprivacy=awaitclient.user.getPrivacy();console.log("Privacy:",privacy);// Set user privacy settingawaitclient.user.setPrivacy("last","contacts");// Block and Unblock Usersawaitclient.user.blockUser({Phone: "5491155554444"});awaitclient.user.unblockUser({Phone: "5491155554444"});// Get Blocklistconstblocklist=awaitclient.user.getBlocklist();
👥 Group Module - Group management

Basic Group Operations

// List all groupsconstgroups=awaitclient.group.list();// Create a groupconstnewGroup=awaitclient.group.create("My New Group",["5491155553934","5491155553935",]);// Get group infoconstgroupInfo=awaitclient.group.getInfo("120362023605733675@g.us");// Leave a groupawaitclient.group.leave("120362023605733675@g.us");

Group Settings

// Set group nameawaitclient.group.setName("120362023605733675@g.us","New Group Name");// Set group topic/descriptionawaitclient.group.setTopic("120362023605733675@g.us","Welcome to our group! Please read the rules.");// Set group announcement setting (only admins can send messages)awaitclient.group.setAnnounce("120362023605733675@g.us",true);// Set group locked (only admins can modify info)awaitclient.group.setLocked("120362023605733675@g.us",true);// Set disappearing messagesawaitclient.group.setEphemeral("120362023605733675@g.us","24h");// '24h', '7d', '90d', or 'off'

Group Media

// Set group photo (JPEG only)awaitclient.group.setPhoto("120362023605733675@g.us","data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ...");// Remove group photoawaitclient.group.removePhoto("120362023605733675@g.us");

Invites and Participants

// Get invite linkconstinvite=awaitclient.group.getInviteLink("120362023605733675@g.us");// Join a group using invite linkconstjoinResult=awaitclient.group.join("https://chat.whatsapp.com/XXXXXXXXX");// Get group invite informationconstinviteInfo=awaitclient.group.getInviteInfo("https://chat.whatsapp.com/XXXXXXXXX");// Update group participants (add, remove, promote, demote)awaitclient.group.updateParticipants("120362023605733675@g.us","add",// "add", "remove", "promote", "demote"["5491155553936","5491155553937"]);// Group Join Requests & Approval Modeawaitclient.group.setJoinApprovalMode("120362023605733675@g.us",true);constrequests=awaitclient.group.getRequestParticipants("120362023605733675@g.us");// Approve or reject join requestsawaitclient.group.updateRequestParticipants("120362023605733675@g.us","approve",// "approve" or "reject"["5491155553936"]);
👨‍💼 Admin Module - User management (requires admin token)
// List all usersconstusers=awaitclient.admin.listUsers({token: "admin-token"});// Get a specific user by IDconstuser=awaitclient.admin.getUser("user-id-string",{token: "admin-token"});// Add new userconstnewUser=awaitclient.admin.addUser({name: "John Doe",token: "user-token-123",webhook: "https://example.com/webhook",events: "Message,ReadReceipt",// optionalproxyConfig: {enabled: true,proxyURL: "socks5://user:pass@proxy:port",},s3Config: {enabled: true,endpoint: "https://s3.amazonaws.com",region: "us-east-1",bucket: "user-media-bucket",accessKey: "AKIA...",secretKey: "secret...",pathStyle: false,mediaDelivery: "both",retentionDays: 30,},history: 20,// Number of messages to save in the database, defaults to 0, which is disabled},{token: "admin-token"});// Delete user by ID (ID is a string)awaitclient.admin.deleteUser("user-id-string",{token: "admin-token"});// Update/edit a userawaitclient.admin.updateUser("user-id-string",{name: "Updated Name",webhook: "https://new-webhook.com/webhook",events: "Message,ReadReceipt",history: 100,},{token: "admin-token"});// Delete user completely (full deletion including all data)awaitclient.admin.deleteUserComplete("user-id-string",{token: "admin-token",});
🏥 System Module - System statistics and health
// Get system health and statisticsconsthealth=awaitclient.system.getHealth();console.log("Status:",health.status);console.log("Memory usage:",health.memory_stats);console.log("Active connections:",health.active_connections);
🔗 Webhook Module - Webhook configuration
// Set webhook URL with specific eventsawaitclient.webhook.setWebhook("https://my-server.com/webhook",["Message","Receipt","Connected","Disconnected",]);// Get current webhook configurationconstwebhookConfig=awaitclient.webhook.getWebhook();console.log("Webhook URL:",webhookConfig.webhook);console.log("Subscribed events:",webhookConfig.subscribe);// Update webhook URL, events, and statusawaitclient.webhook.updateWebhook("https://my-new-server.com/webhook",["Message","Receipt","Presence"],true);// Delete webhook configurationawaitclient.webhook.deleteWebhook();// Get all available eventsconstavailableEvents=client.webhook.constructor.getAvailableEvents();console.log("Available events:",availableEvents);// Use the enum for type safety (TypeScript)import{WebhookEventType}from"wuzapi";awaitclient.webhook.setWebhook("https://my-server.com/webhook",[WebhookEventType.MESSAGE,WebhookEventType.RECEIPT,WebhookEventType.CONNECTED,]);

📋 Complete Webhook Events List

WuzAPI supports 46 different webhook events. Here's the complete list:

🔧 Connection & Session Events

WebhookEventType.CONNECTED;// "Connected"WebhookEventType.DISCONNECTED;// "Disconnected"WebhookEventType.CONNECT_FAILURE;// "ConnectFailure"WebhookEventType.LOGGED_OUT;// "LoggedOut"WebhookEventType.KEEP_ALIVE_RESTORED;// "KeepAliveRestored"WebhookEventType.KEEP_ALIVE_TIMEOUT;// "KeepAliveTimeout"WebhookEventType.CLIENT_OUTDATED;// "ClientOutdated"WebhookEventType.TEMPORARY_BAN;// "TemporaryBan"WebhookEventType.STREAM_ERROR;// "StreamError"WebhookEventType.STREAM_REPLACED;// "StreamReplaced"

🔐 Authentication Events

WebhookEventType.QR;// "QR"WebhookEventType.QR_SCANNED_WITHOUT_MULTIDEVICE;// "QRScannedWithoutMultidevice"WebhookEventType.QR_TIMEOUT;// "QRTimeout"WebhookEventType.PAIR_SUCCESS;// "PairSuccess"WebhookEventType.PAIR_ERROR;// "PairError"

💬 Message Events

WebhookEventType.MESSAGE;// "Message"WebhookEventType.UNDECRYPTABLE_MESSAGE;// "UndecryptableMessage"WebhookEventType.RECEIPT;// "Receipt"WebhookEventType.MEDIA_RETRY;// "MediaRetry"

👥 Group Events

WebhookEventType.GROUP_INFO;// "GroupInfo"WebhookEventType.JOINED_GROUP;// "JoinedGroup"

👤 User & Contact Events

WebhookEventType.PICTURE;// "Picture"WebhookEventType.USER_ABOUT;// "UserAbout"WebhookEventType.PUSH_NAME_SETTING;// "PushNameSetting"WebhookEventType.PRIVACY_SETTINGS;// "PrivacySettings"WebhookEventType.PRESENCE;// "Presence"WebhookEventType.CHAT_PRESENCE;// "ChatPresence"WebhookEventType.IDENTITY_CHANGE;// "IdentityChange"

🚫 Blocklist Events

WebhookEventType.BLOCKLIST;// "Blocklist"WebhookEventType.BLOCKLIST_CHANGE;// "BlocklistChange"

📱 App State & Sync Events

WebhookEventType.APP_STATE;// "AppState"WebhookEventType.APP_STATE_SYNC_COMPLETE;// "AppStateSyncComplete"WebhookEventType.HISTORY_SYNC;// "HistorySync"WebhookEventType.OFFLINE_SYNC_COMPLETED;// "OfflineSyncCompleted"WebhookEventType.OFFLINE_SYNC_PREVIEW;// "OfflineSyncPreview"

📞 Call Events

WebhookEventType.CALL_OFFER;// "CallOffer"WebhookEventType.CALL_ACCEPT;// "CallAccept"WebhookEventType.CALL_TERMINATE;// "CallTerminate"WebhookEventType.CALL_OFFER_NOTICE;// "CallOfferNotice"WebhookEventType.CALL_RELAY_LATENCY;// "CallRelayLatency"

📰 Newsletter Events

WebhookEventType.NEWSLETTER_JOIN;// "NewsletterJoin"WebhookEventType.NEWSLETTER_LEAVE;// "NewsletterLeave"WebhookEventType.NEWSLETTER_MUTE_CHANGE;// "NewsletterMuteChange"WebhookEventType.NEWSLETTER_LIVE_UPDATE;// "NewsletterLiveUpdate"

🔧 System Events

WebhookEventType.CAT_REFRESH_ERROR;// "CATRefreshError"WebhookEventType.FB_MESSAGE;// "FBMessage"

📦 Webhook Payload Structure

All webhook payloads follow this structure:

{"event": {/* Event-specific data */},"type": "Message",// Event type from the list above"token": "YOUR_TOKEN",// Your authentication token// Optional media fields (when media is involved)"s3": {"url": "https://bucket.s3.amazonaws.com/media/file.jpg","key": "media/file.jpg","bucket": "your-bucket","size": 1024000,"mimeType": "image/jpeg","fileName": "file.jpg"},"base64": "data:image/jpeg;base64,/9j/4AAQ...","mimeType": "image/jpeg","fileName": "image.jpg"}

🎯 Event Subscription Examples

// Subscribe to all message-related eventsawaitclient.webhook.setWebhook("https://your-server.com/webhook",["Message","UndecryptableMessage","Receipt","MediaRetry",]);// Subscribe to connection events onlyawaitclient.webhook.setWebhook("https://your-server.com/webhook",["Connected","Disconnected","LoggedOut","QR",]);// Subscribe to group eventsawaitclient.webhook.setWebhook("https://your-server.com/webhook",["GroupInfo","JoinedGroup",]);// Subscribe to all eventsawaitclient.webhook.setWebhook("https://your-server.com/webhook",["All"]);// TypeScript: Use enum for type safetyimport{WebhookEventType}from"wuzapi";awaitclient.webhook.setWebhook("https://your-server.com/webhook",[WebhookEventType.MESSAGE,WebhookEventType.RECEIPT,WebhookEventType.CONNECTED,WebhookEventType.QR,]);
📰 Newsletter Module - Newsletter management (Business accounts only)
// List all subscribed newslettersconstnewsletters=awaitclient.newsletter.list();newsletters.Newsletters.forEach((newsletter)=>{console.log(`Newsletter: ${newsletter.Name}`);console.log(`Description: ${newsletter.Description}`);console.log(`Handle: ${newsletter.Handle}`);console.log(`State: ${newsletter.State}`);});
📝 Status Module - WhatsApp status updates
// Set status text messageawaitclient.status.setStatusText("Hello from WuzAPI! 🎉");
📞 Call Module - Call management
// Reject an incoming callawaitclient.call.rejectCall("5491155554444",// call_from: phone number of caller"CALL_ID_12345"// call_id: unique call identifier from webhook);

🎣 Webhook Event Handling

WuzAPI sends real-time events to your webhook endpoint. Here's how to handle them:

🆕 Type-Safe Message Discovery

The library now includes comprehensive TypeScript types and utilities for handling webhook messages:

importWuzapiClient,{discoverMessageType,MessageType,hasS3Media,hasBase64Media,}from"wuzapi";// Discover message type automaticallyconstmessageType=discoverMessageType(webhookPayload.event.Message);switch(messageType){caseMessageType.TEXT:
console.log("Text:",webhookPayload.event.Message.conversation);break;caseMessageType.EXTENDED_TEXT:
console.log("Text:",webhookPayload.event.Message.extendedTextMessage.text);break;caseMessageType.IMAGE:
constimageMsg=webhookPayload.event.Message.imageMessage;console.log("Image:",imageMsg.mimetype,imageMsg.fileLength);break;caseMessageType.VIDEO:
constvideoMsg=webhookPayload.event.Message.videoMessage;console.log("Video:",`${videoMsg.seconds}s`,videoMsg.caption);break;caseMessageType.AUDIO:
constaudioMsg=webhookPayload.event.Message.audioMessage;console.log(audioMsg.ptt ? "Voice message" : "Audio file");break;caseMessageType.DOCUMENT:
constdocMsg=webhookPayload.event.Message.documentMessage;console.log("Document:",docMsg.fileName,`${docMsg.pageCount} pages`);break;caseMessageType.CONTACT:
constcontactMsg=webhookPayload.event.Message.contactMessage;console.log("Contact:",contactMsg.displayName);break;caseMessageType.LOCATION:
constlocationMsg=webhookPayload.event.Message.locationMessage;console.log("Location:",locationMsg.degreesLatitude,locationMsg.degreesLongitude);break;caseMessageType.STICKER:
conststickerMsg=webhookPayload.event.Message.stickerMessage;console.log("Sticker:",stickerMsg.isAnimated ? "Animated" : "Static",stickerMsg.mimetype);break;caseMessageType.REACTION:
constreactionMsg=webhookPayload.event.Message.reactionMessage;console.log("Reaction:",reactionMsg.text,"to message",reactionMsg.key.ID);break;caseMessageType.POLL_CREATION:
constpollMsg=webhookPayload.event.Message.pollCreationMessageV3;console.log("Poll:",pollMsg.name,`${pollMsg.options.length} options`);break;caseMessageType.BUTTONS_RESPONSE:
constbuttonResponse=webhookPayload.event.Message.buttonsResponseMessage;console.log("Button clicked:",buttonResponse.selectedButtonId);break;caseMessageType.LIST_RESPONSE:
constlistResponse=webhookPayload.event.Message.listResponseMessage;console.log("List item selected:",listResponse.singleSelectReply.selectedRowId);break;caseMessageType.GROUP_INVITE:
constgroupInvite=webhookPayload.event.Message.groupInviteMessage;console.log("Group invite:",groupInvite.groupName);break;caseMessageType.VIEW_ONCE:
constviewOnceMsg=webhookPayload.event.Message.viewOnceMessage;console.log("View once message received");break;// Handle other new message typescaseMessageType.BUTTONS:
caseMessageType.LIST:
caseMessageType.TEMPLATE:
caseMessageType.POLL:
caseMessageType.POLL_UPDATE:
console.log(`Interactive message type: ${messageType}`);break;}// Handle media intelligentlyif(hasS3Media(webhookPayload)){console.log("S3 URL:",webhookPayload.s3.url);}elseif(hasBase64Media(webhookPayload)){console.log("Base64 media available");}

🎯 Available Message Types

enumMessageType{// Basic messagesTEXT="conversation",// Simple text messagesEXTENDED_TEXT="extendedTextMessage",// Rich text messages// Media messagesIMAGE="imageMessage",// Photos, screenshotsVIDEO="videoMessage",// Video files, GIFsAUDIO="audioMessage",// Audio files, voice messagesDOCUMENT="documentMessage",// PDFs, Word docs, etc.STICKER="stickerMessage",// Stickers (animated/static)// Contact & locationCONTACT="contactMessage",// Shared contactsLOCATION="locationMessage",// Location pins// Interactive messagesBUTTONS="buttonsMessage",// Interactive buttonsLIST="listMessage",// List menusTEMPLATE="templateMessage",// Template messages// Response messagesBUTTONS_RESPONSE="buttonsResponseMessage",// Button click responsesLIST_RESPONSE="listResponseMessage",// List selection responses// Group messagesGROUP_INVITE="groupInviteMessage",// Group invitations// Poll messagesPOLL="pollCreationMessage",// Polls (standard)POLL_CREATION="pollCreationMessageV3",// Polls (v3)POLL_UPDATE="pollUpdateMessage",// Poll vote updates// Special messagesVIEW_ONCE="viewOnceMessage",// View once messagesREACTION="reactionMessage",// Message reactions (emoji)EDITED="editedMessage",// Edited messages// System messagesPROTOCOL="protocolMessage",// System messagesDEVICE_SENT="deviceSentMessage",// Multi-device messagesUNKNOWN="unknown",// Unrecognized types}

Basic Webhook Setup

importexpressfrom"express";importWuzapiClient,{getMessageContent,hasS3Media}from"wuzapi";constapp=express();app.use(express.json());constclient=newWuzapiClient({apiUrl: "http://localhost:8080",token: "your-token",});app.post("/webhook",async(req,res)=>{try{constwebhookPayload=req.body;// Validate payload structure with token and typeif(!webhookPayload.token||!webhookPayload.type||!webhookPayload.event){returnres.status(400).json({error: "Invalid webhook payload structure"});}// Verify token (optional security check)if(webhookPayload.token!=="your-expected-token"){returnres.status(401).json({error: "Invalid webhook token"});}console.log(`Received webhook event: ${webhookPayload.type}`);// Handle S3 media if presentif(hasS3Media(webhookPayload)){console.log("S3 Media:",webhookPayload.s3.url);}constevent=webhookPayload.event;// Handle different event typesswitch(webhookPayload.type){case"Message":
if(event.Message&&event.Info){constmessageContent=getMessageContent(event.Message);constfrom=event.Info.RemoteJid.replace("@s.whatsapp.net","");if(messageContent?.type==="text"){console.log(`Message from ${from}: ${messageContent.content}`);// Auto-replyif(messageContent.content.toLowerCase().includes("hello")){awaitclient.chat.sendText({Phone: from,Body: "Hello! 👋 How can I help you?",});}}}break;case"Receipt":
console.log("Message receipt:",event.Type,event.MessageIDs);break;case"Connected":
console.log("✅ WhatsApp connected successfully");break;case"Disconnected":
console.log("❌ WhatsApp disconnected");break;case"QR":
console.log("📱 QR Code received:",event.Codes);break;case"GroupInfo":
console.log("👥 Group info updated:",event.GroupName);break;case"Presence":
console.log("👤 User presence:",event.From,event.Unavailable ? "offline" : "online");break;// Handle all other webhook eventsdefault:
console.log(`Unhandled event type: ${webhookPayload.type}`,event);}res.json({success: true});}catch(error){console.error("Webhook error:",error);res.status(500).json({error: error.message});}});

Message Types

The getMessageContent() utility function returns structured message data:

constmessageContent=getMessageContent(event.Message);switch(messageContent?.type){case"text":
console.log("Text:",messageContent.content);break;case"image":
console.log("Image:",messageContent.content.caption);break;case"buttonsResponse":
console.log("Button clicked:",messageContent.content.selectedButtonId);break;case"listResponse":
console.log("List selection:",messageContent.content.singleSelectReply?.selectedRowId);break;// ... handle other types}

🛠️ Advanced Topics

⚠️ Error Handling
import{WuzapiError}from"wuzapi";try{awaitclient.chat.sendText({Phone: "invalid-number",Body: "This will fail",});}catch(error){if(errorinstanceofWuzapiError){console.error("WuzAPI Error:",{code: error.code,message: error.message,details: error.details,});}else{console.error("Unexpected error:",error);}}

Common Error Codes

  • 401: Authentication required
  • 404: Endpoint not found
  • 500: Server error
🔧 Custom Configuration
// Custom axios configurationimport{BaseClient}from"wuzapi";classCustomClientextendsBaseClient{constructor(config){super(config);// Add custom interceptorsthis.axios.interceptors.request.use((config)=>{console.log("Making request:",config.url);returnconfig;});}}
📝 TypeScript Support
import{WuzapiClient,SendTextRequest,SendMessageResponse,GroupInfo,User,}from"wuzapi";// All API requests and responses are fully typedconstrequest: SendTextRequest={Phone: "5491155554444",Body: "Typed message",};constresponse: SendMessageResponse=awaitclient.chat.sendText(request);
🔄 Legacy Aliases
// These are equivalent:awaitclient.user.check(["5491155554444"]);awaitclient.users.check(["5491155554444"]);// Aliasawaitclient.chat.sendText({Phone: "123",Body: "Hi"});awaitclient.message.sendText({Phone: "123",Body: "Hi"});// Alias

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone the repository
git clone https://github.com/gusnips/wuzapi-node.git
cd wuzapi
# Install dependencies
bun install
# Run linter
bun run lint
# Run type checker
bun run typecheck
# Build the project
bun run build

📄 License

MIT License - see the LICENSE file for details.

🔗 Links


📊 Changelog

See CHANGELOG.md for detailed version history.


Made with ❤️ for the WhatsApp automation community.

About

TypeScript client library for WuzAPI WhatsApp API

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages