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();
                }
        }
    }
});