A powerful, event-driven WhatsApp bot built on @whiskeysockets/baileys with a comprehensive FCA-compatible API layer.
- Features
- Quick Start
- Authentication & Login
- Configuration
- Web Dashboard
- Project Architecture
- Development Guide
- Command Management
- Creator & Maintainer
- License
- Event-Driven Architecture: Fully modular command and event handling.
- Web Dashboard: Built-in Express & Socket.IO web interface to monitor bot status live.
- Hot Reloading: Install, load, and reload commands without restarting the bot.
- Robust Multi-Device Support: Built on the latest Baileys library for stable connection.
- Flexible Login Methods: Supports QR Code, Pair Code (Terminal), and Session ID strings.
- JSON & MongoDB Support: Integrated database system out of the box.
- Rich Messaging API: Simplified methods to send images, videos, audio, documents, and interactive messages.
- Auto-Update: Automatically checks and installs updates from GitHub on every startup.
- Whitelist Mode: Restrict bot access to specific users or threads.
Ensure you have Node.js 18+ installed.
git clone https://github.com/efkidgamerdev/WAGOAT-BOT.git
cd WAGOAT-BOT
npm install
npm startThe bot will print a Pairing Code in your terminal.
To authenticate, open WhatsApp on your phone β Linked Devices β Link a Device β Link with phone number instead β Enter the 8-digit code.
WAGOAT-BOT supports 3 login methods. Choose one based on your deployment:
| Method | Best For | How |
|---|---|---|
| π’ Pair Code | Local / Terminal | Bot prints an 8-digit code β link on WhatsApp |
| π Session ID | βοΈ Cloud (Heroku, Railway, Render) | Generate a session string β paste in config.json |
| π· QR Code | Quick local setup | Scan QR in terminal with WhatsApp |
Set
loginModeto"pair"and your phone number inconfig.json, then runnpm start.
The bot will display an 8-digit code β enter it in WhatsApp β Linked Devices β Link with phone number.
Step 1 Β· Fork & Star the repository
Step 2 Β· Generate your Session ID
Step 3 Β· Configure & Run
Paste the generated session string into the
sessionIDfield inconfig.json(or set theSESSION_IDenvironment variable), then runnpm start.
The bot will import your credentials automatically and clear the field for security.
{
"sessionID": "YOUR_SESSION_STRING_HERE",
"loginMode": "pair"
}Set
loginModeto"qr"inconfig.json, runnpm start, and scan the QR code that appears in your terminal using WhatsApp.
Control your bot's behavior by modifying config.json.
{
"prefix": ".",
"botName": "WAGoat-Bot",
"language": "en",
"adminBot": ["YOUR_WHATSAPP_ID_HERE"],
"phoneNumber": "8801XXXXXXXXX",
"loginMode": "pair",
"sessionID": "",
"authFolder": "./auth",
"database": {
"type": "json"
},
"listen": {
"selfListen": false,
"listenEvents": true
},
"featureBox": {
"adminOnly": false,
"antiInbox": false,
"unsendBotReact": true
}
}| Key | Description |
|---|---|
prefix |
The character used to trigger commands (default: /) |
adminBot |
Array of WhatsApp JIDs that have bot-admin privileges |
DEV |
Array of WhatsApp JIDs with developer-level access |
loginMode |
"pair" (pairing code) or "qr" (QR code) |
sessionID |
Paste your session string here for cloud deployments |
database.type |
"json" (local files) or "mongodb" (MongoDB URI) |
featureBox.adminOnly |
Set to true during maintenance to lock out regular users |
featureBox.whitelistMode |
Restrict bot access to whitelistUIDs only |
express.port |
Port for the web dashboard (default: 3000) |
autoUpdate.enable |
Auto-check and install GitHub updates on startup |
Pro Tip: Set
featureBox.adminOnlytotrueduring maintenance to prevent standard users from triggering commands.
WAGOAT-BOT includes a built-in, real-time web dashboard powered by Express & Socket.IO.
Once the bot starts successfully, access the dashboard at:
http://localhost:3000/dashboard (or your server's exposed port for cloud deployments).
Dashboard Features:
- π Live uptime, memory usage, and ping monitoring
- π Real-time view of loaded commands and events
- π§βπ€βπ§ Overview of total users and active threads
- β‘ Live terminal log output directly in your browser
WAGoat-Bot/
βββ Goat.js # Main entry point
βββ index.js # Process manager & auto-restart wrapper
βββ config.json # Global configuration
βββ bot/
β βββ handler/ # Event, action, and data controllers
β βββ login/ # Baileys adapter & socket logic
βββ dashboard/ # Web dashboard UI & backend
βββ database/ # Database controllers (JSON/MongoDB)
βββ scripts/
β βββ cmds/ # Command plugins (.js)
β βββ events/ # Event plugins (.js)
βββ logger/ # Console logging utilities
βββ utils.js # Helper functions
Create a new JavaScript file in scripts/cmds/.
"use strict";
module.exports = {
config: {
name: "ping",
version: "1.0.0",
author: "YourName",
countDown: 3, // Cooldown in seconds
role: 0, // 0: Everyone, 1: Group Admin, 2: Bot Admin
shortDescription: "Check bot latency",
category: "system",
guide: { en: "{pn}" } // {pn} is replaced by prefix + command name
},
onStart: async ({ api, event, args, message }) => {
return message.reply("π Pong!");
}
};| Hook | When it fires |
|---|---|
onStart |
User triggers the command with the prefix |
onChat |
Fires on every single message (no prefix needed) |
onReply |
User replies to a registered bot message |
onReaction |
User reacts to a registered bot message |
1. Register a reply listener:
const info = await message.reply("Reply with a number:");
global.GoatBot.onReply.set(info.messageID, {
commandName: "choose", // Must match your command name
author: event.senderID,
data: ["Option A", "Option B", "Option C"]
});2. Handle the reply in your command:
onReply: async ({ event, Reply, message }) => {
if (event.senderID !== Reply.author) return; // Only the original author can reply
await message.reply(`You chose: ${Reply.data[event.body - 1]}`);
}The message object simplifies interactions:
await message.reply("Standard reply");
await message.send("Send to specific thread", threadID);
await message.react("π");
await message.unsend(messageID);
await message.edit(messageID, "Edited content");Sending Media:
await message.reply({
body: "Check out this image!",
attachment: { type: "image", url: "https://example.com/photo.jpg" }
});Create a new JavaScript file in scripts/events/.
"use strict";
module.exports = {
config: {
name: "welcome",
version: "1.0.0",
author: "YourName",
category: "events"
},
onStart: async ({ api, event }) => {
if (event.logMessageType === "log:subscribe") {
for (const uid of event.participants) {
await api.sendMessage(`π Welcome!`, event.threadID);
}
}
}
};event.type |
Description |
|---|---|
message |
Regular chat message |
message_reaction |
User adds or removes a reaction |
event |
Group participant change |
group_update |
Group name or settings changed |
| Value | Trigger |
|---|---|
log:subscribe |
User(s) joined a group |
log:unsubscribe |
User(s) left or were removed |
log:thread-admins |
Admin promoted or demoted |
log:thread-name |
Group name was changed |
WAGOAT-BOT provides a robust api object (a wrapper around Baileys) to interact with WhatsApp.
Click to expand API methods
Messaging
api.sendMessage(content, threadID, options)api.sendImage(buffer, threadID, caption, options)api.sendVideo(buffer, threadID, caption, options)api.sendAudio(buffer, threadID, options)api.sendPTT(buffer, threadID, options)api.sendDocument(buffer, threadID, fileName, options)api.sendSticker(buffer, threadID, options)api.sendGif(buffer, threadID, caption, options)api.sendMedia(buffer, threadID, type, caption, options)api.sendLocation(threadID, latitude, longitude, options)api.sendPoll(threadID, question, options)api.sendButtons(threadID, text, buttons, options)api.sendList(threadID, title, buttonText, sections, options)api.sendTemplate(threadID, text, templateButtons, options)
Message Actions
api.reactToMessage(threadID, key, emoji)api.deleteMessage(threadID, key, forEveryone)api.editMessage(threadID, messageID, newText)api.pinMessage(threadID, messageID, duration)api.unpinMessage(threadID, messageID)api.updateMediaMessage(msgObj)api.downloadMedia(msgObj)
Group Management
api.getGroupInfo(threadID)api.getGroupInviteLink(threadID)api.groupRevokeInvite(threadID)api.groupAcceptInvite(code)api.groupSettingUpdate(threadID, setting, value)api.kickUser(threadID, jids)api.promoteAdmin(threadID, jids)api.demoteAdmin(threadID, jids)api.getGroupAdmins(threadID)api.createGroup(title, participants)api.leaveGroup(threadID)api.getAllGroups()api.addUserToGroup(threadID, jid)api.removeUserFromGroup(threadID, jid)api.changeGroupSubject(threadID, subject)api.changeGroupDescription(threadID, description)
User & Profile
api.getCurrentUserID()api.getUserInfo(jid)api.getDMInfo(jid)api.getContacts()api.getChats()api.getProfilePicture(jid)api.updateProfilePicture(buffer)api.updateProfileStatus(status)api.updateProfileName(name)api.fetchStatus(jid)
Presence & Receipts
api.sendTypingIndicator(threadID, duration)api.sendPresenceUpdate(jid, presence)api.sendReadReceipt(threadID, participant, messageIds)api.markAsRead(threadID, participant, messageIds)
Chat Moderation
api.muteChat(threadID, duration)api.unmuteChat(threadID)api.archiveChat(threadID, archive)api.unarchiveChat(threadID)api.pinChat(threadID, pin)api.blockContact(jid)api.unblockContact(jid)
Manage commands and events on-the-fly using the built-in cmd and event plugins. (Bot Admin only)
| Usage | Description |
|---|---|
!cmd install <file.js> <url> |
Download & install a command from a raw URL |
!cmd loadall |
Hot reload every command in the scripts/cmds/ folder |
!cmd load <name> |
Enable a single command |
!cmd unload <name> |
Disable a command |
!cmd reload <name> |
Refresh a command to apply code changes |
- Romeo Calyx β Lead Developer & Maintainer
- efkidgamerdev β Co-Developer
Distributed under the MIT License. Originally based on the work of Sheikh Tamim, modified and extended by the WAGOAT-BOT Team.
