Code Examples
Basic Bot
A simple bot that responds to messages.
bot.js
const { makeWASocket, useMultiFileAuthState, DisconnectReason } = require('socketon');
const pino = require('pino');
async function startBot() {
const { state, saveCreds } = await useMultiFileAuthState('./auth');
const sock = makeWASocket({
logger: pino({ level: 'silent' }),
auth: state,
printQRInTerminal: true
});
sock.ev.on('connection.update', async (update) => {
const { connection, lastDisconnect } = update;
if (connection === 'close') {
const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut;
console.log('Connection closed, reconnecting:', shouldReconnect);
if (shouldReconnect) {
startBot();
}
} else if (connection === 'open') {
console.log('Bot is connected!');
}
});
sock.ev.on('messages.upsert', async ({ messages, type }) => {
if (type !== 'notify') return;
const msg = messages[0];
if (msg.key.fromMe) return;
const text = msg.message?.conversation ||
msg.message?.extendedTextMessage?.text || '';
if (text === '!ping') {
await sock.sendMessage(msg.key.remoteJid, { text: 'Pong!' });
}
if (text === '!menu') {
await sock.sendMessage(msg.key.remoteJid, {
text: `*Bot Menu*\n\n!ping - Ping bot\n!menu - Show menu\n!sticker - Create sticker`
});
}
});
sock.ev.on('creds.update', saveCreds);
}
startBot();
Pairing Code Authentication
Login without QR code using pairing code.
pairing.js
const { makeWASocket, useMultiFileAuthState } = require('socketon');
const pino = require('pino');
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
async function start() {
const { state, saveCreds } = await useMultiFileAuthState('./auth');
const sock = makeWASocket({
logger: pino({ level: 'silent' }),
auth: state,
printQRInTerminal: false
});
sock.ev.on('connection.update', async ({ connection, pairingCode }) => {
if (pairingCode) {
console.log('\n========================================');
console.log('Pairing Code:', pairingCode);
console.log('========================================\n');
}
if (connection === 'open') {
console.log('Connected successfully!');
}
});
sock.ev.on('creds.update', saveCreds);
}
// Request pairing code for phone number
rl.question('Enter phone number (e.g., 6281234567890): ', async (phone) => {
rl.close();
const { state, saveCreds } = await useMultiFileAuthState('./auth');
const sock = makeWASocket({
logger: pino({ level: 'silent' }),
auth: state,
printQRInTerminal: false
});
const code = await sock.requestPairingCode(phone);
console.log('Pairing Code:', code);
sock.ev.on('creds.update', saveCreds);
});
Send Media Messages
Send various types of media messages.
media.js
const fs = require('fs');
// Send image
await sock.sendMessage(jid, {
image: { url: './image.jpg' },
caption: 'Check out this image!',
jpegThumbnail: fs.readFileSync('./thumbnail.jpg')
});
// Send video
await sock.sendMessage(jid, {
video: { url: './video.mp4' },
caption: 'Video caption',
gifPlayback: false
});
// Send audio
await sock.sendMessage(jid, {
audio: { url: './audio.mp3' },
mimetype: 'audio/mp4',
ptt: true // Voice note
});
// Send document
await sock.sendMessage(jid, {
document: { url: './document.pdf' },
mimetype: 'application/pdf',
fileName: 'document.pdf',
caption: 'Here is the document'
});
// Send sticker
await sock.sendMessage(jid, {
sticker: fs.readFileSync('./sticker.webp')
});
// Send location
await sock.sendMessage(jid, {
location: {
degreesLatitude: -6.2088,
degreesLongitude: 106.8456,
name: 'Jakarta',
address: 'Indonesia'
}
});
// Send contact
const vcard = 'BEGIN:VCARD\n'
+ 'VERSION:3.0\n'
+ 'FN:John Doe\n'
+ 'TEL;type=CELL;type=VOICE;waid=6281234567890:+6281234567890\n'
+ 'END:VCARD';
await sock.sendMessage(jid, {
contacts: {
displayName: 'John Doe',
contacts: [{ vcard }]
}
});
Interactive Messages
Send buttons and list messages.
interactive.js
// Send buttons
await sock.sendMessage(jid, {
text: 'Choose an option:',
footer: 'Socketon Bot',
buttons: [
{ buttonId: 'btn1', buttonText: { displayText: 'Button 1' }, type: 1 },
{ buttonId: 'btn2', buttonText: { displayText: 'Button 2' }, type: 1 }
],
headerType: 1
});
// Send list message
await sock.sendMessage(jid, {
text: 'Select from list:',
footer: 'Socketon Bot',
title: 'Menu',
buttonText: 'View Options',
sections: [
{
title: 'Section 1',
rows: [
{ title: 'Option 1', rowId: 'opt1', description: 'Description 1' },
{ title: 'Option 2', rowId: 'opt2', description: 'Description 2' }
]
},
{
title: 'Section 2',
rows: [
{ title: 'Option 3', rowId: 'opt3', description: 'Description 3' }
]
}
]
});
// Handle button response
sock.ev.on('messages.upsert', async ({ messages }) => {
const msg = messages[0];
const buttonResponse = msg.message?.buttonsResponseMessage;
const listResponse = msg.message?.listResponseMessage;
if (buttonResponse) {
console.log('Button clicked:', buttonResponse.selectedButtonId);
}
if (listResponse) {
console.log('List selected:', listResponse.singleSelectReply?.selectedRowId);
}
});
Group Management
Manage WhatsApp groups.
groups.js
// Create group
const group = await sock.groupCreate('My Group', ['6281234567890@s.whatsapp.net']);
console.log('Group created:', group.id);
// Get group metadata
const metadata = await sock.groupMetadata(groupJid);
console.log('Group name:', metadata.subject);
console.log('Participants:', metadata.participants.length);
// Add participants
await sock.groupParticipantsUpdate(groupJid, [
'6281234567890@s.whatsapp.net',
'6281234567891@s.whatsapp.net'
], 'add');
// Remove participants
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'remove');
// Promote to admin
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'promote');
// Demote from admin
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'demote');
// Update group subject
await sock.groupUpdateSubject(groupJid, 'New Group Name');
// Update group description
await sock.groupUpdateDescription(groupJid, 'Group description');
// Get invite code
const code = await sock.groupInviteCode(groupJid);
console.log('Invite code:', code);
console.log('Invite link:', `https://chat.whatsapp.com/${code}`);
// Revoke invite code
await sock.groupRevokeInvite(groupJid);
// Join group via invite code
const joinedGroupId = await sock.groupAcceptInvite('ABC123DEF456');
// Leave group
await sock.groupLeave(groupJid);
// Set group to admins only
await sock.groupSettingUpdate(groupJid, 'announcement');
// Set group to all members can send
await sock.groupSettingUpdate(groupJid, 'not_announcement');
// Lock group info
await sock.groupSettingUpdate(groupJid, 'locked');
// Unlock group info
await sock.groupSettingUpdate(groupJid, 'unlocked');
Newsletter
Work with WhatsApp newsletters/channels.
newsletter.js
// Create newsletter
const newsletter = await sock.newsletterCreate(
'My Newsletter',
'Newsletter description',
'ALL' // Reaction mode: 'ALL' | 'BASIC' | 'NONE'
);
console.log('Newsletter created:', newsletter.id);
// Get newsletter metadata
const meta = await sock.newsletterMetadata('jid', newsletterJid);
// Follow newsletter
await sock.newsletterFollow(newsletterJid);
// Unfollow newsletter
await sock.newsletterUnfollow(newsletterJid);
// Update newsletter
await sock.newsletterUpdateName(newsletterJid, 'New Name');
await sock.newsletterUpdateDescription(newsletterJid, 'New description');
await sock.newsletterUpdatePicture(newsletterJid, { url: './image.jpg' });
await sock.newsletterRemovePicture(newsletterJid);
// React to newsletter message
await sock.newsletterReactMessage(newsletterJid, 'serverMessageId', '👍');
// Fetch newsletter messages
const messages = await sock.newsletterFetchMessages('jid', newsletterJid, 50);
console.log('Messages:', messages);
// Delete newsletter
await sock.newsletterDelete(newsletterJid);
Profile Management
Manage user profile and privacy settings.
profile.js
// Update profile name
await sock.updateProfileName('New Name');
// Update profile status/about
await sock.updateProfileStatus('Available');
// Update profile picture
await sock.updateProfilePicture(sock.user.id, { url: './avatar.jpg' });
// Remove profile picture
await sock.removeProfilePicture(sock.user.id);
// Get profile picture URL
const ppUrl = await sock.profilePictureUrl(jid);
console.log('Profile picture:', ppUrl);
// Get user status
const status = await sock.fetchStatus(jid);
console.log('Status:', status);
// Block contact
await sock.updateBlockStatus(jid, 'block');
// Unblock contact
await sock.updateBlockStatus(jid, 'unblock');
// Get blocked contacts
const blocklist = await sock.fetchBlocklist();
console.log('Blocked:', blocklist);
// Privacy settings
await sock.updateLastSeenPrivacy('all'); // 'all' | 'contacts' | 'contact_blacklist' | 'nobody'
await sock.updateOnlinePrivacy('all'); // 'all' | 'match_last_seen'
await sock.updateProfilePicturePrivacy('contacts');
await sock.updateReadReceiptsPrivacy('all'); // 'all' | 'none'
Download Media
Download media from received messages.
download.js
const { downloadMediaMessage } = require('socketon');
const fs = require('fs');
sock.ev.on('messages.upsert', async ({ messages }) => {
const msg = messages[0];
// Check if message contains media
const msgType = Object.keys(msg.message || {})[0];
if (['imageMessage', 'videoMessage', 'audioMessage', 'documentMessage', 'stickerMessage'].includes(msgType)) {
try {
const buffer = await downloadMediaMessage(msg, 'buffer', {});
// Get extension
const mime = msg.message[msgType].mimetype;
const ext = mime.split('/')[1];
// Save to file
const filename = `./download_${Date.now()}.${ext}`;
fs.writeFileSync(filename, buffer);
console.log('Media saved:', filename);
} catch (err) {
console.error('Download error:', err);
}
}
});
React to Messages
React to messages with emojis.
react.js
// React to a message
await sock.sendMessage(jid, {
react: {
key: message.key,
text: '👍' // Emoji
}
});
// Remove reaction
await sock.sendMessage(jid, {
react: {
key: message.key,
text: '' // Empty string to remove
}
});
Reply & Quote Messages
Reply to specific messages.
reply.js
// Reply to a message
await sock.sendMessage(jid, {
text: 'This is a reply!'
}, {
quoted: message
});
// Forward a message
await sock.sendMessage(newJid, {
forward: message,
force: false // Set true to appear as forwarded
});
Presence & Typing
Send presence updates and typing indicators.
presence.js
// Send typing indicator
await sock.sendPresenceUpdate('composing', jid);
// Send recording audio indicator
await sock.sendPresenceUpdate('recording', jid);
// Stop typing
await sock.sendPresenceUpdate('paused', jid);
// Set online
await sock.sendPresenceUpdate('available');
// Set offline
await sock.sendPresenceUpdate('unavailable');
// Subscribe to contact presence
await sock.presenceSubscribe(jid);
// Listen for presence updates
sock.ev.on('presence.update', ({ id, presences }) => {
for (const [participant, presence] of Object.entries(presences)) {
console.log(`${participant}: ${presence.lastKnownPresence}`);
}
});
Error Handling
Handle connection errors properly.
error-handling.js
const { DisconnectReason } = require('socketon');
sock.ev.on('connection.update', async (update) => {
const { connection, lastDisconnect } = update;
if (connection === 'close') {
const statusCode = lastDisconnect?.error?.output?.statusCode;
const shouldReconnect = statusCode !== DisconnectReason.loggedOut;
console.log('Connection closed. Status:', statusCode);
switch (statusCode) {
case DisconnectReason.loggedOut:
console.log('Device logged out. Clear auth and scan QR again.');
// Clear auth folder
break;
case DisconnectReason.connectionReplaced:
console.log('Another device connected. This device disconnected.');
break;
case DisconnectReason.restartRequired:
console.log('Restart required. Reconnecting...');
startBot();
break;
case DisconnectReason.timedOut:
console.log('Connection timed out. Reconnecting...');
startBot();
break;
default:
if (shouldReconnect) {
console.log('Reconnecting...');
startBot();
}
}
}
});