Skip to content

Instantly share code, notes, and snippets.

@ZTRdiamond
Created October 19, 2025 11:08
Show Gist options
  • Select an option

  • Save ZTRdiamond/5cc2a28df784f42d875a398ce161c748 to your computer and use it in GitHub Desktop.

Select an option

Save ZTRdiamond/5cc2a28df784f42d875a398ce161c748 to your computer and use it in GitHub Desktop.
Baileys Shard example usage.
import makeWASocket, { useMultiFileAuthState, DisconnectReason } from "baileys";
import { ShardManager } from "baileys-shard";
import { Boom } from "@hapi/boom";
import Pino from "pino";
console.log(await import("baileys-shard"))
const manager = new ShardManager();
function parseArgs(input = "") {
const args = (input || "").match(/--\w+(?:[= ](?:[^\s"']+|".+?"|'.+?'))?/g) || [];
const result = {};
const argRegex = /--(\w+)(?:[= ]((?:[^\s"']+)|(?:"[^"]*")|(?:'[^']*')))?/;
args.forEach(arg => {
const match = arg.match(argRegex);
if (match) {
const key = match[1];
let value = match[2];
if (value == undefined) {
result[key] = true; // flag tanpa nilai
} else if (/^["']/.test(value)) {
value = value.slice(1, -1); // hapus tanda kutip di sekitar nilai
}
result[key] = value;
}
});
return result;
}
let timeout = 0;
const logger = Pino(
{
level: "info",
formatters: {
level(label) {
return { level: label };
},
},
timestamp: () => `,"time":"${new Date().toISOString()}"`,
base: { pid: false, hostname: false },
},
Pino.destination("./baileys-logs.txt")
);
manager.on("messages.upsert", async({ shardId, sock, data }) => {
const m = data.messages[0]
if(!m) return;
const sender = m?.key?.remoteJid;
const body = m?.message?.conversation;
if(body && body.startsWith(".sayhi")) {
return sock.sendMessage(sender, {
text: `Hello, from ${shardId}`
})
} else return;
})
async function start() {
const { state, saveCreds } = await useMultiFileAuthState("./session");
const sock = makeWASocket({
printQRInTerminal: false,
logger,
auth: state
});
// pairing jika belum registered
if (!sock.authState.creds.registered) {
const botNumber = "628xxx" // phone number
console.log("Request new session:");
console.log("> Bot Number:", botNumber);
setTimeout(async function () {
const pairingCode = await sock.requestPairingCode(botNumber);
console.log("> Pairing Code:", pairingCode);
}, 5000);
}
// update creds
sock.ev.on("creds.update", saveCreds);
// update koneksi
sock.ev.on("connection.update", async (update) => {
const { lastDisconnect, connection } = update;
if (connection) {
console.log(`[Session] Connecting session... (${connection})`);
}
if (connection == "close") {
const closeReason = new Boom(lastDisconnect?.error)?.output?.statusCode;
switch (closeReason) {
case DisconnectReason.badSession:
console.log("[Session] Bad session file, delete old session and login again.");
break;
case DisconnectReason.connectionClosed:
timeout++;
console.log("[Session] Connection closed, Reconnecting...");
await start();
break;
case DisconnectReason.connectionLost:
timeout++;
console.log("[Session] Connection lost, Reconnecting...");
await start();
break;
case DisconnectReason.connectionReplaced:
console.log("[Session] Connection replaced, please logout from other device.");
break;
case DisconnectReason.loggedOut:
console.log("[Session] Logged out, please login again.");
break;
case DisconnectReason.restartRequired:
timeout++;
console.log("[Session] Restart required, reconnecting...");
await start();
break;
case DisconnectReason.connectionTimedOut:
timeout++;
console.log("[Session] Connection timeout, reconnecting...");
await start();
break;
case DisconnectReason.multideviceMismatch:
console.log("[Session] Multi device mismatch, please login again.");
break;
default:
timeout++;
console.log("[Session] Unknown disconnect reason, reconnecting...");
await start();
}
if (timeout > 10) {
console.log("[Session] Stopped after 10 retries.");
process.exit(1);
}
}
if (connection == "open") {
console.log("[Session] sock connected on:", (sock?.user?.id.split(":")[0] || global.botNumber));
}
});
sock.ev.on("messages.upsert", async(raw) => {
const m = raw.messages[0];
if(!m) return;
const sender = m?.key?.remoteJid;
const body = m?.message?.conversation || null;
if (!body || !body.startsWith('/')) return; // Hanya proses command dengan prefix /
const args = parseArgs(body);
const botId = args.id;
const command = body.split(' ')[0].replace("/", ""); // Hapus prefix / dan ambil command
console.log("debug:", command, args)
if (command == 'new') {
const botNumber = args.number;
if (!botId || !botNumber) {
sock.sendMessage(sender, {
text: `❌ Usage: /new --id=shardId --number=phoneNumber`
});
return;
}
try {
manager.createShard({
id: botId,
phoneNumber: botNumber
});
manager.on("login.update", async({ shardId, state, type, code, image }) => {
if (state == "connecting") {
if (type == "qr") {
sock.sendMessage(sender, {
caption: "Scan this QR image to login device!",
image
});
} else if (type == "pairing") {
sock.sendMessage(sender, {
text: `Pairing code ${shardId}: ${code}`
});
}
} else if (state == "connected") {
sock.sendMessage(sender, {
text: `βœ… ${shardId} successfully connected`
});
} else if (state == "disconnected") {
sock.sendMessage(sender, {
text: `⚠️ ${shardId} disconnected, will reconnect...`
});
} else if (state == "logged_out") {
sock.sendMessage(sender, {
text: `❌ ${shardId} logged out, session cleared`
});
} else if (state == "creds_saved") {
sock.sendMessage(sender, {
text: `πŸ’Ύ Credentials ${shardId} saved`
});
}
});
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Failed to create shard: ${error.message}`
});
}
}
else if (command == 'stop') {
if (!botId) {
sock.sendMessage(sender, {
text: `❌ Usage: /stop --id=shardId`
});
return;
}
try {
const stopStatus = await manager.stopShard(botId);
sock.sendMessage(sender, {
text: `πŸ›‘ Shard ${botId} stopped successfully!`
});
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Failed to stop shard ${botId}: ${error.message}`
});
}
}
else if (command == 'socket') {
if (!botId) {
sock.sendMessage(sender, {
text: `❌ Usage: /socket --id=shardId`
});
return;
}
const shardSocket = manager.socket(botId);
if (shardSocket) {
const socketInfo = `πŸ“± *Socket Info for ${botId}:*\n\n` +
`User ID: ${shardSocket?.user?.id || 'N/A'}\n` +
`User Name: ${shardSocket?.user?.name || 'N/A'}\n` +
`Connection State: ${shardSocket?.ws?.readyState == 1 ? 'Connected' : 'Disconnected'}\n` +
`Auth Registered: ${shardSocket?.authState?.creds?.registered ? 'βœ…' : '❌'}`;
sock.sendMessage(sender, { text: socketInfo });
} else {
sock.sendMessage(sender, {
text: `❌ Socket not found for shard ${botId}`
});
}
}
else if (command == 'info') {
if (!botId) {
sock.sendMessage(sender, {
text: `❌ Usage: /info --id=shardId`
});
return;
}
const shardInfo = manager.getShardInfo(botId);
if (shardInfo) {
const infoText = `ℹ️ *Shard Info: ${botId}*\n\n` +
`ID: ${shardInfo.id}\n` +
`Index: ${shardInfo.index}\n` +
`Total Shards: ${shardInfo.total}\n` +
`Phone Number: ${shardInfo.phoneNumber || 'N/A'}\n` +
`Status: ${shardInfo.status}\n` +
`Created: ${shardInfo.createdAt || 'N/A'}\n` +
`Last Update: ${shardInfo.updatedAt || 'N/A'}`;
sock.sendMessage(sender, { text: infoText });
} else {
sock.sendMessage(sender, {
text: `❌ Shard info not found for ${botId}`
});
}
}
else if (command == 'listall') {
const allShardInfo = manager.getAllShardInfo();
if (allShardInfo.length == 0) {
sock.sendMessage(sender, {
text: `πŸ“‹ No active shards found.`
});
} else {
let listText = `πŸ“‹ *All Active Shards (${allShardInfo.length}):*\n\n`;
allShardInfo.forEach((shard, index) => {
listText += `*${index + 1}. ${shard.id}*\n`;
listText += ` Status: ${shard.status}\n`;
listText += ` Phone: ${shard.phoneNumber || 'N/A'}\n`;
listText += ` Index: ${shard.index}/${shard.total}\n\n`;
});
sock.sendMessage(sender, { text: listText });
}
}
else if (command == 'connect') {
if (!botId) {
sock.sendMessage(sender, {
text: `❌ Usage: /connect --id=shardId`
});
return;
}
try {
const connectResult = await manager.connect(botId);
sock.sendMessage(sender, {
text: `πŸ”Œ Attempting to connect shard ${connectResult.id}...`
});
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Failed to connect shard ${botId}: ${error.message}`
});
}
}
else if (command == 'recreate') {
const clearSession = args.clear == 'true';
const forceRecreate = args.force == 'true';
if (!botId) {
sock.sendMessage(sender, {
text: `❌ Usage: /recreate --id=shardId [--clear=true] [--force=true]`
});
return;
}
try {
const recreateResult = await manager.recreateShard({
id: botId,
clearSession,
forceRecreate
});
sock.sendMessage(sender, {
text: `♻️ Shard ${recreateResult.id} recreated successfully!\n` +
`Clear Session: ${clearSession ? 'βœ…' : '❌'}\n` +
`Force Recreate: ${forceRecreate ? 'βœ…' : '❌'}`
});
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Failed to recreate shard ${botId}: ${error.message}`
});
}
}
else if (command == 'session') {
if (!botId) {
sock.sendMessage(sender, {
text: `❌ Usage: /session --id=shardId`
});
return;
}
try {
const sessionInfo = await manager.getSessionInfo(botId);
const sessionText = `πŸ’Ύ *Session Info for ${botId}:*\n\n` +
`Exists: ${sessionInfo.exists ? 'βœ…' : '❌'}\n` +
`Registered: ${sessionInfo.registered ? 'βœ…' : '❌'}\n` +
`Valid: ${sessionInfo.valid ? 'βœ…' : '❌'}\n` +
`Reason: ${sessionInfo.reason || 'N/A'}`;
sock.sendMessage(sender, { text: sessionText });
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Failed to get session info for ${botId}: ${error.message}`
});
}
}
else if (command == 'loadall') {
try {
sock.sendMessage(sender, {
text: `πŸ”„ Loading all existing sessions...`
});
const loadedIds = await manager.loadAllShards();
if (loadedIds.length == 0) {
sock.sendMessage(sender, {
text: `❌ No sessions were loaded.`
});
} else {
let loadText = `βœ… *Loaded ${loadedIds.length} sessions:*\n\n`;
loadedIds.forEach((id, index) => {
loadText += `${index + 1}. ${id}\n`;
});
sock.sendMessage(sender, { text: loadText });
}
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Failed to load sessions: ${error.message}`
});
}
}
else if (command == 'cleanup') {
try {
sock.sendMessage(sender, {
text: `🧹 Starting session cleanup...`
});
await manager.cleanupCorruptSessions();
sock.sendMessage(sender, {
text: `βœ… Session cleanup completed!`
});
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Cleanup failed: ${error.message}`
});
}
}
else if (command == 'send') {
const targetJid = args.to;
const message = args.message;
if (!botId || !targetJid || !message) {
sock.sendMessage(sender, {
text: `❌ Usage: /send --id=shardId --to=targetNumber --message="your message"`
});
return;
}
try {
const shardSocket = manager.socket(botId);
if (!shardSocket) {
throw new Error(`Shard ${botId} not found`);
}
await shardSocket.sendMessage(targetJid + "@s.whatsapp.net", { text: message });
sock.sendMessage(sender, {
text: `βœ… Message sent from shard ${botId} to ${targetJid}`
});
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Failed to send message from ${botId}: ${error.message}`
});
}
}
else if (command == 'events') {
if (!botId) {
sock.sendMessage(sender, {
text: `❌ Usage: /events --id=shardId`
});
return;
}
try {
const shardEmitter = manager.shard(botId);
if (shardEmitter) {
let eventCount = 0;
const eventTypes = [];
const tempListener = (event, payload) => {
if (!eventTypes.includes(event)) {
eventTypes.push(event);
}
eventCount++;
};
manager.onAny(tempListener);
setTimeout(() => {
const eventText = `πŸ“‘ *Events for Shard ${botId}:*\n\n` +
`Total Events (30s): ${eventCount}\n` +
`Event Types: ${eventTypes.join(', ') || 'None'}\n\n` +
`Available Events:\n` +
`β€’ messages.upsert\nβ€’ connection.update\nβ€’ creds.update\n` +
`β€’ chats.upsert\nβ€’ contacts.upsert\nβ€’ groups.upsert`;
sock.sendMessage(sender, { text: eventText });
}, 30000);
sock.sendMessage(sender, {
text: `πŸ“Š Monitoring events for shard ${botId} for 30 seconds...`
});
} else {
sock.sendMessage(sender, {
text: `❌ Event emitter not found for shard ${botId}`
});
}
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Failed to get events for ${botId}: ${error.message}`
});
}
}
else if (command == 'health') {
try {
const allShards = manager.getAllShardInfo();
let healthyCount = 0;
let connectedCount = 0;
let disconnectedCount = 0;
let errorCount = 0;
for (const shard of allShards) {
const sessionInfo = await manager.getSessionInfo(shard.id);
if (sessionInfo.valid && shard.status == 'connected') {
healthyCount++;
connectedCount++;
} else if (shard.status == 'disconnected') {
disconnectedCount++;
} else {
errorCount++;
}
}
const healthText = `πŸ₯ *Shard Health Report:*\n\n` +
`Total Shards: ${allShards.length}\n` +
`Healthy & Connected: ${healthyCount} βœ…\n` +
`Disconnected: ${disconnectedCount} ⚠️\n` +
`Errors/Issues: ${errorCount} ❌\n\n` +
`Overall Health: ${healthyCount == allShards.length ? 'Perfect' :
healthyCount >= (allShards.length * 0.8) ? 'Good' :
healthyCount >= (allShards.length * 0.5) ? 'Fair' : 'Poor'}`;
sock.sendMessage(sender, { text: healthText });
} catch (error) {
sock.sendMessage(sender, {
text: `❌ Health check failed: ${error.message}`
});
}
}
else if (command == 'help') {
const helpText = `πŸ€– *Shard Manager Commands:*\n\n` +
`*Basic Management:*\n` +
`β€’ /new --id=botId --number=phoneNumber - Create new shard\n` +
`β€’ /stop --id=botId - Stop shard\n` +
`β€’ /connect --id=botId - Connect/reconnect shard\n` +
`β€’ /recreate --id=botId [--clear=true] [--force=true] - Recreate shard\n\n` +
`*Information & Status:*\n` +
`β€’ /info --id=botId - Get shard information\n` +
`β€’ /session --id=botId - Get session status\n` +
`β€’ /socket --id=botId - Get socket information\n` +
`β€’ /listall - List all active shards\n\n` +
`*Session Management:*\n` +
`β€’ /loadall - Load all existing sessions\n` +
`β€’ /cleanup - Clean up corrupt sessions\n` +
`β€’ /health - Overall health check\n\n` +
`*Messaging & Events:*\n` +
`β€’ /send --id=botId --to=target --message="text" - Send message\n` +
`β€’ /events --id=botId - Monitor shard events\n\n` +
`β€’ /help - Show this help message`;
sock.sendMessage(sender, { text: helpText });
}
else {
// Command tidak dikenali
sock.sendMessage(sender, {
text: `❌ Command "${command}" not recognized. Type /help for available commands.`
});
}
});
return sock;
}
start();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment