Skip to content

sheikhtamimlover/wca

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WCA

npm version npm downloads Node.js GitHub stars License Visitors


WCA is an FCA-style WhatsApp bot framework built on top of Baileys.
If you know how to write a Facebook Messenger bot using stfca, you already know WCA.


📦 NPM🤖 Example Bot🐛 Issues💬 Support Group📸 Instagram


✨ Features

Category Feature
🔌 Connection QR Code login · Pairing Code (no phone scan) · Auto-reconnect
💬 Messaging Send text · Reply/quote · Mentions · Emoji reactions · Delete for everyone · Edit message · Send poll
📎 Media Image · Video · Audio · PTT/Voice · Document · Sticker · GIF · Location
👥 Groups Create · Leave · Add/Kick · Promote/Demote · Rename · Description · Invite link · Settings · Pin message · Get all groups
👤 Profile Get/Set profile picture · Status text · Display name · Block/Unblock · Get DM info
📡 Events Messages · Reactions · Delete events · Group changes · Typing presence · Calls
💬 Chats Get all chats · Get all contacts · Archive/Unarchive · Mute/Unmute
🔄 Updates Auto-update on startup — always keeps itself current

📋 Requirements

  • Node.js ≥ 18.x (LTS recommended — download)
  • npm ≥ 8.x
  • A WhatsApp account
# Check your versions
node -v
npm -v

📦 Installation

npm install @sheikhtamim/wca

🚀 Quick Start

QR Code login

const wca = require('@sheikhtamim/wca');

wca({ authFolder: './wca_auth' }, (err, api) => {
    if (err) return console.error(err);

    api.listen((err, msg) => {
        if (err || !msg || msg.type !== 'message') return;
        if (msg.body === '!ping') {
            api.sendMessage('🏓 Pong!', msg.threadID);
        }
    });
});

Pairing Code login (no QR scan needed)

const wca = require('@sheikhtamim/wca');

wca({
    authFolder:     './wca_auth',
    phoneNumber:    '8801xxxxxxxxx',   // international format, no +
    usePairingCode: true,
}, (err, api) => {
    if (err) return console.error(err);
    console.log('Connected as', api.getCurrentUserID());

    api.listen((err, msg) => {
        if (!msg || msg.type !== 'message') return;
        if (msg.body === '!ping') {
            api.sendMessage('🏓 Pong!', msg.threadID);
        }
    });
});

When the pairing code prints in your console:

  1. Open WhatsApp → ⋮ Menu → Linked Devices
  2. Tap Link a deviceLink with phone number instead
  3. Enter the code shown in your terminal

⚙️ Options

wca({
    authFolder:       './wca_auth',   // auth state folder  (default: './wca_auth')
    phoneNumber:      '628xxx',       // for pairing code
    usePairingCode:   true,           // force pairing code flow
    skipUpdateCheck:  false,          // set true to skip auto-update on start

    globalOptions: {
        selfListen:            false,   // process own sent messages
        selfListenEvent:       false,   // emit own messages to listen()
        listenEvents:          true,    // emit group / call / presence events
        updatePresence:        false,   // emit all presence updates
        listenTyping:          false,   // emit only typing (composing/paused) events
        autoMarkDelivery:      false,   // auto-read every received message
        autoReconnect:         true,    // reconnect on unexpected drop
        emitReady:             false,   // emit { type:'ready' } on connection open
        enableTypingIndicator: false,   // show typing before every sendMessage
        typingDuration:        3000,    // typing indicator duration ms
        logLevel:              'error', // 'silent' | 'error' | 'warn' | 'info' | 'debug'
        online:                true,    // appear online when connected
    },
}, callback);

🔄 Auto-Update (built-in)

WCA automatically checks for updates every time it starts and installs the latest version before connecting. No manual setup needed — just run your bot normally.

// WCA auto-updates itself. No extra code required.
wca({ authFolder: './wca_auth' }, (err, api) => { ... });

To disable auto-update (not recommended):

wca({ skipUpdateCheck: true, authFolder: './wca_auth' }, (err, api) => { ... });

You can also call it manually:

const { checkForWCAUpdate } = require('@sheikhtamim/wca/checkUpdate');
await checkForWCAUpdate();

// Options:
await checkForWCAUpdate({
    autoUpdate:   true,    // install the update   (default: true)
    silent:       false,   // suppress console log (default: false)
    exitOnUpdate: true,    // exit(2) so pm2/nodemon restarts (default: true)
});

📨 Message Event Format

{
    type:          'message',
    body:          'Hello!',
    threadID:      '628xxx@s.whatsapp.net',   // DM  OR  120363xxx@g.us  (group)
    senderID:      '628xxx@s.whatsapp.net',   // always a phone JID (LIDs resolved)
    author:        '628xxx@s.whatsapp.net',   // alias for senderID
    messageID:     'XXXXXXXXXXXXXXXXXX',
    isGroup:       false,
    isSingleUser:  true,
    fromMe:        false,
    timestamp:     1716900000,
    attachments:   [ { type:'image', mimetype:'image/jpeg', caption:'...', ... } ],
    mentions:      [ '628yyy@s.whatsapp.net' ],
    replyToMessage: {
        messageID: 'YYYYY',
        senderID:  '628xxx@s.whatsapp.net',
        body:      'quoted text',
        attachments: [],
    },
    location:     null,   // { latitude, longitude, name, address } if location msg
    poll:         null,   // { name, options, selectableCount }     if poll msg
    quoteOptions: { quoted: <rawWAMessage> },  // pass directly to sendMessage for reply
    args:         ['!ping'],    // body.split(' ')
    raw:          <WAMessage>,  // raw Baileys object
}

Other event types

// Emoji reaction
{ type: 'message_reaction', emoji: '👍', reactionKey: { id, remoteJid, fromMe }, senderID, threadID, ... }

// Someone deleted a message
{ type: 'message_unsend', logMessageType: 'log:unsend', deletedMessageID, senderID, threadID, ... }

// Group participant change
{ type: 'event', logMessageType: 'log:subscribe'|'log:unsubscribe'|'log:thread-admins',
  participants: ['628xxx@s.whatsapp.net'], author, threadID, logMessageData: { action, ... } }

// Group metadata change
{ type: 'group_update', logMessageType: 'log:thread-name'|'log:thread-image'|'log:thread-description'|...,
  threadID, author, logMessageData: { value } }

// Typing / presence
{ type: 'presence', userID, threadID, presence: 'composing'|'paused'|'available'|'unavailable', isTyping }

// Incoming call
{ type: 'call', from, isVideo, isGroup, status }

📚 API Reference

Messaging

api.sendMessage(msg, threadID, [cb])        // text, attachment, reply, mention
api.sendImage(url, threadID, caption, opts)
api.sendVideo(url, threadID, caption, opts)
api.sendAudio(url, threadID, opts)
api.sendPTT(url, threadID, opts)            // voice note
api.sendDocument(url, threadID, caption, opts)
api.sendSticker(url, threadID, opts)
api.sendGif(url, threadID, caption, opts)
api.sendLocation(threadID, lat, lon, opts)
api.sendTypingIndicator(bool, threadID)
api.markAsRead(threadID, senderID, [ids])
api.reactToMessage(threadID, msgID, emoji)
api.deleteMessage(threadID, msgID, forAll)
api.editMessage(threadID, msgID, newText)   // edit a sent message
api.sendPoll(threadID, question, options, [opts])  // send a poll
api.pinMessage(threadID, msgID)             // pin a message
api.unpinMessage(threadID, msgID)           // unpin a message
api.downloadMedia(rawMsg)                   // → Buffer

Quoted reply

// Using quoteOptions from the incoming event (best):
api.sendMessage('Got it!', msg.threadID, null, { replyToMessage: msg.quoteOptions.quoted });

// Or pass the raw message directly:
api.sendMessage({ body: 'Reply!', replyToMessage: msg.raw }, msg.threadID);

Groups

api.getGroupInfo(threadID)                  // full group info (for DB saving)
api.getAllGroups()                           // all groups the bot is in
api.getGroupAdmins(threadID)
api.getGroupInviteLink(threadID)
api.groupRevokeInvite(threadID)
api.groupAcceptInvite(code)
api.addUserToGroup(threadID, [userIDs])
api.kickUser(threadID, [userIDs])
api.createGroup(name, [participantIDs])
api.leaveGroup(threadID)
api.promoteAdmin(threadID, [userIDs])
api.demoteAdmin(threadID, [userIDs])
api.changeGroupSubject(threadID, name)
api.changeGroupDescription(threadID, desc)
api.groupSettingUpdate(threadID, setting)   // 'announcement'|'not_announcement'|'locked'|'unlocked'

Profile & user

api.getProfilePicture(userID, type)
api.getUserInfo([userIDs])
api.getDMInfo(userID)                       // full DM user info (for DB saving)
api.getContacts()                           // all contacts
api.getChats()                              // all chats / conversations
api.fetchStatus(userID)
api.updateProfilePicture(media)
api.updateProfileStatus(text)
api.updateProfileName(name)
api.blockContact(userID)
api.unblockContact(userID)
api.sendPresenceUpdate(type, threadID)      // 'available'|'unavailable'|'composing'|'paused'
api.getCurrentUserID()                      // own JID
api.sock                                    // raw Baileys socket

Chats

api.archiveChat(threadID, [archive=true])   // archive a chat
api.unarchiveChat(threadID)                 // unarchive a chat
api.muteChat(threadID, [durationMs])        // mute a chat  (default 8 hours)
api.unmuteChat(threadID)                    // unmute a chat

🗄️ Group / DM Info for Database

Get full group info (GC)

const info = await api.getGroupInfo('120363xxx@g.us');
// Returns:
// {
//   threadID, name, description, owner, creation,
//   size, adminIDs, participantIDs,
//   participants: [{ userID, isAdmin, isSuperAdmin }],
//   announcement, restrict, ephemeralDuration, raw
// }

Get all groups the bot is in

const groups = await api.getAllGroups();
groups.forEach(g => console.log(g.name, g.size));

Get full DM user info

const info = await api.getDMInfo('628xxx@s.whatsapp.net');
// Returns:
// {
//   userID, phone, name, status, statusTimestamp,
//   profilePicture, isBusiness, businessProfile, isMe, raw
// }

🤖 Full Bot Example

const wca = require('@sheikhtamim/wca');

// WCA auto-updates itself before connecting — no extra code needed.
wca({
    authFolder:     './wca_auth',
    phoneNumber:    '8801xxxxxxxxx',
    usePairingCode: true,
    globalOptions:  {
        listenEvents:  true,
        selfListen:    false,
        autoReconnect: true,
    },
}, (err, api) => {
    if (err) return console.error('WCA error:', err);
    console.log('Bot ready:', api.getCurrentUserID());

    api.listen(async (err, msg) => {
        if (err) return;
        if (!msg || msg.type !== 'message' || msg.fromMe) return;

        const { body, threadID } = msg;
        if (!body.startsWith('!')) return;

        const [cmd, ...args] = body.slice(1).split(' ');

        switch (cmd.toLowerCase()) {
            case 'ping':
                await api.sendMessage('🏓 Pong!', threadID);
                break;

            case 'poll':
                await api.sendPoll(threadID, 'Favourite colour?', ['Red', 'Blue', 'Green']);
                break;

            case 'gcinfo':
                if (msg.isGroup) {
                    const info = await api.getGroupInfo(threadID);
                    await api.sendMessage(
                        `*${info.name}*\nMembers: ${info.size}\nAdmins: ${info.adminIDs.length}`,
                        threadID
                    );
                }
                break;

            case 'dminfo':
                if (!msg.isGroup) {
                    const info = await api.getDMInfo(msg.senderID);
                    await api.sendMessage(
                        `Name: ${info.name || 'Unknown'}\nStatus: ${info.status || 'None'}`,
                        threadID
                    );
                }
                break;

            case 'react':
                await api.reactToMessage(threadID, msg.messageID, '👍');
                break;

            case 'reply':
                await api.sendMessage(
                    { body: 'This is a reply!', replyToMessage: msg.raw },
                    threadID
                );
                break;

            case 'image':
                await api.sendImage('https://picsum.photos/800/600', threadID, 'Test image');
                break;
        }
    });
});

📂 Project Structure

wca/
 ├── index.js              ← Main entry  wca(options, callback)
 ├── utils.js              ← JID helpers, LID resolver, event formatter
 ├── checkUpdate.js        ← Auto-update checker (runs on every startup)
 └── src/                  ← One file per feature
     ├── listenMqtt.js
     ├── sendMessage.js
     ├── sendMedia.js
     ├── sendPoll.js
     ├── editMessage.js
     ├── pinMessage.js
     ├── sendTypingIndicator.js
     ├── sendReadReceipt.js
     ├── sendLocation.js
     ├── sendPresenceUpdate.js
     ├── reactToMessage.js
     ├── deleteMessage.js
     ├── downloadMedia.js
     ├── getGroupInfo.js
     ├── getAllGroups.js
     ├── getGroupAdmins.js
     ├── getGroupInviteLink.js
     ├── groupRevokeInvite.js
     ├── groupAcceptInvite.js
     ├── groupSettingUpdate.js
     ├── addUserToGroup.js
     ├── kickUser.js
     ├── createGroup.js
     ├── leaveGroup.js
     ├── setGroupAdmin.js
     ├── changeGroupSubject.js
     ├── changeGroupDescription.js
     ├── getProfilePicture.js
     ├── getUserInfo.js
     ├── getDMInfo.js
     ├── getContacts.js
     ├── getChats.js
     ├── archiveChat.js
     ├── muteChat.js
     ├── fetchStatus.js
     ├── updateProfilePicture.js
     ├── updateProfileStatus.js
     ├── updateProfileName.js
     ├── blockContact.js
     ├── sendButtons.js
     └── getAppState.js

🧠 LID Resolution (Delta System)

WhatsApp internally uses LID (Linked Identity) JIDs — e.g. 186393124970625@lid — which are opaque internal IDs that differ from phone numbers. WCA automatically resolves these to real @s.whatsapp.net JIDs using Baileys' contact store.

  • msg.senderID → always a phone JID (628xxx@s.whatsapp.net)
  • msg.threadID → group @g.us or phone JID for DMs
  • Device suffixes (628xxx:5@s.whatsapp.net) are stripped automatically

🔗 Links

📦 NPM package @sheikhtamim/wca
🧩 WCA source github.com/sheikhtamimlover/wca
🤖 Example bot github.com/sheikhtamimlover/ST_WhatsappBot
💬 Support Group Join WCA Support GC
📸 Instagram instagram.com/sheikh.tamim_lover
📞 Contact wa.me/8801600203673

Made with ❤️ by Sheikh Tamim

GitHub Instagram WhatsApp Group

About

A lightweight, high-performance WhatsApp Bot API and framework built with Node.js. Designed for scalability, easy integration, and seamless chat automation using a modular source structure. Perfect for building custom automated services.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors