Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
don't fork without giving credit 😊😊😊

## WhatsApp bot additions

Added Node.js bot scaffolding to help with Baileys pairing and group-status flow:

- `package.json` includes Baileys `@whiskeysockets/baileys@7.0.0-rc.9` and related dependencies.
- `src/commands/owner/pair.js` provides owner-only pair-code generation with formatted instructions.
- `src/commands/admin/togcstatus.js` ports your `groupstatus/togstatus/gstatus` case into command-module style.

> Wire these files to your command loader if it expects a different exported function name/signature.
45 changes: 45 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "terry-whatsapp-bot",
"version": "1.0.0",
"private": true,
"description": "WhatsApp bot dependencies and command handlers",
"main": "index.js",
"type": "commonjs",
"scripts": {
"lint": "eslint .",
"format": "prettier --write ."
},
"dependencies": {
"@ffmpeg-installer/ffmpeg": "1.1.0",
"@whiskeysockets/baileys": "7.0.0-rc.9",
"archiver": "7.0.1",
"awesome-phonenumber": "2.73.0",
"axios": "1.13.6",
"axios-cookiejar-support": "6.0.5",
"better-sqlite3": "12.6.0",
"chalk": "5.6.2",
"cheerio": "1.2.0",
"cloudinary": "2.9.0",
"crypto-js": "4.2.0",
"file-type": "17.1.6",
"fluent-ffmpeg": "2.1.3",
"gif-encoder-2": "1.0.5",
"javascript-obfuscator": "5.3.0",
"jszip": "3.10.1",
"moment-timezone": "0.5.48",
"node-fetch": "3.3.2",
"node-webpmux": "3.2.1",
"puppeteer-extra": "3.3.6",
"puppeteer-extra-plugin-stealth": "2.11.2",
"qrcode": "1.5.4",
"syntax-error": "1.4.0",
"web-scraper": "1.0.10",
"yt-search": "2.13.1"
},
"devDependencies": {
"@eslint/js": "9.39.2",
"eslint": "9.39.2",
"globals": "16.5.0",
"prettier": "3.8.0"
}
}
114 changes: 114 additions & 0 deletions src/commands/admin/togcstatus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* Admin command: post group status (text or quoted media)
* Aliases: groupstatus, togstatus, gstatus
*/
module.exports = {
name: 'togcstatus',
aliases: ['groupstatus', 'togstatus', 'gstatus'],
category: 'admin',
description: 'Post text or quoted media as a group status update.',
groupOnly: true,
adminOnly: true,

/**
* @param {object} ctx
* @param {import('@whiskeysockets/baileys').WASocket} ctx.sock
* @param {object} ctx.m
* @param {string[]} [ctx.args]
* @param {string} [ctx.text]
* @param {string} [ctx.prefix]
* @param {string} [ctx.command]
* @param {(msg:string)=>any} ctx.reply
*/
async execute({ sock, m, args = [], text = '', prefix = '.', command = 'gstatus', reply }) {
if (!m?.isGroup) {
return reply('👥 *Group Status*\n\nThis command can only be used in groups.');
}

const quoted = m?.quoted;
const content = (text || args.join(' ') || '').trim();

if (!quoted && !content) {
return reply(
[
'📢 *Group Status*',
'',
'Reply to an image/video/audio, or provide text to post as group status.',
`Example: ${prefix}${command} Hello group!`
].join('\n')
);
}

try {
await sock.sendMessage(m.chat, { react: { text: '📢', key: m.key } });

if (!quoted && content) {
await sock.sendMessage(m.chat, {
groupStatusMessageV2: {
message: {
extendedTextMessage: {
text: content,
backgroundArgb: 0xff000000,
textArgb: 0xffffffff,
font: 1,
contextInfo: {
mentionedJid: [],
isGroupStatus: true
}
}
}
}
});

await sock.sendMessage(m.chat, { react: { text: '✅', key: m.key } });
return reply('📢 *Group Status*\n\nText status posted!');
}

const mime = quoted?.mimetype || quoted?.msg?.mimetype || '';

if (/image/i.test(mime)) {
const media = await quoted.download();
await sock.sendMessage(m.chat, {
image: media,
caption: content || '',
contextInfo: { isGroupStatus: true }
});
} else if (/video/i.test(mime)) {
const media = await quoted.download();
await sock.sendMessage(m.chat, {
video: media,
caption: content || '',
contextInfo: { isGroupStatus: true }
});
} else if (/audio/i.test(mime)) {
const media = await quoted.download();
await sock.sendMessage(m.chat, {
audio: media,
mimetype: mime || 'audio/mpeg',
ptt: false,
contextInfo: { isGroupStatus: true }
});
} else {
await sock.sendMessage(m.chat, {
groupStatusMessageV2: {
message: {
extendedTextMessage: {
text: quoted?.text || content || '',
backgroundArgb: 0xff000000,
textArgb: 0xffffffff,
font: 1,
contextInfo: { isGroupStatus: true }
}
}
}
});
}

await sock.sendMessage(m.chat, { react: { text: '✅', key: m.key } });
return reply('📢 *Group Status*\n\nStatus posted successfully.');
} catch (error) {
await sock.sendMessage(m.chat, { react: { text: '❌', key: m.key } });
return reply(`❌ *Group Status Error:* ${error.message || error}`);
}
}
};
65 changes: 65 additions & 0 deletions src/commands/owner/pair.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Owner command: generate WhatsApp pair code
*/
module.exports = {
name: 'pair',
aliases: ['paircode', 'linkdevice'],
category: 'owner',
description: 'Generate a WhatsApp pairing code for a phone number.',
ownerOnly: true,

/**
* @param {object} ctx
* @param {import('@whiskeysockets/baileys').WASocket} ctx.sock
* @param {string[]} [ctx.args]
* @param {boolean} [ctx.isOwner]
* @param {string} [ctx.prefix]
* @param {string} [ctx.command]
* @param {(msg:string)=>any} ctx.reply
*/
async execute({ sock, args = [], isOwner, prefix = '.', command = 'pair', reply }) {
if (!isOwner) {
return reply('👑 This command is only for bot owner!');
}

if (!sock || typeof sock.requestPairingCode !== 'function') {
return reply('❌ Pairing not enabled. Start Baileys with usePairingCode: true.');
}

const phone = args.join('').replace(/[^\d]/g, '');

if (!phone || phone.length < 10) {
return reply(
[
'📱 *Pair Device*',
'',
`Use: ${prefix}${command} 2348012345678`,
'Use your full international number (without + or spaces).'
].join('\n')
);
}

try {
const rawCode = await sock.requestPairingCode(phone);
const pairCode = rawCode?.match(/.{1,4}/g)?.join('-') || rawCode;

return reply(
[
'🔷 *Pair Code:*',
pairCode,
'',
'🔷 *How to Link:*',
'1. Open WhatsApp on your phone.',
'2. Go to Settings > Linked Devices.',
'3. Tap Link a Device then Link with phone number.',
'4. Enter the pair code above.',
'5. Or tap the WhatsApp notification sent to your phone.',
'',
'⏳ Code expires in ~2 minutes.'
].join('\n')
);
} catch (error) {
return reply(`❌ Failed to generate pair code: ${error.message || error}`);
}
}
};