├── lib
├── lib
├── ltmp
├── owner.json
├── messageConfig.js
├── isBanned.js
├── isOwner.js
├── antilinkHelper.js
├── isAdmin.js
├── tictactoe.js
├── converter.js
├── antilink.js
├── uploadImage.js
├── uploader.js
├── reactions.js
├── lightweight_store.js
├── welcome.js
└── myfunc2.js
├── data
├── banned.json
├── data
├── dtmp
├── warnings.json
├── autoStatus.json
├── autoread.json
├── owner.json
├── premium.json
├── antidelete.json
├── autotyping.json
├── messageCount.json
└── userGroupData.json
├── commands
├── commands
├── tempc
├── unmute.js
├── owner.js
├── fact.js
├── joke.js
├── clear.js
├── goodbye.js
├── welcome.js
├── eightball.js
├── quote.js
├── roseday.js
├── dare.js
├── weather.js
├── truth.js
├── flirt.js
├── news.js
├── goodnight.js
├── warnings.js
├── tts.js
├── antibadword.js
├── github.js
├── shayari.js
├── ship.js
├── gif.js
├── meme.js
├── attp.js
├── viewonce.js
├── resetlink.js
├── botsong.js
├── ping.js
├── tagall.js
├── staff.js
├── anticall.js
├── lyrics.js
├── trivia.js
├── simage-alt.js
├── groupinfo.js
├── ban.js
├── mute.js
├── stupid.js
├── topmembers.js
├── unban.js
├── pies.js
├── hangman.js
├── simage.js
├── wasted.js
├── ss.js
├── play.js
├── getpp.js
├── simp.js
├── alive.js
├── kick.js
├── sticker-alt.js
├── setpp.js
├── imagine.js
├── sudo.js
├── img-blur.js
├── take.js
├── clearsession.js
├── character.js
├── promote.js
├── tag.js
├── compliment.js
├── cleartmp.js
├── emojimix.js
├── insult.js
├── ai.js
├── translate.js
├── removebg.js
├── delete.js
├── remini.js
├── facebook.js
├── instagram.js
├── pair.js
└── textmaker.js
├── session
└── upload creds file here
├── .gitignore
├── assets
├── bot_image.jpg
├── sticktag.webp
└── stickintro.webp
├── settings.js
├── config.js
├── package.json
└── README.md
/lib/lib:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/lib/ltmp:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/data/banned.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/data/data:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/data/dtmp:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/commands/commands:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/commands/tempc:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/data/warnings.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/lib/owner.json:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/session/upload creds file here:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/autoStatus.json:
--------------------------------------------------------------------------------
1 | {"enabled":false}
--------------------------------------------------------------------------------
/data/autoread.json:
--------------------------------------------------------------------------------
1 | {
2 | "enabled": false
3 | }
--------------------------------------------------------------------------------
/data/owner.json:
--------------------------------------------------------------------------------
1 | ["263780145644","263710407389"]
--------------------------------------------------------------------------------
/data/premium.json:
--------------------------------------------------------------------------------
1 | ["263780145644","263710407389"]
--------------------------------------------------------------------------------
/data/antidelete.json:
--------------------------------------------------------------------------------
1 | {
2 | "enabled": false
3 | }
--------------------------------------------------------------------------------
/data/autotyping.json:
--------------------------------------------------------------------------------
1 | {
2 | "enabled": false
3 | }
--------------------------------------------------------------------------------
/data/messageCount.json:
--------------------------------------------------------------------------------
1 | {
2 | "isPublic": true,
3 | "messageCount": {}
4 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNOWBIRD0074/Lady-Bella-v3/HEAD/.gitignore
--------------------------------------------------------------------------------
/assets/bot_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNOWBIRD0074/Lady-Bella-v3/HEAD/assets/bot_image.jpg
--------------------------------------------------------------------------------
/assets/sticktag.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNOWBIRD0074/Lady-Bella-v3/HEAD/assets/sticktag.webp
--------------------------------------------------------------------------------
/assets/stickintro.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNOWBIRD0074/Lady-Bella-v3/HEAD/assets/stickintro.webp
--------------------------------------------------------------------------------
/data/userGroupData.json:
--------------------------------------------------------------------------------
1 | {
2 | "users": [],
3 | "groups": [],
4 | "antilink": {},
5 | "antibadword": {},
6 | "warnings": {},
7 | "sudo": [],
8 | "welcome": {},
9 | "goodbye": {},
10 | "chatbot": {},
11 | "autoReaction": false
12 | }
--------------------------------------------------------------------------------
/commands/unmute.js:
--------------------------------------------------------------------------------
1 | async function unmuteCommand(sock, chatId) {
2 | await sock.groupSettingUpdate(chatId, 'not_announcement'); // Unmute the group
3 | await sock.sendMessage(chatId, { text: 'The group has been unmuted.' });
4 | }
5 |
6 | module.exports = unmuteCommand;
7 |
--------------------------------------------------------------------------------
/lib/messageConfig.js:
--------------------------------------------------------------------------------
1 | const channelInfo = {
2 | contextInfo: {
3 | forwardingScore: 999,
4 | isForwarded: true,
5 | forwardedNewsletterMessageInfo: {
6 | newsletterJid: '120363399707841760@newsletter',
7 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
8 | serverMessageId: -1,
9 | }
10 | }
11 | };
12 |
13 | module.exports = {
14 | channelInfo
15 | };;
16 |
--------------------------------------------------------------------------------
/lib/isBanned.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 |
3 | function isBanned(userId) {
4 | try {
5 | const bannedUsers = JSON.parse(fs.readFileSync('./data/banned.json', 'utf8'));
6 | return bannedUsers.includes(userId);
7 | } catch (error) {
8 | console.error('Error checking banned status:', error);
9 | return false;
10 | }
11 | }
12 |
13 | module.exports = { isBanned };
--------------------------------------------------------------------------------
/lib/isOwner.js:
--------------------------------------------------------------------------------
1 | const settings = require('../settings');
2 | const { isSudo } = require('./index');
3 |
4 | async function isOwnerOrSudo(senderId) {
5 | // Get owner number from settings
6 | const ownerJid = settings.ownerNumber + "@s.whatsapp.net";
7 | if (senderId === ownerJid) return true;
8 | try {
9 | return await isSudo(senderId);
10 | } catch (e) {
11 | return false;
12 | }
13 | }
14 |
15 | module.exports = isOwnerOrSudo;
--------------------------------------------------------------------------------
/commands/owner.js:
--------------------------------------------------------------------------------
1 | const settings = require('../settings');
2 |
3 | async function ownerCommand(sock, chatId) {
4 | const vcard = `
5 | BEGIN:VCARD
6 | VERSION:3.0
7 | FN:${settings.botOwner}
8 | TEL;waid=${settings.ownerNumber}:${settings.ownerNumber}
9 | END:VCARD
10 | `;
11 |
12 | await sock.sendMessage(chatId, {
13 | contacts: { displayName: settings.botOwner, contacts: [{ vcard }] },
14 | });
15 | }
16 |
17 | module.exports = ownerCommand;
18 |
--------------------------------------------------------------------------------
/commands/fact.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 |
3 | module.exports = async function (sock, chatId, message) {
4 | try {
5 | const response = await axios.get('https://uselessfacts.jsph.pl/random.json?language=en');
6 | const fact = response.data.text;
7 | await sock.sendMessage(chatId, { text: fact },{ quoted: message });
8 | } catch (error) {
9 | console.error('Error fetching fact:', error);
10 | await sock.sendMessage(chatId, { text: 'Sorry, I could not fetch a fact right now.' },{ quoted: message });
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/commands/joke.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 |
3 | module.exports = async function (sock, chatId) {
4 | try {
5 | const response = await axios.get('https://icanhazdadjoke.com/', {
6 | headers: { Accept: 'application/json' }
7 | });
8 | const joke = response.data.joke;
9 | await sock.sendMessage(chatId, { text: joke });
10 | } catch (error) {
11 | console.error('Error fetching joke:', error);
12 | await sock.sendMessage(chatId, { text: 'Sorry, I could not fetch a joke right now.' });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/commands/clear.js:
--------------------------------------------------------------------------------
1 | async function clearCommand(sock, chatId) {
2 | try {
3 | const message = await sock.sendMessage(chatId, { text: 'Clearing bot messages...' });
4 | const messageKey = message.key; // Get the key of the message the bot just sent
5 |
6 | // Now delete the bot's message
7 | await sock.sendMessage(chatId, { delete: messageKey });
8 |
9 | } catch (error) {
10 | console.error('Error clearing messages:', error);
11 | await sock.sendMessage(chatId, { text: 'An error occurred while clearing messages.' });
12 | }
13 | }
14 |
15 | module.exports = { clearCommand };
16 |
--------------------------------------------------------------------------------
/settings.js:
--------------------------------------------------------------------------------
1 | const settings = {
2 | packname: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
3 | author: '',
4 | botName: "ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3",
5 | botOwner: 'sɴᴏᴡʙɪʀᴅ', // Your name
6 | ownerNumber: '263780145644', //Set your number here without + symbol, just add country code & number without any space
7 | giphyApiKey: 'qnl7ssQChTdPjsKta2Ax2LMaGXz303tq',
8 | commandMode: "public",
9 | maxStoreMessages: 20,
10 | storeWriteInterval: 10000,
11 | description: "This is a bot for managing group commands and automating tasks.",
12 | version: "3.0.0",
13 | updateZipUrl: "https://github.com/SNOWBIRD0074/Lady-Bella2/archive/refs/heads/main.zip",
14 | };
15 |
16 | module.exports = settings;
17 |
--------------------------------------------------------------------------------
/commands/goodbye.js:
--------------------------------------------------------------------------------
1 | const { handleGoodbye } = require('../lib/welcome');
2 |
3 | async function goodbyeCommand(sock, chatId, message, match) {
4 | // Check if it's a group
5 | if (!chatId.endsWith('@g.us')) {
6 | await sock.sendMessage(chatId, { text: 'This command can only be used in groups.' });
7 | return;
8 | }
9 |
10 | // Extract match from message
11 | const text = message.message?.conversation ||
12 | message.message?.extendedTextMessage?.text || '';
13 | const matchText = text.split(' ').slice(1).join(' ');
14 |
15 | await handleGoodbye(sock, chatId, message, matchText);
16 | }
17 |
18 | module.exports = goodbyeCommand;
19 |
--------------------------------------------------------------------------------
/commands/welcome.js:
--------------------------------------------------------------------------------
1 | const { handleWelcome } = require('../lib/welcome');
2 |
3 | async function welcomeCommand(sock, chatId, message, match) {
4 | // Check if it's a group
5 | if (!chatId.endsWith('@g.us')) {
6 | await sock.sendMessage(chatId, { text: 'This command can only be used in groups.' });
7 | return;
8 | }
9 |
10 | // Extract match from message
11 | const text = message.message?.conversation ||
12 | message.message?.extendedTextMessage?.text || '';
13 | const matchText = text.split(' ').slice(1).join(' ');
14 |
15 | await handleWelcome(sock, chatId, message, matchText);
16 | }
17 |
18 | module.exports = welcomeCommand;
19 |
--------------------------------------------------------------------------------
/commands/eightball.js:
--------------------------------------------------------------------------------
1 | const eightBallResponses = [
2 | "Yes, definitely!",
3 | "No way!",
4 | "Ask again later.",
5 | "It is certain.",
6 | "Very doubtful.",
7 | "Without a doubt.",
8 | "My reply is no.",
9 | "Signs point to yes."
10 | ];
11 |
12 | async function eightBallCommand(sock, chatId, question) {
13 | if (!question) {
14 | await sock.sendMessage(chatId, { text: 'Please ask a question!' });
15 | return;
16 | }
17 |
18 | const randomResponse = eightBallResponses[Math.floor(Math.random() * eightBallResponses.length)];
19 | await sock.sendMessage(chatId, { text: `🎱 ${randomResponse}` });
20 | }
21 |
22 | module.exports = { eightBallCommand };
23 |
--------------------------------------------------------------------------------
/commands/quote.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | module.exports = async function quoteCommand(sock, chatId, message) {
4 | try {
5 | const shizokeys = 'shizo';
6 | const res = await fetch(`https://shizoapi.onrender.com/api/texts/quotes?apikey=${shizokeys}`);
7 |
8 | if (!res.ok) {
9 | throw await res.text();
10 | }
11 |
12 | const json = await res.json();
13 | const quoteMessage = json.result;
14 |
15 | // Send the quote message
16 | await sock.sendMessage(chatId, { text: quoteMessage }, { quoted: message });
17 | } catch (error) {
18 | console.error('Error in quote command:', error);
19 | await sock.sendMessage(chatId, { text: '❌ Failed to get quote. Please try again later!' }, { quoted: message });
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/commands/roseday.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function rosedayCommand(sock, chatId, message) {
4 | try {
5 |
6 | const res = await fetch(`https://api.princetechn.com/api/fun/roseday?apikey=prince`);
7 |
8 | if (!res.ok) {
9 | throw await res.text();
10 | }
11 |
12 | const json = await res.json();
13 | const rosedayMessage = json.result;
14 |
15 | // Send the roseday message
16 | await sock.sendMessage(chatId, { text: rosedayMessage }, { quoted: message });
17 | } catch (error) {
18 | console.error('Error in roseday command:', error);
19 | await sock.sendMessage(chatId, { text: '❌ Failed to get roseday quote. Please try again later!' }, { quoted: message });
20 | }
21 | }
22 |
23 | module.exports = { rosedayCommand };
24 |
--------------------------------------------------------------------------------
/commands/dare.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function dareCommand(sock, chatId, message) {
4 | try {
5 | const shizokeys = 'shizo';
6 | const res = await fetch(`https://shizoapi.onrender.com/api/texts/dare?apikey=${shizokeys}`);
7 |
8 | if (!res.ok) {
9 | throw await res.text();
10 | }
11 |
12 | const json = await res.json();
13 | const dareMessage = json.result;
14 |
15 | // Send the dare message
16 | await sock.sendMessage(chatId, { text: dareMessage }, { quoted: message });
17 | } catch (error) {
18 | console.error('Error in dare command:', error);
19 | await sock.sendMessage(chatId, { text: '❌ Failed to get dare. Please try again later!' }, { quoted: message });
20 | }
21 | }
22 |
23 | module.exports = { dareCommand };
24 |
--------------------------------------------------------------------------------
/commands/weather.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 |
3 | module.exports = async function (sock, chatId, message, city) {
4 | try {
5 | const apiKey = '4902c0f2550f58298ad4146a92b65e10'; // Replace with your OpenWeather API Key
6 | const response = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`);
7 | const weather = response.data;
8 | const weatherText = `Weather in ${weather.name}: ${weather.weather[0].description}. Temperature: ${weather.main.temp}°C.`;
9 | await sock.sendMessage(chatId, { text: weatherText }, { quoted: message } );
10 | } catch (error) {
11 | console.error('Error fetching weather:', error);
12 | await sock.sendMessage(chatId, { text: 'Sorry, I could not fetch the weather right now.' }, { quoted: message } );
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/commands/truth.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function truthCommand(sock, chatId, message) {
4 | try {
5 | const shizokeys = 'shizo';
6 | const res = await fetch(`https://shizoapi.onrender.com/api/texts/truth?apikey=${shizokeys}`);
7 |
8 | if (!res.ok) {
9 | throw await res.text();
10 | }
11 |
12 | const json = await res.json();
13 | const truthMessage = json.result;
14 |
15 | // Send the truth message
16 | await sock.sendMessage(chatId, { text: truthMessage }, { quoted: message });
17 | } catch (error) {
18 | console.error('Error in truth command:', error);
19 | await sock.sendMessage(chatId, { text: '❌ Failed to get truth. Please try again later!' }, { quoted: message });
20 | }
21 | }
22 |
23 | module.exports = { truthCommand };
24 |
--------------------------------------------------------------------------------
/commands/flirt.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function flirtCommand(sock, chatId, message) {
4 | try {
5 | const shizokeys = 'shizo';
6 | const res = await fetch(`https://shizoapi.onrender.com/api/texts/flirt?apikey=${shizokeys}`);
7 |
8 | if (!res.ok) {
9 | throw await res.text();
10 | }
11 |
12 | const json = await res.json();
13 | const flirtMessage = json.result;
14 |
15 | // Send the flirt message
16 | await sock.sendMessage(chatId, { text: flirtMessage }, { quoted: message });
17 | } catch (error) {
18 | console.error('Error in flirt command:', error);
19 | await sock.sendMessage(chatId, { text: '❌ Failed to get flirt message. Please try again later!' }, { quoted: message });
20 | }
21 | }
22 |
23 | module.exports = { flirtCommand };
--------------------------------------------------------------------------------
/commands/news.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 |
3 | module.exports = async function (sock, chatId) {
4 | try {
5 | const apiKey = 'dcd720a6f1914e2d9dba9790c188c08c'; // Replace with your NewsAPI key
6 | const response = await axios.get(`https://newsapi.org/v2/top-headlines?country=us&apiKey=${apiKey}`);
7 | const articles = response.data.articles.slice(0, 5); // Get top 5 articles
8 | let newsMessage = '📰 *Latest News*:\n\n';
9 | articles.forEach((article, index) => {
10 | newsMessage += `${index + 1}. *${article.title}*\n${article.description}\n\n`;
11 | });
12 | await sock.sendMessage(chatId, { text: newsMessage });
13 | } catch (error) {
14 | console.error('Error fetching news:', error);
15 | await sock.sendMessage(chatId, { text: 'Sorry, I could not fetch news right now.' });
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/commands/goodnight.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function goodnightCommand(sock, chatId, message) {
4 | try {
5 | const shizokeys = 'shizo';
6 | const res = await fetch(`https://shizoapi.onrender.com/api/texts/lovenight?apikey=${shizokeys}`);
7 |
8 | if (!res.ok) {
9 | throw await res.text();
10 | }
11 |
12 | const json = await res.json();
13 | const goodnightMessage = json.result;
14 |
15 | // Send the goodnight message
16 | await sock.sendMessage(chatId, { text: goodnightMessage }, { quoted: message });
17 | } catch (error) {
18 | console.error('Error in goodnight command:', error);
19 | await sock.sendMessage(chatId, { text: '❌ Failed to get goodnight message. Please try again later!' }, { quoted: message });
20 | }
21 | }
22 |
23 | module.exports = { goodnightCommand };
--------------------------------------------------------------------------------
/lib/antilinkHelper.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const antilinkFilePath = path.join(__dirname, '../data', 'antilinkSettings.json');
5 |
6 | function loadAntilinkSettings() {
7 | if (fs.existsSync(antilinkFilePath)) {
8 | const data = fs.readFileSync(antilinkFilePath);
9 | return JSON.parse(data);
10 | }
11 | return {};
12 | }
13 |
14 | function saveAntilinkSettings(settings) {
15 | fs.writeFileSync(antilinkFilePath, JSON.stringify(settings, null, 2));
16 | }
17 |
18 | function setAntilinkSetting(groupId, type) {
19 | const settings = loadAntilinkSettings();
20 | settings[groupId] = type;
21 | saveAntilinkSettings(settings);
22 | }
23 |
24 | function getAntilinkSetting(groupId) {
25 | const settings = loadAntilinkSettings();
26 | return settings[groupId] || 'off';
27 | }
28 |
29 | module.exports = {
30 | setAntilinkSetting,
31 | getAntilinkSetting
32 | };
33 |
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 |
3 | global.APIs = {
4 | xteam: 'https://api.xteam.xyz',
5 | dzx: 'https://api.dhamzxploit.my.id',
6 | lol: 'https://api.lolhuman.xyz',
7 | violetics: 'https://violetics.pw',
8 | neoxr: 'https://api.neoxr.my.id',
9 | zenzapis: 'https://zenzapis.xyz',
10 | akuari: 'https://api.akuari.my.id',
11 | akuari2: 'https://apimu.my.id',
12 | nrtm: 'https://fg-nrtm.ddns.net',
13 | bg: 'http://bochil.ddns.net',
14 | fgmods: 'https://api-fgmods.ddns.net'
15 | };
16 |
17 | global.APIKeys = {
18 | 'https://api.xteam.xyz': 'd90a9e986e18778b',
19 | 'https://api.lolhuman.xyz': '85faf717d0545d14074659ad',
20 | 'https://api.neoxr.my.id': 'yourkey',
21 | 'https://violetics.pw': 'beta',
22 | 'https://zenzapis.xyz': 'yourkey',
23 | 'https://api-fgmods.ddns.net': 'fg-dylux'
24 | };
25 |
26 | module.exports = {
27 | WARN_COUNT: 3,
28 | APIs: global.APIs,
29 | APIKeys: global.APIKeys
30 | };
--------------------------------------------------------------------------------
/commands/warnings.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const warningsFilePath = path.join(__dirname, '../data/warnings.json');
5 |
6 | function loadWarnings() {
7 | if (!fs.existsSync(warningsFilePath)) {
8 | fs.writeFileSync(warningsFilePath, JSON.stringify({}), 'utf8');
9 | }
10 | const data = fs.readFileSync(warningsFilePath, 'utf8');
11 | return JSON.parse(data);
12 | }
13 |
14 | async function warningsCommand(sock, chatId, mentionedJidList) {
15 | const warnings = loadWarnings();
16 |
17 | if (mentionedJidList.length === 0) {
18 | await sock.sendMessage(chatId, { text: 'Please mention a user to check warnings.' });
19 | return;
20 | }
21 |
22 | const userToCheck = mentionedJidList[0];
23 | const warningCount = warnings[userToCheck] || 0;
24 |
25 | await sock.sendMessage(chatId, { text: `User has ${warningCount} warning(s).` });
26 | }
27 |
28 | module.exports = warningsCommand;
29 |
--------------------------------------------------------------------------------
/commands/tts.js:
--------------------------------------------------------------------------------
1 | const gTTS = require('gtts');
2 | const fs = require('fs');
3 | const path = require('path');
4 |
5 | async function ttsCommand(sock, chatId, text, message, language = 'en') {
6 | if (!text) {
7 | await sock.sendMessage(chatId, { text: 'Please provide the text for TTS conversion.' });
8 | return;
9 | }
10 |
11 | const fileName = `tts-${Date.now()}.mp3`;
12 | const filePath = path.join(__dirname, '..', 'assets', fileName);
13 |
14 | const gtts = new gTTS(text, language);
15 | gtts.save(filePath, async function (err) {
16 | if (err) {
17 | await sock.sendMessage(chatId, { text: 'Error generating TTS audio.' });
18 | return;
19 | }
20 |
21 | await sock.sendMessage(chatId, {
22 | audio: { url: filePath },
23 | mimetype: 'audio/mpeg'
24 | }, { quoted: message });
25 |
26 | fs.unlinkSync(filePath);
27 | });
28 | }
29 |
30 | module.exports = ttsCommand;
31 |
--------------------------------------------------------------------------------
/commands/antibadword.js:
--------------------------------------------------------------------------------
1 | const { handleAntiBadwordCommand } = require('../lib/antibadword');
2 | const isAdminHelper = require('../lib/isAdmin');
3 |
4 | async function antibadwordCommand(sock, chatId, message, senderId, isSenderAdmin) {
5 | try {
6 | if (!isSenderAdmin) {
7 | await sock.sendMessage(chatId, { text: '```For Group Admins Only!```' }, { quoted: message });
8 | return;
9 | }
10 |
11 | // Extract match from message
12 | const text = message.message?.conversation ||
13 | message.message?.extendedTextMessage?.text || '';
14 | const match = text.split(' ').slice(1).join(' ');
15 |
16 | await handleAntiBadwordCommand(sock, chatId, message, match);
17 | } catch (error) {
18 | console.error('Error in antibadword command:', error);
19 | await sock.sendMessage(chatId, { text: '*Error processing antibadword command*' }, { quoted: message });
20 | }
21 | }
22 |
23 | module.exports = antibadwordCommand;
--------------------------------------------------------------------------------
/commands/github.js:
--------------------------------------------------------------------------------
1 | async function githubCommand(sock, chatId) {
2 | const repoInfo = `*Lady bella*
3 |
4 | *Github:*
5 | https://github.com/SNOWBIRD0074/BEN-10-MD
6 |
7 | *Dont forget to star✨and fork our repo
8 |
9 | *OUR OFFICIAL CHANNEL
10 |
11 | https://whatsapp.com/channel/0029Vb5nSebFy722d2NEeU3C
12 | `;
13 |
14 | try {
15 | await sock.sendMessage(chatId, {
16 | text: repoInfo,
17 | contextInfo: {
18 | forwardingScore: 1,
19 | isForwarded: true,
20 | forwardedNewsletterMessageInfo: {
21 | newsletterJid: '120363399707841760@newsletter',
22 | newsletterName: 'Lady bella',
23 | serverMessageId: -1
24 | }
25 | }
26 | });
27 | } catch (error) {
28 | console.error('Error in github command:', error);
29 | await sock.sendMessage(chatId, {
30 | text: '❌ Error fetching repository information.'
31 | });
32 | }
33 | }
34 |
35 | module.exports = githubCommand;
--------------------------------------------------------------------------------
/commands/shayari.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function shayariCommand(sock, chatId, message) {
4 | try {
5 | const response = await fetch('https://shizoapi.onrender.com/api/texts/shayari?apikey=shizo');
6 | const data = await response.json();
7 |
8 | if (!data || !data.result) {
9 | throw new Error('Invalid response from API');
10 | }
11 |
12 | const buttons = [
13 | { buttonId: '.shayari', buttonText: { displayText: 'Shayari 🪄' }, type: 1 },
14 | { buttonId: '.roseday', buttonText: { displayText: '🌹 RoseDay' }, type: 1 }
15 | ];
16 |
17 | await sock.sendMessage(chatId, {
18 | text: data.result,
19 | buttons: buttons,
20 | headerType: 1
21 | }, { quoted: message });
22 | } catch (error) {
23 | console.error('Error in shayari command:', error);
24 | await sock.sendMessage(chatId, {
25 | text: '❌ Failed to fetch shayari. Please try again later.',
26 | }, { quoted: message });
27 | }
28 | }
29 |
30 | module.exports = { shayariCommand };
--------------------------------------------------------------------------------
/commands/ship.js:
--------------------------------------------------------------------------------
1 | async function shipCommand(sock, chatId, msg, groupMetadata) {
2 | try {
3 | // Get all participants from the group
4 | const participants = await sock.groupMetadata(chatId);
5 | const ps = participants.participants.map(v => v.id);
6 |
7 | // Get two random participants
8 | let firstUser, secondUser;
9 |
10 | // Select first random user
11 | firstUser = ps[Math.floor(Math.random() * ps.length)];
12 |
13 | // Select second random user (different from first)
14 | do {
15 | secondUser = ps[Math.floor(Math.random() * ps.length)];
16 | } while (secondUser === firstUser);
17 |
18 | // Format the mentions
19 | const formatMention = id => '@' + id.split('@')[0];
20 |
21 | // Create and send the ship message
22 | await sock.sendMessage(chatId, {
23 | text: `${formatMention(firstUser)} ❤️ ${formatMention(secondUser)}\nCongratulations 💖🍻`,
24 | mentions: [firstUser, secondUser]
25 | });
26 |
27 | } catch (error) {
28 | console.error('Error in ship command:', error);
29 | await sock.sendMessage(chatId, { text: '❌ Failed to ship! Make sure this is a group.' });
30 | }
31 | }
32 |
33 | module.exports = shipCommand;
--------------------------------------------------------------------------------
/commands/gif.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const settings = require('../settings'); // Assuming the API key is stored here
3 |
4 | async function gifCommand(sock, chatId, query) {
5 | const apiKey = settings.giphyApiKey; // Replace with your Giphy API Key
6 |
7 | if (!query) {
8 | await sock.sendMessage(chatId, { text: 'Please provide a search term for the GIF.' });
9 | return;
10 | }
11 |
12 | try {
13 | const response = await axios.get(`https://api.giphy.com/v1/gifs/search`, {
14 | params: {
15 | api_key: apiKey,
16 | q: query,
17 | limit: 1,
18 | rating: 'g'
19 | }
20 | });
21 |
22 | const gifUrl = response.data.data[0]?.images?.downsized_medium?.url;
23 |
24 | if (gifUrl) {
25 | await sock.sendMessage(chatId, { video: { url: gifUrl }, caption: `Here is your GIF for "${query}"` });
26 | } else {
27 | await sock.sendMessage(chatId, { text: 'No GIFs found for your search term.' });
28 | }
29 | } catch (error) {
30 | console.error('Error fetching GIF:', error);
31 | await sock.sendMessage(chatId, { text: 'Failed to fetch GIF. Please try again later.' });
32 | }
33 | }
34 |
35 | module.exports = gifCommand;
36 |
--------------------------------------------------------------------------------
/lib/isAdmin.js:
--------------------------------------------------------------------------------
1 | async function isAdmin(sock, chatId, senderId) {
2 | try {
3 | const groupMetadata = await sock.groupMetadata(chatId);
4 |
5 | const botId = sock.user.id.split(':')[0] + '@s.whatsapp.net';
6 |
7 | const participant = groupMetadata.participants.find(p =>
8 | p.id === senderId ||
9 | p.id === senderId.replace('@s.whatsapp.net', '@lid') ||
10 | p.id === senderId.replace('@lid', '@s.whatsapp.net')
11 | );
12 |
13 | const bot = groupMetadata.participants.find(p =>
14 | p.id === botId ||
15 | p.id === botId.replace('@s.whatsapp.net', '@lid')
16 | );
17 |
18 | const isBotAdmin = bot && (bot.admin === 'admin' || bot.admin === 'superadmin');
19 | const isSenderAdmin = participant && (participant.admin === 'admin' || participant.admin === 'superadmin');
20 |
21 | if (!bot) {
22 | return { isSenderAdmin, isBotAdmin: true };
23 | }
24 |
25 | return { isSenderAdmin, isBotAdmin };
26 | } catch (error) {
27 | console.error('Error in isAdmin:', error);
28 | return { isSenderAdmin: false, isBotAdmin: false };
29 | }
30 | }
31 |
32 | module.exports = isAdmin;
33 |
--------------------------------------------------------------------------------
/commands/meme.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function memeCommand(sock, chatId, message) {
4 | try {
5 | const response = await fetch('https://shizoapi.onrender.com/api/memes/cheems?apikey=shizo');
6 |
7 | // Check if response is an image
8 | const contentType = response.headers.get('content-type');
9 | if (contentType && contentType.includes('image')) {
10 | const imageBuffer = await response.buffer();
11 |
12 | const buttons = [
13 | { buttonId: '.meme', buttonText: { displayText: '🎭 Another Meme' }, type: 1 },
14 | { buttonId: '.joke', buttonText: { displayText: '😄 Joke' }, type: 1 }
15 | ];
16 |
17 | await sock.sendMessage(chatId, {
18 | image: imageBuffer,
19 | caption: "> Here's your cheems meme! 🐕",
20 | buttons: buttons,
21 | headerType: 1
22 | },{ quoted: message});
23 | } else {
24 | throw new Error('Invalid response type from API');
25 | }
26 | } catch (error) {
27 | console.error('Error in meme command:', error);
28 | await sock.sendMessage(chatId, {
29 | text: '❌ Failed to fetch meme. Please try again later.'
30 | },{ quoted: message });
31 | }
32 | }
33 |
34 | module.exports = memeCommand;
35 |
--------------------------------------------------------------------------------
/commands/attp.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 |
3 | async function attpCommand(sock, chatId, message) {
4 | const userMessage = message.message.conversation || message.message.extendedTextMessage?.text || '';
5 | const text = userMessage.split(' ').slice(1).join(' ');
6 |
7 | if (!text) {
8 | await sock.sendMessage(chatId, { text: 'Please provide text after the .attp command.' }, { quoted: message });
9 | return;
10 | }
11 |
12 | try {
13 | // Use the API to generate animated text sticker
14 | const apiUrl = `https://api.lolhuman.xyz/api/attp?apikey=537f15cefff1662ac5df2935&text=${encodeURIComponent(text)}`;
15 |
16 | const response = await axios.get(apiUrl, {
17 | responseType: 'arraybuffer',
18 | timeout: 30000,
19 | headers: {
20 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
21 | }
22 | });
23 |
24 | const stickerBuffer = Buffer.from(response.data);
25 |
26 | await sock.sendMessage(chatId, {
27 | sticker: stickerBuffer,
28 | mimetype: 'image/webp',
29 | }, { quoted: message });
30 |
31 | } catch (error) {
32 | console.error('Error generating sticker:', error);
33 | await sock.sendMessage(chatId, { text: 'Failed to generate the sticker. Please try again later.' }, { quoted: message });
34 | }
35 | }
36 |
37 | module.exports = attpCommand;
--------------------------------------------------------------------------------
/commands/viewonce.js:
--------------------------------------------------------------------------------
1 | const { downloadContentFromMessage } = require('@whiskeysockets/baileys');
2 |
3 | async function viewonceCommand(sock, chatId, message) {
4 | // Extract quoted imageMessage or videoMessage from your structure
5 | const quoted = message.message?.extendedTextMessage?.contextInfo?.quotedMessage;
6 | const quotedImage = quoted?.imageMessage;
7 | const quotedVideo = quoted?.videoMessage;
8 |
9 | if (quotedImage && quotedImage.viewOnce) {
10 | // Download and send the image
11 | const stream = await downloadContentFromMessage(quotedImage, 'image');
12 | let buffer = Buffer.from([]);
13 | for await (const chunk of stream) buffer = Buffer.concat([buffer, chunk]);
14 | await sock.sendMessage(chatId, { image: buffer, fileName: 'media.jpg', caption: quotedImage.caption || '' }, { quoted: message });
15 | } else if (quotedVideo && quotedVideo.viewOnce) {
16 | // Download and send the video
17 | const stream = await downloadContentFromMessage(quotedVideo, 'video');
18 | let buffer = Buffer.from([]);
19 | for await (const chunk of stream) buffer = Buffer.concat([buffer, chunk]);
20 | await sock.sendMessage(chatId, { video: buffer, fileName: 'media.mp4', caption: quotedVideo.caption || '' }, { quoted: message });
21 | } else {
22 | await sock.sendMessage(chatId, { text: '❌ Please reply to a view-once image or video.' }, { quoted: message });
23 | }
24 | }
25 |
26 | module.exports = viewonceCommand;
--------------------------------------------------------------------------------
/commands/resetlink.js:
--------------------------------------------------------------------------------
1 | async function resetlinkCommand(sock, chatId, senderId) {
2 | try {
3 | // Check if sender is admin
4 | const groupMetadata = await sock.groupMetadata(chatId);
5 | const isAdmin = groupMetadata.participants
6 | .filter(p => p.admin)
7 | .map(p => p.id)
8 | .includes(senderId);
9 |
10 | // Check if bot is admin
11 | const botId = sock.user.id.split(':')[0] + '@s.whatsapp.net';
12 | const isBotAdmin = groupMetadata.participants
13 | .filter(p => p.admin)
14 | .map(p => p.id)
15 | .includes(botId);
16 |
17 | if (!isAdmin) {
18 | await sock.sendMessage(chatId, { text: '❌ Only admins can use this command!' });
19 | return;
20 | }
21 |
22 | if (!isBotAdmin) {
23 | await sock.sendMessage(chatId, { text: '❌ Bot must be admin to reset group link!' });
24 | return;
25 | }
26 |
27 | // Reset the group link
28 | const newCode = await sock.groupRevokeInvite(chatId);
29 |
30 | // Send the new link
31 | await sock.sendMessage(chatId, {
32 | text: `✅ Group link has been successfully reset\n\n📌 New link:\nhttps://chat.whatsapp.com/${newCode}`
33 | });
34 |
35 | } catch (error) {
36 | console.error('Error in resetlink command:', error);
37 | await sock.sendMessage(chatId, { text: 'Failed to reset group link!' });
38 | }
39 | }
40 |
41 | module.exports = resetlinkCommand;
--------------------------------------------------------------------------------
/commands/botsong.js:
--------------------------------------------------------------------------------
1 |
2 | const fs = require('fs');
3 | const path = require('path');
4 |
5 | async function botsongCommand(sock, chatId) {
6 | try {
7 | const audioPath = path.join(__dirname, '../assets/botsong.mp3');
8 | const imagePath = path.join(__dirname, '../assets/bot_image.jpg');
9 |
10 | // Check if audio and image exist
11 | if (!fs.existsSync(audioPath)) {
12 | return await sock.sendMessage(chatId, { text: '⚠️ botsong.mp3 not found in assets folder.' });
13 | }
14 |
15 | const audioBuffer = fs.readFileSync(audioPath);
16 | const imageBuffer = fs.existsSync(imagePath) ? fs.readFileSync(imagePath) : null;
17 |
18 | await sock.sendMessage(chatId, {
19 | audio: audioBuffer,
20 | mimetype: 'audio/mp4',
21 | ptt: false,
22 | contextInfo: {
23 | externalAdReply: {
24 | title: "BEN 10 MD Theme Song",
25 | body: "🔥 Powered by SNOWBIRD",
26 | thumbnail: imageBuffer,
27 | mediaType: 2,
28 | mediaUrl: "https://whatsapp.com/channel/0029Vb5nSebFy722d2NEeU3",
29 | sourceUrl: "https://whatsapp.com/channel/0029Vb5nSebFy722d2NEeU3"
30 | }
31 | }
32 | });
33 | } catch (error) {
34 | console.error("Error in botsong command:", error);
35 | await sock.sendMessage(chatId, { text: '❌ Error sending bot song.' });
36 | }
37 | }
38 |
39 | module.exports = botsongCommand;
40 |
--------------------------------------------------------------------------------
/commands/ping.js:
--------------------------------------------------------------------------------
1 | const os = require('os');
2 | const settings = require('../settings.js');
3 |
4 | function formatTime(seconds) {
5 | const days = Math.floor(seconds / (24 * 60 * 60));
6 | seconds = seconds % (24 * 60 * 60);
7 | const hours = Math.floor(seconds / (60 * 60));
8 | seconds = seconds % (60 * 60);
9 | const minutes = Math.floor(seconds / 60);
10 | seconds = Math.floor(seconds % 60);
11 |
12 | let time = '';
13 | if (days > 0) time += `${days}d `;
14 | if (hours > 0) time += `${hours}h `;
15 | if (minutes > 0) time += `${minutes}m `;
16 | if (seconds > 0 || time === '') time += `${seconds}s`;
17 |
18 | return time.trim();
19 | }
20 |
21 | async function pingCommand(sock, chatId, message) {
22 | try {
23 | const start = Date.now();
24 | await sock.sendMessage(chatId, { text: ' *𝙹𝚄𝙽𝙴 𝙼𝙳 𝙱𝙾𝚃* ' }, { quoted: message });
25 | const end = Date.now();
26 | const ping = Math.round((end - start) / 2);
27 |
28 | const uptimeInSeconds = process.uptime();
29 | const uptimeFormatted = formatTime(uptimeInSeconds);
30 |
31 | const botInfo = `🔸 *ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3* 𝚜𝚙𝚎𝚎𝚍: ${ping} ms`.trim();
32 |
33 | // Reply to the original message with the bot info
34 | await sock.sendMessage(chatId, { text: botInfo},{ quoted: message });
35 |
36 | } catch (error) {
37 | console.error('Error in ping command:', error);
38 | await sock.sendMessage(chatId, { text: '❌ Failed to get bot status.' });
39 | }
40 | }
41 |
42 | module.exports = pingCommand;
43 |
--------------------------------------------------------------------------------
/commands/tagall.js:
--------------------------------------------------------------------------------
1 | const isAdmin = require('../lib/isAdmin'); // Move isAdmin to helpers
2 |
3 | async function tagAllCommand(sock, chatId, senderId) {
4 | try {
5 | const { isSenderAdmin, isBotAdmin } = await isAdmin(sock, chatId, senderId);
6 |
7 | if (!isSenderAdmin && !isBotAdmin) {
8 | await sock.sendMessage(chatId, {
9 | text: 'Only admins can use the .tagall command.'
10 | });
11 | return;
12 | }
13 |
14 | // Get group metadata
15 | const groupMetadata = await sock.groupMetadata(chatId);
16 | const participants = groupMetadata.participants;
17 |
18 | if (!participants || participants.length === 0) {
19 | await sock.sendMessage(chatId, { text: 'No participants found in the group.' });
20 | return;
21 | }
22 |
23 | // Create message with each member on a new line
24 | let message = '🔊 *Group Members:*\n\n';
25 | participants.forEach(participant => {
26 | message += `@${participant.id.split('@')[0]}\n`; // Add \n for new line
27 | });
28 |
29 | // Send message with mentions
30 | await sock.sendMessage(chatId, {
31 | text: message,
32 | mentions: participants.map(p => p.id)
33 | });
34 |
35 | } catch (error) {
36 | console.error('Error in tagall command:', error);
37 | await sock.sendMessage(chatId, { text: 'Failed to tag all members.' });
38 | }
39 | }
40 |
41 | module.exports = tagAllCommand; // Export directly
42 |
--------------------------------------------------------------------------------
/commands/staff.js:
--------------------------------------------------------------------------------
1 | async function staffCommand(sock, chatId, msg) {
2 | try {
3 | // Get group metadata
4 | const groupMetadata = await sock.groupMetadata(chatId);
5 |
6 | // Get group profile picture
7 | let pp;
8 | try {
9 | pp = await sock.profilePictureUrl(chatId, 'image');
10 | } catch {
11 | pp = 'https://i.imgur.com/2wzGhpF.jpeg'; // Default image
12 | }
13 |
14 | // Get admins from participants
15 | const participants = groupMetadata.participants;
16 | const groupAdmins = participants.filter(p => p.admin);
17 | const listAdmin = groupAdmins.map((v, i) => `${i + 1}. @${v.id.split('@')[0]}`).join('\n▢ ');
18 |
19 | // Get group owner
20 | const owner = groupMetadata.owner || groupAdmins.find(p => p.admin === 'superadmin')?.id || chatId.split('-')[0] + '@s.whatsapp.net';
21 |
22 | // Create staff text
23 | const text = `
24 | ≡ *GROUP ADMINS* _${groupMetadata.subject}_
25 |
26 | ┌─⊷ *ADMINS*
27 | ▢ ${listAdmin}
28 | └───────────
29 | `.trim();
30 |
31 | // Send the message with image and mentions
32 | await sock.sendMessage(chatId, {
33 | image: { url: pp },
34 | caption: text,
35 | mentions: [...groupAdmins.map(v => v.id), owner]
36 | });
37 |
38 | } catch (error) {
39 | console.error('Error in staff command:', error);
40 | await sock.sendMessage(chatId, { text: 'Failed to get admin list!' });
41 | }
42 | }
43 |
44 | module.exports = staffCommand;
--------------------------------------------------------------------------------
/commands/anticall.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 |
3 | const ANTICALL_PATH = './data/anticall.json';
4 |
5 | function readState() {
6 | try {
7 | if (!fs.existsSync(ANTICALL_PATH)) return { enabled: false };
8 | const raw = fs.readFileSync(ANTICALL_PATH, 'utf8');
9 | const data = JSON.parse(raw || '{}');
10 | return { enabled: !!data.enabled };
11 | } catch {
12 | return { enabled: false };
13 | }
14 | }
15 |
16 | function writeState(enabled) {
17 | try {
18 | if (!fs.existsSync('./data')) fs.mkdirSync('./data', { recursive: true });
19 | fs.writeFileSync(ANTICALL_PATH, JSON.stringify({ enabled: !!enabled }, null, 2));
20 | } catch {}
21 | }
22 |
23 | async function anticallCommand(sock, chatId, message, args) {
24 | const state = readState();
25 | const sub = (args || '').trim().toLowerCase();
26 |
27 | if (!sub || (sub !== 'on' && sub !== 'off' && sub !== 'status')) {
28 | await sock.sendMessage(chatId, { text: '*ANTICALL*\n\n.anticall on - Enable auto-block on incoming calls\n.anticall off - Disable anticall\n.anticall status - Show current status' }, { quoted: message });
29 | return;
30 | }
31 |
32 | if (sub === 'status') {
33 | await sock.sendMessage(chatId, { text: `Anticall is currently *${state.enabled ? 'ON' : 'OFF'}*.` }, { quoted: message });
34 | return;
35 | }
36 |
37 | const enable = sub === 'on';
38 | writeState(enable);
39 | await sock.sendMessage(chatId, { text: `Anticall is now *${enable ? 'ENABLED' : 'DISABLED'}*.` }, { quoted: message });
40 | }
41 |
42 | module.exports = { anticallCommand, readState };
43 |
44 |
45 |
--------------------------------------------------------------------------------
/commands/lyrics.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function lyricsCommand(sock, chatId, songTitle, message) {
4 | if (!songTitle) {
5 | await sock.sendMessage(chatId, {
6 | text: '🔍 Please enter the song name to get the lyrics! Usage: *lyrics *'
7 | },{ quoted: message });
8 | return;
9 | }
10 |
11 | try {
12 | // Use lyricsapi.fly.dev and return only the raw lyrics text
13 | const apiUrl = `https://lyricsapi.fly.dev/api/lyrics?q=${encodeURIComponent(songTitle)}`;
14 | const res = await fetch(apiUrl);
15 |
16 | if (!res.ok) {
17 | const errText = await res.text();
18 | throw errText;
19 | }
20 |
21 | const data = await res.json();
22 |
23 | const lyrics = data && data.result && data.result.lyrics ? data.result.lyrics : null;
24 | if (!lyrics) {
25 | await sock.sendMessage(chatId, {
26 | text: `❌ Sorry, I couldn't find any lyrics for "${songTitle}".`
27 | },{ quoted: message });
28 | return;
29 | }
30 |
31 | const maxChars = 4096;
32 | const output = lyrics.length > maxChars ? lyrics.slice(0, maxChars - 3) + '...' : lyrics;
33 |
34 | await sock.sendMessage(chatId, { text: output }, { quoted: message });
35 | } catch (error) {
36 | console.error('Error in lyrics command:', error);
37 | await sock.sendMessage(chatId, {
38 | text: `❌ An error occurred while fetching the lyrics for "${songTitle}".`
39 | },{ quoted: message });
40 | }
41 | }
42 |
43 | module.exports = { lyricsCommand };
44 |
--------------------------------------------------------------------------------
/commands/trivia.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 |
3 | let triviaGames = {};
4 |
5 | async function startTrivia(sock, chatId) {
6 | if (triviaGames[chatId]) {
7 | sock.sendMessage(chatId, { text: 'A trivia game is already in progress!' });
8 | return;
9 | }
10 |
11 | try {
12 | const response = await axios.get('https://opentdb.com/api.php?amount=1&type=multiple');
13 | const questionData = response.data.results[0];
14 |
15 | triviaGames[chatId] = {
16 | question: questionData.question,
17 | correctAnswer: questionData.correct_answer,
18 | options: [...questionData.incorrect_answers, questionData.correct_answer].sort(),
19 | };
20 |
21 | sock.sendMessage(chatId, {
22 | text: `Trivia Time!\n\nQuestion: ${triviaGames[chatId].question}\nOptions:\n${triviaGames[chatId].options.join('\n')}`
23 | });
24 | } catch (error) {
25 | sock.sendMessage(chatId, { text: 'Error fetching trivia question. Try again later.' });
26 | }
27 | }
28 |
29 | function answerTrivia(sock, chatId, answer) {
30 | if (!triviaGames[chatId]) {
31 | sock.sendMessage(chatId, { text: 'No trivia game is in progress.' });
32 | return;
33 | }
34 |
35 | const game = triviaGames[chatId];
36 |
37 | if (answer.toLowerCase() === game.correctAnswer.toLowerCase()) {
38 | sock.sendMessage(chatId, { text: `Correct! The answer is ${game.correctAnswer}` });
39 | } else {
40 | sock.sendMessage(chatId, { text: `Wrong! The correct answer was ${game.correctAnswer}` });
41 | }
42 |
43 | delete triviaGames[chatId];
44 | }
45 |
46 | module.exports = { startTrivia, answerTrivia };
47 |
--------------------------------------------------------------------------------
/commands/simage-alt.js:
--------------------------------------------------------------------------------
1 | var { downloadContentFromMessage } = require('@whiskeysockets/baileys');
2 | var { exec } = require('child_process');
3 | var fs = require('fs');
4 | const ffmpeg = require('ffmpeg-static');
5 |
6 | async function simageCommand(sock, quotedMessage, chatId) {
7 | try {
8 | if (!quotedMessage?.stickerMessage) {
9 | await sock.sendMessage(chatId, { text: 'Please reply to a sticker!' });
10 | return;
11 | }
12 |
13 | const stream = await downloadContentFromMessage(quotedMessage.stickerMessage, 'sticker');
14 | let buffer = Buffer.from([]);
15 | for await (const chunk of stream) {
16 | buffer = Buffer.concat([buffer, chunk]);
17 | }
18 |
19 | const tempSticker = `/app/temp/temp_${Date.now()}.webp`;
20 | const tempOutput = `/app/temp/image_${Date.now()}.png`;
21 |
22 | fs.writeFileSync(tempSticker, buffer);
23 |
24 | // Convert webp to png using ffmpeg
25 | await new Promise((resolve, reject) => {
26 | exec(`${ffmpeg} -i ${tempSticker} ${tempOutput}`, (error) => {
27 | if (error) reject(error);
28 | else resolve();
29 | });
30 | });
31 |
32 | await sock.sendMessage(chatId, {
33 | image: fs.readFileSync(tempOutput),
34 | caption: '✨ Here\'s your image!'
35 | });
36 |
37 | // Cleanup
38 | fs.unlinkSync(tempSticker);
39 | fs.unlinkSync(tempOutput);
40 |
41 | } catch (error) {
42 | console.error('Error in simage command:', error);
43 | await sock.sendMessage(chatId, { text: 'Failed to convert sticker to image!' });
44 | }
45 | }
46 |
47 | module.exports = simageCommand;
--------------------------------------------------------------------------------
/commands/groupinfo.js:
--------------------------------------------------------------------------------
1 | async function groupInfoCommand(sock, chatId, msg) {
2 | try {
3 | // Get group metadata
4 | const groupMetadata = await sock.groupMetadata(chatId);
5 |
6 | // Get group profile picture
7 | let pp;
8 | try {
9 | pp = await sock.profilePictureUrl(chatId, 'image');
10 | } catch {
11 | pp = 'https://i.imgur.com/2wzGhpF.jpeg'; // Default image
12 | }
13 |
14 | // Get admins from participants
15 | const participants = groupMetadata.participants;
16 | const groupAdmins = participants.filter(p => p.admin);
17 | const listAdmin = groupAdmins.map((v, i) => `${i + 1}. @${v.id.split('@')[0]}`).join('\n');
18 |
19 | // Get group owner
20 | const owner = groupMetadata.owner || groupAdmins.find(p => p.admin === 'superadmin')?.id || chatId.split('-')[0] + '@s.whatsapp.net';
21 |
22 | // Create info text
23 | const text = `
24 | ┌──「 *INFO GROUP* 」
25 | ▢ *♻️ID:*
26 | • ${groupMetadata.id}
27 | ▢ *🔖NAME* :
28 | • ${groupMetadata.subject}
29 | ▢ *👥Members* :
30 | • ${participants.length}
31 | ▢ *🤿Group Owner:*
32 | • @${owner.split('@')[0]}
33 | ▢ *🕵🏻♂️Admins:*
34 | ${listAdmin}
35 |
36 | ▢ *📌Description* :
37 | • ${groupMetadata.desc?.toString() || 'No description'}
38 | `.trim();
39 |
40 | // Send the message with image and mentions
41 | await sock.sendMessage(chatId, {
42 | image: { url: pp },
43 | caption: text,
44 | mentions: [...groupAdmins.map(v => v.id), owner]
45 | });
46 |
47 | } catch (error) {
48 | console.error('Error in groupinfo command:', error);
49 | await sock.sendMessage(chatId, { text: 'Failed to get group info!' });
50 | }
51 | }
52 |
53 | module.exports = groupInfoCommand;
--------------------------------------------------------------------------------
/commands/ban.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const { channelInfo } = require('../lib/messageConfig');
3 |
4 | async function banCommand(sock, chatId, message) {
5 | let userToBan;
6 |
7 | // Check for mentioned users
8 | if (message.message?.extendedTextMessage?.contextInfo?.mentionedJid?.length > 0) {
9 | userToBan = message.message.extendedTextMessage.contextInfo.mentionedJid[0];
10 | }
11 | // Check for replied message
12 | else if (message.message?.extendedTextMessage?.contextInfo?.participant) {
13 | userToBan = message.message.extendedTextMessage.contextInfo.participant;
14 | }
15 |
16 | if (!userToBan) {
17 | await sock.sendMessage(chatId, {
18 | text: 'Please mention the user or reply to their message to ban!',
19 | ...channelInfo
20 | });
21 | return;
22 | }
23 |
24 | try {
25 | // Add user to banned list
26 | const bannedUsers = JSON.parse(fs.readFileSync('./data/banned.json'));
27 | if (!bannedUsers.includes(userToBan)) {
28 | bannedUsers.push(userToBan);
29 | fs.writeFileSync('./data/banned.json', JSON.stringify(bannedUsers, null, 2));
30 |
31 | await sock.sendMessage(chatId, {
32 | text: `Successfully banned @${userToBan.split('@')[0]}!`,
33 | mentions: [userToBan],
34 | ...channelInfo
35 | });
36 | } else {
37 | await sock.sendMessage(chatId, {
38 | text: `${userToBan.split('@')[0]} is already banned!`,
39 | mentions: [userToBan],
40 | ...channelInfo
41 | });
42 | }
43 | } catch (error) {
44 | console.error('Error in ban command:', error);
45 | await sock.sendMessage(chatId, { text: 'Failed to ban user!', ...channelInfo });
46 | }
47 | }
48 |
49 | module.exports = banCommand;
50 |
--------------------------------------------------------------------------------
/commands/mute.js:
--------------------------------------------------------------------------------
1 | const isAdmin = require('../lib/isAdmin');
2 |
3 | async function muteCommand(sock, chatId, senderId, message, durationInMinutes) {
4 |
5 |
6 | const { isSenderAdmin, isBotAdmin } = await isAdmin(sock, chatId, senderId);
7 | if (!isBotAdmin) {
8 | await sock.sendMessage(chatId, { text: 'Please make the bot an admin first.' }, { quoted: message });
9 | return;
10 | }
11 |
12 | if (!isSenderAdmin) {
13 | await sock.sendMessage(chatId, { text: 'Only group admins can use the mute command.' }, { quoted: message });
14 | return;
15 | }
16 |
17 | try {
18 | // Mute the group
19 | await sock.groupSettingUpdate(chatId, 'announcement');
20 |
21 | if (durationInMinutes !== undefined && durationInMinutes > 0) {
22 | const durationInMilliseconds = durationInMinutes * 60 * 1000;
23 | await sock.sendMessage(chatId, { text: `The group has been muted for ${durationInMinutes} minutes.` }, { quoted: message });
24 |
25 | // Set timeout to unmute after duration
26 | setTimeout(async () => {
27 | try {
28 | await sock.groupSettingUpdate(chatId, 'not_announcement');
29 | await sock.sendMessage(chatId, { text: 'The group has been unmuted.' });
30 | } catch (unmuteError) {
31 | console.error('Error unmuting group:', unmuteError);
32 | }
33 | }, durationInMilliseconds);
34 | } else {
35 | await sock.sendMessage(chatId, { text: 'The group has been muted.' }, { quoted: message });
36 | }
37 | } catch (error) {
38 | console.error('Error muting/unmuting the group:', error);
39 | await sock.sendMessage(chatId, { text: 'An error occurred while muting/unmuting the group. Please try again.' }, { quoted: message });
40 | }
41 | }
42 |
43 | module.exports = muteCommand;
44 |
--------------------------------------------------------------------------------
/commands/stupid.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function stupidCommand(sock, chatId, quotedMsg, mentionedJid, sender, args) {
4 | try {
5 | // Determine the target user
6 | let who = quotedMsg
7 | ? quotedMsg.sender
8 | : mentionedJid && mentionedJid[0]
9 | ? mentionedJid[0]
10 | : sender;
11 |
12 | // Get the text for the stupid card (default to "im+stupid" if not provided)
13 | let text = args && args.length > 0 ? args.join(' ') : 'im+stupid';
14 |
15 | // Get the profile picture URL
16 | let avatarUrl;
17 | try {
18 | avatarUrl = await sock.profilePictureUrl(who, 'image');
19 | } catch (error) {
20 | console.error('Error fetching profile picture:', error);
21 | avatarUrl = 'https://telegra.ph/file/24fa902ead26340f3df2c.png'; // Default avatar
22 | }
23 |
24 | // Fetch the stupid card from the API
25 | const apiUrl = `https://some-random-api.com/canvas/misc/its-so-stupid?avatar=${encodeURIComponent(avatarUrl)}&dog=${encodeURIComponent(text)}`;
26 | const response = await fetch(apiUrl);
27 |
28 | if (!response.ok) {
29 | throw new Error(`API responded with status: ${response.status}`);
30 | }
31 |
32 | // Get the image buffer
33 | const imageBuffer = await response.buffer();
34 |
35 | // Send the image with caption
36 | await sock.sendMessage(chatId, {
37 | image: imageBuffer,
38 | caption: `*@${who.split('@')[0]}*`,
39 | mentions: [who]
40 | });
41 |
42 | } catch (error) {
43 | console.error('Error in stupid command:', error);
44 | await sock.sendMessage(chatId, {
45 | text: '❌ Sorry, I couldn\'t generate the stupid card. Please try again later!'
46 | });
47 | }
48 | }
49 |
50 | module.exports = { stupidCommand };
--------------------------------------------------------------------------------
/commands/topmembers.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const dataFilePath = path.join(__dirname, '..', 'data', 'messageCount.json');
5 |
6 | function loadMessageCounts() {
7 | if (fs.existsSync(dataFilePath)) {
8 | const data = fs.readFileSync(dataFilePath);
9 | return JSON.parse(data);
10 | }
11 | return {};
12 | }
13 |
14 | function saveMessageCounts(messageCounts) {
15 | fs.writeFileSync(dataFilePath, JSON.stringify(messageCounts, null, 2));
16 | }
17 |
18 | function incrementMessageCount(groupId, userId) {
19 | const messageCounts = loadMessageCounts();
20 |
21 | if (!messageCounts[groupId]) {
22 | messageCounts[groupId] = {};
23 | }
24 |
25 | if (!messageCounts[groupId][userId]) {
26 | messageCounts[groupId][userId] = 0;
27 | }
28 |
29 | messageCounts[groupId][userId] += 1;
30 |
31 | saveMessageCounts(messageCounts);
32 | }
33 |
34 | function topMembers(sock, chatId, isGroup) {
35 | if (!isGroup) {
36 | sock.sendMessage(chatId, { text: 'This command is only available in group chats.' });
37 | return;
38 | }
39 |
40 | const messageCounts = loadMessageCounts();
41 | const groupCounts = messageCounts[chatId] || {};
42 |
43 | const sortedMembers = Object.entries(groupCounts)
44 | .sort(([, a], [, b]) => b - a)
45 | .slice(0, 5); // Get top 5 members
46 |
47 | if (sortedMembers.length === 0) {
48 | sock.sendMessage(chatId, { text: 'No message activity recorded yet.' });
49 | return;
50 | }
51 |
52 | let message = '🏆 Top Members Based on Message Count:\n\n';
53 | sortedMembers.forEach(([userId, count], index) => {
54 | message += `${index + 1}. @${userId.split('@')[0]} - ${count} messages\n`;
55 | });
56 |
57 | sock.sendMessage(chatId, { text: message, mentions: sortedMembers.map(([userId]) => userId) });
58 | }
59 |
60 | module.exports = { incrementMessageCount, topMembers };
61 |
--------------------------------------------------------------------------------
/commands/unban.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const { channelInfo } = require('../lib/messageConfig');
4 |
5 | async function unbanCommand(sock, chatId, message) {
6 | let userToUnban;
7 |
8 | // Check for mentioned users
9 | if (message.message?.extendedTextMessage?.contextInfo?.mentionedJid?.length > 0) {
10 | userToUnban = message.message.extendedTextMessage.contextInfo.mentionedJid[0];
11 | }
12 | // Check for replied message
13 | else if (message.message?.extendedTextMessage?.contextInfo?.participant) {
14 | userToUnban = message.message.extendedTextMessage.contextInfo.participant;
15 | }
16 |
17 | if (!userToUnban) {
18 | await sock.sendMessage(chatId, {
19 | text: 'Please mention the user or reply to their message to unban!',
20 | ...channelInfo
21 | }, { quoted: message });
22 | return;
23 | }
24 |
25 | try {
26 | const bannedUsers = JSON.parse(fs.readFileSync('./data/banned.json'));
27 | const index = bannedUsers.indexOf(userToUnban);
28 | if (index > -1) {
29 | bannedUsers.splice(index, 1);
30 | fs.writeFileSync('./data/banned.json', JSON.stringify(bannedUsers, null, 2));
31 |
32 | await sock.sendMessage(chatId, {
33 | text: `Successfully unbanned ${userToUnban.split('@')[0]}!`,
34 | mentions: [userToUnban],
35 | ...channelInfo
36 | });
37 | } else {
38 | await sock.sendMessage(chatId, {
39 | text: `${userToUnban.split('@')[0]} is not banned!`,
40 | mentions: [userToUnban],
41 | ...channelInfo
42 | });
43 | }
44 | } catch (error) {
45 | console.error('Error in unban command:', error);
46 | await sock.sendMessage(chatId, { text: 'Failed to unban user!', ...channelInfo }, { quoted: message });
47 | }
48 | }
49 |
50 | module.exports = unbanCommand;
--------------------------------------------------------------------------------
/commands/pies.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | const BASE = 'https://shizoapi.onrender.com/api/pies';
4 | const VALID_COUNTRIES = ['china', 'indonesia', 'japan', 'korea', 'hijab'];
5 |
6 | async function fetchPiesImageBuffer(country) {
7 | const url = `${BASE}/${country}?apikey=shizo`;
8 | const res = await fetch(url);
9 | if (!res.ok) throw new Error(`HTTP ${res.status}`);
10 | const contentType = res.headers.get('content-type') || '';
11 | if (!contentType.includes('image')) throw new Error('API did not return an image');
12 | return res.buffer();
13 | }
14 |
15 | async function piesCommand(sock, chatId, message, args) {
16 | const sub = (args && args[0] ? args[0] : '').toLowerCase();
17 | if (!sub) {
18 | await sock.sendMessage(chatId, { text: `Usage: .pies \nCountries: ${VALID_COUNTRIES.join(', ')}` }, { quoted: message });
19 | return;
20 | }
21 | if (!VALID_COUNTRIES.includes(sub)) {
22 | await sock.sendMessage(chatId, { text: `❌ Unsupported country: ${sub}. Try one of: ${VALID_COUNTRIES.join(', ')}` }, { quoted: message });
23 | return;
24 | }
25 | try {
26 | const imageBuffer = await fetchPiesImageBuffer(sub);
27 | await sock.sendMessage(
28 | chatId,
29 | { image: imageBuffer, caption: `pies: ${sub}` },
30 | { quoted: message }
31 | );
32 | } catch (err) {
33 | console.error('Error in pies command:', err);
34 | await sock.sendMessage(chatId, { text: '❌ Failed to fetch image. Please try again.' }, { quoted: message });
35 | }
36 | }
37 |
38 | async function piesAlias(sock, chatId, message, country) {
39 | try {
40 | const imageBuffer = await fetchPiesImageBuffer(country);
41 | await sock.sendMessage(
42 | chatId,
43 | { image: imageBuffer, caption: `pies: ${country}` },
44 | { quoted: message }
45 | );
46 | } catch (err) {
47 | console.error(`Error in pies alias (${country}) command:`, err);
48 | await sock.sendMessage(chatId, { text: '❌ Failed to fetch image. Please try again.' }, { quoted: message });
49 | }
50 | }
51 |
52 | module.exports = { piesCommand, piesAlias, VALID_COUNTRIES };
53 |
--------------------------------------------------------------------------------
/commands/hangman.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 |
3 | const words = ['javascript', 'bot', 'hangman', 'whatsapp', 'nodejs'];
4 | let hangmanGames = {};
5 |
6 | function startHangman(sock, chatId) {
7 | const word = words[Math.floor(Math.random() * words.length)];
8 | const maskedWord = '_ '.repeat(word.length).trim();
9 |
10 | hangmanGames[chatId] = {
11 | word,
12 | maskedWord: maskedWord.split(' '),
13 | guessedLetters: [],
14 | wrongGuesses: 0,
15 | maxWrongGuesses: 6,
16 | };
17 |
18 | sock.sendMessage(chatId, { text: `Game started! The word is: ${maskedWord}` });
19 | }
20 |
21 | function guessLetter(sock, chatId, letter) {
22 | if (!hangmanGames[chatId]) {
23 | sock.sendMessage(chatId, { text: 'No game in progress. Start a new game with .hangman' });
24 | return;
25 | }
26 |
27 | const game = hangmanGames[chatId];
28 | const { word, guessedLetters, maskedWord, maxWrongGuesses } = game;
29 |
30 | if (guessedLetters.includes(letter)) {
31 | sock.sendMessage(chatId, { text: `You already guessed "${letter}". Try another letter.` });
32 | return;
33 | }
34 |
35 | guessedLetters.push(letter);
36 |
37 | if (word.includes(letter)) {
38 | for (let i = 0; i < word.length; i++) {
39 | if (word[i] === letter) {
40 | maskedWord[i] = letter;
41 | }
42 | }
43 | sock.sendMessage(chatId, { text: `Good guess! ${maskedWord.join(' ')}` });
44 |
45 | if (!maskedWord.includes('_')) {
46 | sock.sendMessage(chatId, { text: `Congratulations! You guessed the word: ${word}` });
47 | delete hangmanGames[chatId];
48 | }
49 | } else {
50 | game.wrongGuesses += 1;
51 | sock.sendMessage(chatId, { text: `Wrong guess! You have ${maxWrongGuesses - game.wrongGuesses} tries left.` });
52 |
53 | if (game.wrongGuesses >= maxWrongGuesses) {
54 | sock.sendMessage(chatId, { text: `Game over! The word was: ${word}` });
55 | delete hangmanGames[chatId];
56 | }
57 | }
58 | }
59 |
60 | module.exports = { startHangman, guessLetter };
61 |
--------------------------------------------------------------------------------
/commands/simage.js:
--------------------------------------------------------------------------------
1 | const sharp = require('sharp');
2 | const fs = require('fs');
3 | const fsPromises = require('fs/promises');
4 | const fse = require('fs-extra');
5 | const path = require('path');
6 | const { downloadContentFromMessage } = require('@whiskeysockets/baileys');
7 |
8 | const tempDir = './temp';
9 | if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir);
10 |
11 | const scheduleFileDeletion = (filePath) => {
12 | setTimeout(async () => {
13 | try {
14 | await fse.remove(filePath);
15 | console.log(`File deleted: ${filePath}`);
16 | } catch (error) {
17 | console.error(`Failed to delete file:`, error);
18 | }
19 | }, 10000); // 5 minutes
20 | };
21 |
22 | const convertStickerToImage = async (sock, quotedMessage, chatId) => {
23 | try {
24 | const stickerMessage = quotedMessage.stickerMessage;
25 | if (!stickerMessage) {
26 | await sock.sendMessage(chatId, { text: 'Reply to a sticker with .simage to convert it.' });
27 | return;
28 | }
29 |
30 | const stickerFilePath = path.join(tempDir, `sticker_${Date.now()}.webp`);
31 | const outputImagePath = path.join(tempDir, `converted_image_${Date.now()}.png`);
32 |
33 | const stream = await downloadContentFromMessage(stickerMessage, 'sticker');
34 | let buffer = Buffer.from([]);
35 | for await (const chunk of stream) buffer = Buffer.concat([buffer, chunk]);
36 |
37 | await fsPromises.writeFile(stickerFilePath, buffer);
38 | await sharp(stickerFilePath).toFormat('png').toFile(outputImagePath);
39 |
40 | const imageBuffer = await fsPromises.readFile(outputImagePath);
41 | await sock.sendMessage(chatId, { image: imageBuffer, caption: 'Here is the converted image!' });
42 |
43 | scheduleFileDeletion(stickerFilePath);
44 | scheduleFileDeletion(outputImagePath);
45 | } catch (error) {
46 | console.error('Error converting sticker to image:', error);
47 | await sock.sendMessage(chatId, { text: 'An error occurred while converting the sticker.' });
48 | }
49 | };
50 |
51 | module.exports = convertStickerToImage;
52 |
--------------------------------------------------------------------------------
/commands/wasted.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const { channelInfo } = require('../lib/messageConfig');
3 |
4 | async function wastedCommand(sock, chatId, message) {
5 | let userToWaste;
6 |
7 | // Check for mentioned users
8 | if (message.message?.extendedTextMessage?.contextInfo?.mentionedJid?.length > 0) {
9 | userToWaste = message.message.extendedTextMessage.contextInfo.mentionedJid[0];
10 | }
11 | // Check for replied message
12 | else if (message.message?.extendedTextMessage?.contextInfo?.participant) {
13 | userToWaste = message.message.extendedTextMessage.contextInfo.participant;
14 | }
15 |
16 | if (!userToWaste) {
17 | await sock.sendMessage(chatId, {
18 | text: 'Please mention someone or reply to their message to waste them!',
19 | ...channelInfo
20 | }, { quoted: message });
21 | return;
22 | }
23 |
24 | try {
25 | // Get user's profile picture
26 | let profilePic;
27 | try {
28 | profilePic = await sock.profilePictureUrl(userToWaste, 'image');
29 | } catch {
30 | profilePic = 'https://i.imgur.com/2wzGhpF.jpeg'; // Default image if no profile pic
31 | }
32 |
33 | // Get the wasted effect image
34 | const wastedResponse = await axios.get(
35 | `https://some-random-api.com/canvas/overlay/wasted?avatar=${encodeURIComponent(profilePic)}`,
36 | { responseType: 'arraybuffer' }
37 | );
38 |
39 | // Send the wasted image
40 | await sock.sendMessage(chatId, {
41 | image: Buffer.from(wastedResponse.data),
42 | caption: `⚰️ *Wasted* : ${userToWaste.split('@')[0]} 💀\n\nRest in pieces!`,
43 | mentions: [userToWaste],
44 | ...channelInfo
45 | });
46 |
47 | } catch (error) {
48 | console.error('Error in wasted command:', error);
49 | await sock.sendMessage(chatId, {
50 | text: 'Failed to create wasted image! Try again later.',
51 | ...channelInfo
52 | }, { quoted: message });
53 | }
54 | }
55 |
56 | module.exports = wastedCommand;
--------------------------------------------------------------------------------
/commands/ss.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function handleSsCommand(sock, chatId, message, match) {
4 | if (!match) {
5 | await sock.sendMessage(chatId, {
6 | text: `*SCREENSHOT TOOL*\n\n*.ss *\n*.ssweb *\n*.screenshot *\n\nTake a screenshot of any website\n\nExample:\n.ss https://google.com\n.ssweb https://google.com\n.screenshot https://google.com`,
7 | quoted: message
8 | });
9 | return;
10 | }
11 |
12 | try {
13 | // Show typing indicator
14 | await sock.presenceSubscribe(chatId);
15 | await sock.sendPresenceUpdate('composing', chatId);
16 |
17 | // Extract URL from command
18 | const url = match.trim();
19 |
20 | // Validate URL
21 | if (!url.startsWith('http://') && !url.startsWith('https://')) {
22 | return sock.sendMessage(chatId, {
23 | text: '❌ Please provide a valid URL starting with http:// or https://',
24 | quoted: message
25 | });
26 | }
27 |
28 | // Call the API
29 | const apiUrl = `https://api.siputzx.my.id/api/tools/ssweb?url=${encodeURIComponent(url)}&theme=light&device=desktop`;
30 | const response = await fetch(apiUrl, { headers: { 'accept': '*/*' } });
31 |
32 | if (!response.ok) {
33 | throw new Error(`API responded with status: ${response.status}`);
34 | }
35 |
36 | // Get the image buffer
37 | const imageBuffer = await response.buffer();
38 |
39 | // Send the screenshot
40 | await sock.sendMessage(chatId, {
41 | image: imageBuffer,
42 | }, {
43 | quoted: message
44 | });
45 |
46 | } catch (error) {
47 | console.error('❌ Error in ss command:', error);
48 | await sock.sendMessage(chatId, {
49 | text: '❌ Failed to take screenshot. Please try again in a few minutes.\n\nPossible reasons:\n• Invalid URL\n• Website is blocking screenshots\n• Website is down\n• API service is temporarily unavailable',
50 | quoted: message
51 | });
52 | }
53 | }
54 |
55 | module.exports = {
56 | handleSsCommand
57 | };
--------------------------------------------------------------------------------
/commands/play.js:
--------------------------------------------------------------------------------
1 | const yts = require('yt-search');
2 | const axios = require('axios');
3 |
4 | async function playCommand(sock, chatId, message) {
5 | try {
6 | const text = message.message?.conversation || message.message?.extendedTextMessage?.text;
7 | const searchQuery = text.split(' ').slice(1).join(' ').trim();
8 |
9 | if (!searchQuery) {
10 | return await sock.sendMessage(chatId, {
11 | text: "What song do you want to download?"
12 | });
13 | }
14 |
15 | // Search for the song
16 | const { videos } = await yts(searchQuery);
17 | if (!videos || videos.length === 0) {
18 | return await sock.sendMessage(chatId, {
19 | text: "No songs found!"
20 | });
21 | }
22 |
23 | // Send loading message
24 | await sock.sendMessage(chatId, {
25 | text: "_Please wait your download is in progress_"
26 | });
27 |
28 | // Get the first video result
29 | const video = videos[0];
30 | const urlYt = video.url;
31 |
32 | // Fetch audio data from API
33 | const response = await axios.get(`https://apis-keith.vercel.app/download/dlmp3?url=${urlYt}`);
34 | const data = response.data;
35 |
36 | if (!data || !data.status || !data.result || !data.result.downloadUrl) {
37 | return await sock.sendMessage(chatId, {
38 | text: "Failed to fetch audio from the API. Please try again later."
39 | });
40 | }
41 |
42 | const audioUrl = data.result.downloadUrl;
43 | const title = data.result.title;
44 |
45 | // Send the audio
46 | await sock.sendMessage(chatId, {
47 | audio: { url: audioUrl },
48 | mimetype: "audio/mpeg",
49 | fileName: `${title}.mp3`
50 | }, { quoted: message });
51 |
52 | } catch (error) {
53 | console.error('Error in song2 command:', error);
54 | await sock.sendMessage(chatId, {
55 | text: "Download failed. Please try again later."
56 | });
57 | }
58 | }
59 |
60 | module.exports = playCommand;
61 |
62 | /*Powered by KNIGHT-BOT*
63 | *Credits to Keith MD*`*/
--------------------------------------------------------------------------------
/lib/tictactoe.js:
--------------------------------------------------------------------------------
1 | class TicTacToe {
2 | constructor(playerX = 'x', playerO = 'o') {
3 | this.playerX = playerX;
4 | this.playerO = playerO;
5 | this._currentTurn = false;
6 | this._x = 0;
7 | this._o = 0;
8 | this.turns = 0;
9 | }
10 |
11 | get board() {
12 | return this._x | this._o;
13 | }
14 |
15 | get currentTurn() {
16 | return this._currentTurn ? this.playerO : this.playerX;
17 | }
18 |
19 | get winner() {
20 | // All possible winning combinations
21 | const winningPatterns = [
22 | 0b111000000, // Top row
23 | 0b000111000, // Middle row
24 | 0b000000111, // Bottom row
25 | 0b100100100, // Left column
26 | 0b010010010, // Middle column
27 | 0b001001001, // Right column
28 | 0b100010001, // Diagonal from top-left
29 | 0b001010100 // Diagonal from top-right
30 | ];
31 |
32 | // Check X's moves
33 | for (let pattern of winningPatterns) {
34 | if ((this._x & pattern) === pattern) {
35 | return this.playerX;
36 | }
37 | }
38 |
39 | // Check O's moves
40 | for (let pattern of winningPatterns) {
41 | if ((this._o & pattern) === pattern) {
42 | return this.playerO;
43 | }
44 | }
45 |
46 | return null;
47 | }
48 |
49 | turn(player, pos) {
50 | // If game is over or invalid position
51 | if (this.winner || pos < 0 || pos > 8) return -1;
52 |
53 | // If position is already taken
54 | if ((this._x | this._o) & (1 << pos)) return 0;
55 |
56 | // Make the move
57 | const value = 1 << pos;
58 | if (this._currentTurn) {
59 | this._o |= value;
60 | } else {
61 | this._x |= value;
62 | }
63 |
64 | this._currentTurn = !this._currentTurn;
65 | this.turns++;
66 | return 1;
67 | }
68 |
69 | render() {
70 | return [...Array(9)].map((_, i) => {
71 | const bit = 1 << i;
72 | return this._x & bit ? 'X' : this._o & bit ? 'O' : i + 1;
73 | });
74 | }
75 | }
76 |
77 | module.exports = TicTacToe;
--------------------------------------------------------------------------------
/commands/getpp.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 |
3 | async function getppCommand(sock, chatId, message) {
4 | try {
5 | // Check if user is owner
6 | const isOwner = message.key.fromMe; // Fixed variable name from 'msg' to 'message'
7 | if (!isOwner) {
8 | await sock.sendMessage(chatId, {
9 | text: '😡 Command only for the owner.'
10 | });
11 | return;
12 | }
13 |
14 | let userToAnalyze;
15 |
16 | // Check for mentioned users
17 | if (message.message?.extendedTextMessage?.contextInfo?.mentionedJid?.length > 0) {
18 | userToAnalyze = message.message.extendedTextMessage.contextInfo.mentionedJid[0];
19 | }
20 | // Check for replied message
21 | else if (message.message?.extendedTextMessage?.contextInfo?.participant) {
22 | userToAnalyze = message.message.extendedTextMessage.contextInfo.participant;
23 | }
24 |
25 | if (!userToAnalyze) {
26 | await sock.sendMessage(chatId, {
27 | text: 'Please mention someone or reply to their message to get their profile picture!'
28 | });
29 | return;
30 | }
31 |
32 | try {
33 | // Get user's profile picture
34 | let profilePic;
35 | try {
36 | profilePic = await sock.profilePictureUrl(userToAnalyze, 'image');
37 | } catch {
38 | profilePic = 'https://files.catbox.moe/lvcwnf.jpg'; // Default image
39 | }
40 |
41 | // Send the profile picture to the chat
42 | await sock.sendMessage(chatId, {
43 | image: { url: profilePic },
44 | caption: `The profile picture of @${userToAnalyze.split('@')[0]}`,
45 | mentions: [userToAnalyze]
46 | });
47 |
48 | } catch (error) {
49 | console.error('Error in getpp command:', error);
50 | await sock.sendMessage(chatId, {
51 | text: 'Failed to retrieve profile picture. The user might not have one set.'
52 | });
53 | }
54 | } catch (error) {
55 | console.error('Unexpected error in getppCommand:', error);
56 | }
57 | }
58 |
59 | module.exports = getppCommand; // Moved outside the function
60 |
--------------------------------------------------------------------------------
/commands/simp.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function simpCommand(sock, chatId, quotedMsg, mentionedJid, sender) {
4 | try {
5 | // Determine the target user
6 | let who = quotedMsg
7 | ? quotedMsg.sender
8 | : mentionedJid && mentionedJid[0]
9 | ? mentionedJid[0]
10 | : sender;
11 |
12 | // Get the profile picture URL
13 | let avatarUrl;
14 | try {
15 | avatarUrl = await sock.profilePictureUrl(who, 'image');
16 | } catch (error) {
17 | console.error('Error fetching profile picture:', error);
18 | avatarUrl = 'https://telegra.ph/file/24fa902ead26340f3df2c.png'; // Default avatar
19 | }
20 |
21 | // Fetch the simp card from the API
22 | const apiUrl = `https://some-random-api.com/canvas/misc/simpcard?avatar=${encodeURIComponent(avatarUrl)}`;
23 | const response = await fetch(apiUrl);
24 |
25 | if (!response.ok) {
26 | throw new Error(`API responded with status: ${response.status}`);
27 | }
28 |
29 | // Get the image buffer
30 | const imageBuffer = await response.buffer();
31 |
32 | // Send the image with caption
33 | await sock.sendMessage(chatId, {
34 | image: imageBuffer,
35 | caption: '*your religion is simping*',
36 | contextInfo: {
37 | forwardingScore: 1,
38 | isForwarded: true,
39 | forwardedNewsletterMessageInfo: {
40 | newsletterJid: '120363399707841760@newsletter',
41 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
42 | serverMessageId: -1
43 | }
44 | }
45 | });
46 |
47 | } catch (error) {
48 | console.error('Error in simp command:', error);
49 | await sock.sendMessage(chatId, {
50 | text: '❌ Sorry, I couldn\'t generate the simp card. Please try again later!',
51 | contextInfo: {
52 | forwardingScore: 1,
53 | isForwarded: true,
54 | forwardedNewsletterMessageInfo: {
55 | newsletterJid: '120363399707841760@newsletter',
56 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
57 | serverMessageId: -1
58 | }
59 | }
60 | });
61 | }
62 | }
63 |
64 | module.exports = { simpCommand };
--------------------------------------------------------------------------------
/commands/alive.js:
--------------------------------------------------------------------------------
1 | const settings = require("../settings");
2 | const axios = require('axios');
3 | const fs = require('fs');
4 | const path = require('path');
5 | const { tmpdir } = require('os');
6 |
7 | async function downloadImage(url) {
8 | try {
9 | const response = await axios.get(url, { responseType: 'arraybuffer' });
10 | const tempPath = path.join(tmpdir(), `zuko_alive_${Date.now()}.jpg`);
11 | await fs.promises.writeFile(tempPath, response.data);
12 | return tempPath;
13 | } catch (error) {
14 | console.error('Error downloading image:', error);
15 | return null;
16 | }
17 | }
18 |
19 | async function aliveCommand(sock, chatId) {
20 | try {
21 | const message = `
22 | ╭━━━━━━━━━━━━━━━━━━━╮
23 | ┃ ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3
24 | ╰━━━━━━━━━━━━━━━━━━━╯
25 | ┌───────────────────┐
26 | │ 🔹 *Status*: Online
27 | │ 🔸 *Version*: ${settings.version}
28 | │ 🔹 *Mode*: Public
29 | ├───────────────────
30 | │ 👽 *Features*:
31 | │ • Group Management
32 | │ • Antilink Protection
33 | │ • Fun Commands
34 | │ • Media Tools
35 | │ • AI Features
36 | ├───────────────────
37 | `.trim();
38 |
39 | const imageUrl = 'https://files.catbox.moe/j9eknp.jpg';
40 | const imagePath = await downloadImage(imageUrl);
41 |
42 | const messageOptions = {
43 | contextInfo: {
44 | forwardingScore: 999,
45 | isForwarded: true,
46 | forwardedNewsletterMessageInfo: {
47 | newsletterJid: '120363399707841760@newsletter',
48 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
49 | serverMessageId: -1
50 | }
51 | }
52 | };
53 |
54 | if (imagePath) {
55 | try {
56 | messageOptions.image = fs.readFileSync(imagePath);
57 | messageOptions.caption = message;
58 | } finally {
59 | // Clean up the downloaded image
60 | fs.unlink(imagePath, () => {});
61 | }
62 | } else {
63 | messageOptions.text = message;
64 | }
65 |
66 | await sock.sendMessage(chatId, messageOptions);
67 | } catch (error) {
68 | console.error('Error in alive command:', error);
69 | await sock.sendMessage(chatId, {
70 | text: '╭━━━━━━━━━━━╮\n┃ ❗ Error ┃\n╰━━━━━━━━━━━╯\nBot is active but status unavailable'
71 | });
72 | }
73 | }
74 |
75 | module.exports = aliveCommand;
--------------------------------------------------------------------------------
/commands/kick.js:
--------------------------------------------------------------------------------
1 | const isAdmin = require('../lib/isAdmin');
2 |
3 | async function kickCommand(sock, chatId, senderId, mentionedJids, message) {
4 | // Check if user is owner
5 | const isOwner = message.key.fromMe;
6 | if (!isOwner) {
7 | const { isSenderAdmin, isBotAdmin } = await isAdmin(sock, chatId, senderId);
8 |
9 | if (!isBotAdmin) {
10 | await sock.sendMessage(chatId, { text: 'Please make the bot an admin first.' }, { quoted: message });
11 | return;
12 | }
13 |
14 | if (!isSenderAdmin) {
15 | await sock.sendMessage(chatId, { text: 'Only group admins can use the kick command.' }, { quoted: message });
16 | return;
17 | }
18 | }
19 |
20 | let usersToKick = [];
21 |
22 | // Check for mentioned users
23 | if (mentionedJids && mentionedJids.length > 0) {
24 | usersToKick = mentionedJids;
25 | }
26 | // Check for replied message
27 | else if (message.message?.extendedTextMessage?.contextInfo?.participant) {
28 | usersToKick = [message.message.extendedTextMessage.contextInfo.participant];
29 | }
30 |
31 | // If no user found through either method
32 | if (usersToKick.length === 0) {
33 | await sock.sendMessage(chatId, {
34 | text: 'Please mention the user or reply to their message to kick!'
35 | }, { quoted: message });
36 | return;
37 | }
38 |
39 | // Get bot's ID
40 | const botId = sock.user.id.split(':')[0] + '@s.whatsapp.net';
41 |
42 | // Check if any of the users to kick is the bot itself
43 | if (usersToKick.includes(botId)) {
44 | await sock.sendMessage(chatId, {
45 | text: "I can't kick myself! 🤖"
46 | }, { quoted: message });
47 | return;
48 | }
49 |
50 | try {
51 | await sock.groupParticipantsUpdate(chatId, usersToKick, "remove");
52 |
53 | // Get usernames for each kicked user
54 | const usernames = await Promise.all(usersToKick.map(async jid => {
55 | return `@${jid.split('@')[0]}`;
56 | }));
57 |
58 | await sock.sendMessage(chatId, {
59 | text: `${usernames.join(', ')} has been kicked successfully!`,
60 | mentions: usersToKick
61 | });
62 | } catch (error) {
63 | console.error('Error in kick command:', error);
64 | await sock.sendMessage(chatId, {
65 | text: 'Failed to kick user(s)!'
66 | });
67 | }
68 | }
69 |
70 | module.exports = kickCommand;
71 |
--------------------------------------------------------------------------------
/commands/sticker-alt.js:
--------------------------------------------------------------------------------
1 | const { downloadContentFromMessage } = require('@whiskeysockets/baileys');
2 | const { exec } = require('child_process');
3 | const fs = require('fs');
4 |
5 | async function stickerCommand(sock, chatId, message) {
6 | try {
7 | const quotedMsg = message.message.extendedTextMessage?.contextInfo?.quotedMessage;
8 | if (!quotedMsg) {
9 | await sock.sendMessage(chatId, { text: 'Please reply to an image or video!' });
10 | return;
11 | }
12 |
13 | const type = Object.keys(quotedMsg)[0];
14 | if (!['imageMessage', 'videoMessage'].includes(type)) {
15 | await sock.sendMessage(chatId, { text: 'Please reply to an image or video!' });
16 | return;
17 | }
18 |
19 | const stream = await downloadContentFromMessage(quotedMsg[type], type.split('Message')[0]);
20 | let buffer = Buffer.from([]);
21 | for await (const chunk of stream) {
22 | buffer = Buffer.concat([buffer, chunk]);
23 | }
24 |
25 | const tempInput = `./temp/temp_${Date.now()}.${type === 'imageMessage' ? 'jpg' : 'mp4'}`;
26 | const tempOutput = `./temp/sticker_${Date.now()}.webp`;
27 |
28 | // Create temp directory if it doesn't exist
29 | if (!fs.existsSync('./temp')) {
30 | fs.mkdirSync('./temp', { recursive: true });
31 | }
32 |
33 | fs.writeFileSync(tempInput, buffer);
34 |
35 | // Convert to WebP using ffmpeg
36 | await new Promise((resolve, reject) => {
37 | const cmd = type === 'imageMessage'
38 | ? `ffmpeg -i "${tempInput}" -vf "scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease" "${tempOutput}"`
39 | : `ffmpeg -i "${tempInput}" -vf "scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease" -c:v libwebp -preset default -loop 0 -vsync 0 -t 6 "${tempOutput}"`;
40 |
41 | exec(cmd, (error) => {
42 | if (error) reject(error);
43 | else resolve();
44 | });
45 | });
46 |
47 | await sock.sendMessage(chatId, {
48 | sticker: fs.readFileSync(tempOutput)
49 | });
50 |
51 | // Cleanup
52 | fs.unlinkSync(tempInput);
53 | fs.unlinkSync(tempOutput);
54 |
55 | } catch (error) {
56 | console.error('Error in sticker command:', error);
57 | await sock.sendMessage(chatId, { text: 'Failed to create sticker!' });
58 | }
59 | }
60 |
61 | module.exports = stickerCommand;
--------------------------------------------------------------------------------
/lib/converter.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Knight Bot - A WhatsApp Bot
3 | * Copyright (c) 2024 Professor
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the MIT License.
7 | *
8 | * Credits:
9 | * - Baileys Library by @adiwajshing
10 | * - Pair Code implementation inspired by TechGod143 & DGXEON
11 | */
12 | const fs = require('fs')
13 | const path = require('path')
14 | const { spawn } = require('child_process')
15 |
16 | function ffmpeg(buffer, args = [], ext = '', ext2 = '') {
17 | return new Promise(async (resolve, reject) => {
18 | try {
19 | let tmp = path.join(__dirname, '../database', + new Date + '.' + ext)
20 | let out = tmp + '.' + ext2
21 | await fs.promises.writeFile(tmp, buffer)
22 | spawn('ffmpeg', [
23 | '-y',
24 | '-i', tmp,
25 | ...args,
26 | out
27 | ])
28 | .on('error', reject)
29 | .on('close', async (code) => {
30 | try {
31 | await fs.promises.unlink(tmp)
32 | if (code !== 0) return reject(code)
33 | resolve(await fs.promises.readFile(out))
34 | await fs.promises.unlink(out)
35 | } catch (e) {
36 | reject(e)
37 | }
38 | })
39 | } catch (e) {
40 | reject(e)
41 | }
42 | })
43 | }
44 |
45 | /**
46 | * Convert Audio to Playable WhatsApp Audio
47 | * @param {Buffer} buffer Audio Buffer
48 | * @param {String} ext File Extension
49 | */
50 | function toAudio(buffer, ext) {
51 | return ffmpeg(buffer, [
52 | '-vn',
53 | '-ac', '2',
54 | '-b:a', '128k',
55 | '-ar', '44100',
56 | '-f', 'mp3'
57 | ], ext, 'mp3')
58 | }
59 |
60 | /**
61 | * Convert Audio to Playable WhatsApp PTT
62 | * @param {Buffer} buffer Audio Buffer
63 | * @param {String} ext File Extension
64 | */
65 | function toPTT(buffer, ext) {
66 | return ffmpeg(buffer, [
67 | '-vn',
68 | '-c:a', 'libopus',
69 | '-b:a', '128k',
70 | '-vbr', 'on',
71 | '-compression_level', '10'
72 | ], ext, 'opus')
73 | }
74 |
75 | /**
76 | * Convert Audio to Playable WhatsApp Video
77 | * @param {Buffer} buffer Video Buffer
78 | * @param {String} ext File Extension
79 | */
80 | function toVideo(buffer, ext) {
81 | return ffmpeg(buffer, [
82 | '-c:v', 'libx264',
83 | '-c:a', 'aac',
84 | '-ab', '128k',
85 | '-ar', '44100',
86 | '-crf', '32',
87 | '-preset', 'slow'
88 | ], ext, 'mp4')
89 | }
90 |
91 | module.exports = {
92 | toAudio,
93 | toPTT,
94 | toVideo,
95 | ffmpeg,
96 | }
--------------------------------------------------------------------------------
/commands/setpp.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const { downloadContentFromMessage } = require('@whiskeysockets/baileys');
4 |
5 | async function setProfilePicture(sock, chatId, msg) {
6 | try {
7 | // Check if user is owner
8 | const isOwner = msg.key.fromMe;
9 | if (!isOwner) {
10 | await sock.sendMessage(chatId, {
11 | text: '❌ This command is only available for the owner!'
12 | });
13 | return;
14 | }
15 |
16 | // Check if message is a reply
17 | const quotedMessage = msg.message?.extendedTextMessage?.contextInfo?.quotedMessage;
18 | if (!quotedMessage) {
19 | await sock.sendMessage(chatId, {
20 | text: '⚠️ Please reply to an image with the .setpp command!'
21 | });
22 | return;
23 | }
24 |
25 | // Check if quoted message contains an image
26 | const imageMessage = quotedMessage.imageMessage || quotedMessage.stickerMessage;
27 | if (!imageMessage) {
28 | await sock.sendMessage(chatId, {
29 | text: '❌ The replied message must contain an image!'
30 | });
31 | return;
32 | }
33 |
34 | // Create tmp directory if it doesn't exist
35 | const tmpDir = path.join(process.cwd(), 'tmp');
36 | if (!fs.existsSync(tmpDir)) {
37 | fs.mkdirSync(tmpDir, { recursive: true });
38 | }
39 |
40 | // Download the image
41 | const stream = await downloadContentFromMessage(imageMessage, 'image');
42 | let buffer = Buffer.from([]);
43 |
44 | for await (const chunk of stream) {
45 | buffer = Buffer.concat([buffer, chunk]);
46 | }
47 |
48 | const imagePath = path.join(tmpDir, `profile_${Date.now()}.jpg`);
49 |
50 | // Save the image
51 | fs.writeFileSync(imagePath, buffer);
52 |
53 | // Set the profile picture
54 | await sock.updateProfilePicture(sock.user.id, { url: imagePath });
55 |
56 | // Clean up the temporary file
57 | fs.unlinkSync(imagePath);
58 |
59 | await sock.sendMessage(chatId, {
60 | text: '✅ Successfully updated bot profile picture!'
61 | });
62 |
63 | } catch (error) {
64 | console.error('Error in setpp command:', error);
65 | await sock.sendMessage(chatId, {
66 | text: '❌ Failed to update profile picture!'
67 | });
68 | }
69 | }
70 |
71 | module.exports = setProfilePicture;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "knightbot",
3 | "version": "1.0.0",
4 | "description": "WhatsApp Bot",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "start:optimized": "node --max-old-space-size=512 --optimize-for-size --gc-interval=100 index.js",
9 | "cleanup": "node cleanup.js",
10 | "reset-session": "node reset-session.js",
11 | "start:clean": "npm run cleanup && npm run start:optimized",
12 | "start:fresh": "npm run reset-session && npm start",
13 | "install:panel": "npm install --legacy-peer-deps",
14 | "install:force": "npm install --force",
15 | "test": "echo \"Error: no test specified\" && exit 1",
16 | "docker:build": "docker build -t docker run -e SESSION_ID=$SESSION_ID knightbot"
17 | },
18 | "keywords": [
19 | "whatsapp-bot"
20 | ],
21 | "author": "",
22 | "license": "ISC",
23 | "dependencies": {
24 | "@adiwajshing/keyed-db": "^0.2.4",
25 | "@ffmpeg/ffmpeg": "^0.12.15",
26 | "@hapi/boom": "^10.0.1",
27 | "@types/node": "^18.0.6",
28 | "@whiskeysockets/baileys": "^6.7.18",
29 | "awesome-phonenumber": "^5.9.0",
30 | "axios": "^1.8.4",
31 | "chalk": "^4.1.2",
32 | "cheerio": "^1.0.0-rc.12",
33 | "cookie": "^0.5.0",
34 | "dotenv": "^16.4.5",
35 | "events": "^3.3.0",
36 | "file-type": "^16.5.4",
37 | "fluent-ffmpeg": "^2.1.3",
38 | "form-data": "^4.0.1",
39 | "fs-extra": "^11.2.0",
40 | "gtts": "^0.2.1",
41 | "human-readable": "^0.2.1",
42 | "jimp": "^1.6.0",
43 | "jsdom": "^22.1.0",
44 | "libphonenumber-js": "^1.11.18",
45 | "libsignal": "^2.0.1",
46 | "link-preview-js": "^3.0.5",
47 | "moment-timezone": "^0.5.43",
48 | "mumaker": "^2.0.0",
49 | "node-cache": "^5.1.2",
50 | "node-fetch": "^2.7.0",
51 | "node-id3": "^0.2.3",
52 | "node-webpmux": "^3.1.0",
53 | "node-youtube-music": "^0.8.3",
54 | "performance-now": "^2.1.0",
55 | "phin": "^3.7.1",
56 | "pino": "^8.21.0",
57 | "qrcode": "^1.5.4",
58 | "qrcode-reader": "^1.0.4",
59 | "qrcode-terminal": "^0.12.0",
60 | "request": "^2.88.2",
61 | "ruhend-scraper": "^8.3.0",
62 | "safe-stable-stringify": "^2.5.0",
63 | "set-cookie": "^0.0.4",
64 | "sharp": "^0.32.6",
65 | "tough-cookie": "^5.0.0",
66 | "translate-google-api": "^1.0.4",
67 | "ws": "^8.17.1",
68 | "yargs": "^17.6.0",
69 | "yargs-parser": "^21.1.1",
70 | "youtube-yts": "^2.0.0",
71 | "youtubedl-core": "^4.11.7",
72 | "yt-search": "^2.12.1",
73 | "ytdl-core": "^4.11.5"
74 | },
75 | "overrides": {
76 | "jimp": "^1.6.0"
77 | },
78 | "engines": {
79 | "node": ">=18.0.0"
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/lib/antilink.js:
--------------------------------------------------------------------------------
1 | const { isJidGroup } = require('@whiskeysockets/baileys');
2 | const { getAntilink, incrementWarningCount, resetWarningCount, isSudo } = require('../lib/index');
3 | const config = require('../config');
4 |
5 | const WARN_COUNT = config.WARN_COUNT || 3;
6 |
7 | /**
8 | * Checks if a string contains a URL.
9 | *
10 | * @param {string} str - The string to check.
11 | * @returns {boolean} - True if the string contains a URL, otherwise false.
12 | */
13 | function containsURL(str) {
14 | const urlRegex = /(https?:\/\/)?([a-z0-9-]+\.)+[a-z]{2,}(\/[^\s]*)?/i;
15 | return urlRegex.test(str);
16 | }
17 |
18 | /**
19 | * Handles the Antilink functionality for group chats.
20 | *
21 | * @param {object} msg - The message object to process.
22 | * @param {object} sock - The socket object to use for sending messages.
23 | */
24 | async function Antilink(msg, sock) {
25 | const jid = msg.key.remoteJid;
26 | if (!isJidGroup(jid)) return;
27 |
28 | const SenderMessage = msg.message?.conversation ||
29 | msg.message?.extendedTextMessage?.text || '';
30 | if (!SenderMessage || typeof SenderMessage !== 'string') return;
31 |
32 | const sender = msg.key.participant;
33 | if (!sender) return;
34 |
35 | // Skip if sender is admin or sudo
36 | const isAdmin = await isSudo(sender);
37 | if (isAdmin) return;
38 |
39 | if (!containsURL(SenderMessage.trim())) return;
40 |
41 | const antilinkConfig = await getAntilink(jid, 'on');
42 | if (!antilinkConfig) return;
43 |
44 | const action = antilinkConfig.action;
45 |
46 | try {
47 | // Delete message first
48 | await sock.sendMessage(jid, { delete: msg.key });
49 |
50 | switch (action) {
51 | case 'delete':
52 | await sock.sendMessage(jid, {
53 | text: `\`\`\`@${sender.split('@')[0]} link are not allowed here\`\`\``,
54 | mentions: [sender]
55 | });
56 | break;
57 |
58 | case 'kick':
59 | await sock.groupParticipantsUpdate(jid, [sender], 'remove');
60 | await sock.sendMessage(jid, {
61 | text: `\`\`\`@${sender.split('@')[0]} has been kicked for sending links\`\`\``,
62 | mentions: [sender]
63 | });
64 | break;
65 |
66 | case 'warn':
67 | const warningCount = await incrementWarningCount(jid, sender);
68 | if (warningCount >= WARN_COUNT) {
69 | await sock.groupParticipantsUpdate(jid, [sender], 'remove');
70 | await resetWarningCount(jid, sender);
71 | await sock.sendMessage(jid, {
72 | text: `\`\`\`@${sender.split('@')[0]} has been kicked after ${WARN_COUNT} warnings\`\`\``,
73 | mentions: [sender]
74 | });
75 | } else {
76 | await sock.sendMessage(jid, {
77 | text: `\`\`\`@${sender.split('@')[0]} warning ${warningCount}/${WARN_COUNT} for sending links\`\`\``,
78 | mentions: [sender]
79 | });
80 | }
81 | break;
82 | }
83 | } catch (error) {
84 | console.error('Error in Antilink:', error);
85 | }
86 | }
87 |
88 | module.exports = { Antilink };
--------------------------------------------------------------------------------
/commands/imagine.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const { fetchBuffer } = require('../lib/myfunc');
3 |
4 | async function imagineCommand(sock, chatId, message) {
5 | try {
6 | // Get the prompt from the message
7 | const prompt = message.message?.conversation?.trim() ||
8 | message.message?.extendedTextMessage?.text?.trim() || '';
9 |
10 | // Remove the command prefix and trim
11 | const imagePrompt = prompt.slice(8).trim();
12 |
13 | if (!imagePrompt) {
14 | await sock.sendMessage(chatId, {
15 | text: 'Please provide a prompt for the image generation.\nExample: .imagine a beautiful sunset over mountains'
16 | }, {
17 | quoted: message
18 | });
19 | return;
20 | }
21 |
22 | // Send processing message
23 | await sock.sendMessage(chatId, {
24 | text: '🎨 Generating your image... Please wait.'
25 | }, {
26 | quoted: message
27 | });
28 |
29 | // Enhance the prompt with quality keywords
30 | const enhancedPrompt = enhancePrompt(imagePrompt);
31 |
32 | // Make API request
33 | const response = await axios.get(`https://shizoapi.onrender.com/api/ai/imagine?apikey=shizo&query=${encodeURIComponent(enhancedPrompt)}`, {
34 | responseType: 'arraybuffer'
35 | });
36 |
37 | // Convert response to buffer
38 | const imageBuffer = Buffer.from(response.data);
39 |
40 | // Send the generated image
41 | await sock.sendMessage(chatId, {
42 | image: imageBuffer,
43 | caption: `🎨 Generated image for prompt: "${imagePrompt}"`
44 | }, {
45 | quoted: message
46 | });
47 |
48 | } catch (error) {
49 | console.error('Error in imagine command:', error);
50 | await sock.sendMessage(chatId, {
51 | text: '❌ Failed to generate image. Please try again later.'
52 | }, {
53 | quoted: message
54 | });
55 | }
56 | }
57 |
58 | // Function to enhance the prompt
59 | function enhancePrompt(prompt) {
60 | // Quality enhancing keywords
61 | const qualityEnhancers = [
62 | 'high quality',
63 | 'detailed',
64 | 'masterpiece',
65 | 'best quality',
66 | 'ultra realistic',
67 | '4k',
68 | 'highly detailed',
69 | 'professional photography',
70 | 'cinematic lighting',
71 | 'sharp focus'
72 | ];
73 |
74 | // Randomly select 3-4 enhancers
75 | const numEnhancers = Math.floor(Math.random() * 2) + 3; // Random number between 3-4
76 | const selectedEnhancers = qualityEnhancers
77 | .sort(() => Math.random() - 0.5)
78 | .slice(0, numEnhancers);
79 |
80 | // Combine original prompt with enhancers
81 | return `${prompt}, ${selectedEnhancers.join(', ')}`;
82 | }
83 |
84 | module.exports = imagineCommand;
--------------------------------------------------------------------------------
/commands/sudo.js:
--------------------------------------------------------------------------------
1 | const settings = require('../settings');
2 | const { addSudo, removeSudo, getSudoList } = require('../lib/index');
3 |
4 | function extractMentionedJid(message) {
5 | const mentioned = message.message?.extendedTextMessage?.contextInfo?.mentionedJid || [];
6 | if (mentioned.length > 0) return mentioned[0];
7 | const text = message.message?.conversation || message.message?.extendedTextMessage?.text || '';
8 | const match = text.match(/\b(\d{7,15})\b/);
9 | if (match) return match[1] + '@s.whatsapp.net';
10 | return null;
11 | }
12 |
13 | async function sudoCommand(sock, chatId, message) {
14 | const senderJid = message.key.participant || message.key.remoteJid;
15 | const ownerJid = settings.ownerNumber + '@s.whatsapp.net';
16 | const isOwner = message.key.fromMe || senderJid === ownerJid;
17 |
18 | const rawText = message.message?.conversation || message.message?.extendedTextMessage?.text || '';
19 | const args = rawText.trim().split(' ').slice(1);
20 | const sub = (args[0] || '').toLowerCase();
21 |
22 | if (!sub || !['add', 'del', 'remove', 'list'].includes(sub)) {
23 | await sock.sendMessage(chatId, { text: 'Usage:\n.sudo add <@user|number>\n.sudo del <@user|number>\n.sudo list' },{quoted :message});
24 | return;
25 | }
26 |
27 | if (sub === 'list') {
28 | const list = await getSudoList();
29 | if (list.length === 0) {
30 | await sock.sendMessage(chatId, { text: 'No sudo users set.' },{quoted :message});
31 | return;
32 | }
33 | const text = list.map((j, i) => `${i + 1}. ${j}`).join('\n');
34 | await sock.sendMessage(chatId, { text: `Sudo users:\n${text}` },{quoted :message});
35 | return;
36 | }
37 |
38 | if (!isOwner) {
39 | await sock.sendMessage(chatId, { text: '❌ Only owner can add/remove sudo users. Use .sudo list to view.' },{quoted :message});
40 | return;
41 | }
42 |
43 | const targetJid = extractMentionedJid(message);
44 | if (!targetJid) {
45 | await sock.sendMessage(chatId, { text: 'Please mention a user or provide a number.' },{quoted :message});
46 | return;
47 | }
48 |
49 | if (sub === 'add') {
50 | const ok = await addSudo(targetJid);
51 | await sock.sendMessage(chatId, { text: ok ? `✅ Added sudo: ${targetJid}` : '❌ Failed to add sudo' },{quoted :message});
52 | return;
53 | }
54 |
55 | if (sub === 'del' || sub === 'remove') {
56 | const ownerJid = settings.ownerNumber + '@s.whatsapp.net';
57 | if (targetJid === ownerJid) {
58 | await sock.sendMessage(chatId, { text: 'Owner cannot be removed.' },{quoted :message});
59 | return;
60 | }
61 | const ok = await removeSudo(targetJid);
62 | await sock.sendMessage(chatId, { text: ok ? `✅ Removed sudo: ${targetJid}` : '❌ Failed to remove sudo' },{quoted :message});
63 | return;
64 | }
65 | }
66 |
67 | module.exports = sudoCommand;
68 |
69 |
70 |
--------------------------------------------------------------------------------
/commands/img-blur.js:
--------------------------------------------------------------------------------
1 | const { downloadMediaMessage } = require('@whiskeysockets/baileys');
2 | const axios = require('axios');
3 | const sharp = require('sharp');
4 |
5 | async function blurCommand(sock, chatId, message, quotedMessage) {
6 | try {
7 | // Get the image to blur
8 | let imageBuffer;
9 |
10 | if (quotedMessage) {
11 | // If replying to a message
12 | if (!quotedMessage.imageMessage) {
13 | await sock.sendMessage(chatId, {
14 | text: '❌ Please reply to an image message'
15 | }, { quoted: message });
16 | return;
17 | }
18 |
19 | const quoted = {
20 | message: {
21 | imageMessage: quotedMessage.imageMessage
22 | }
23 | };
24 |
25 | imageBuffer = await downloadMediaMessage(
26 | quoted,
27 | 'buffer',
28 | { },
29 | { }
30 | );
31 | } else if (message.message?.imageMessage) {
32 | // If image is in current message
33 | imageBuffer = await downloadMediaMessage(
34 | message,
35 | 'buffer',
36 | { },
37 | { }
38 | );
39 | } else {
40 | await sock.sendMessage(chatId, {
41 | text: '❌ Please reply to an image or send an image with caption .blur'
42 | }, { quoted: message });
43 | return;
44 | }
45 |
46 | // Resize and optimize image
47 | const resizedImage = await sharp(imageBuffer)
48 | .resize(800, 800, { // Resize to max 800x800
49 | fit: 'inside',
50 | withoutEnlargement: true
51 | })
52 | .jpeg({ quality: 80 }) // Convert to JPEG with 80% quality
53 | .toBuffer();
54 |
55 | // Apply blur effect directly using sharp
56 | const blurredImage = await sharp(resizedImage)
57 | .blur(10) // Blur radius of 10
58 | .toBuffer();
59 |
60 | // Send the blurred image
61 | await sock.sendMessage(chatId, {
62 | image: blurredImage,
63 | caption: '*[ ✔ ] Image Blurred Successfully*',
64 | contextInfo: {
65 | forwardingScore: 1,
66 | isForwarded: true,
67 | forwardedNewsletterMessageInfo: {
68 | newsletterJid: '120363399707841760@newsletter',
69 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
70 | serverMessageId: -1
71 | }
72 | }
73 | }, { quoted: message });
74 |
75 | } catch (error) {
76 | console.error('Error in blur command:', error);
77 | await sock.sendMessage(chatId, {
78 | text: '❌ Failed to blur image. Please try again later.'
79 | }, { quoted: message });
80 | }
81 | }
82 |
83 | module.exports = blurCommand;
--------------------------------------------------------------------------------
/commands/take.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const { downloadMediaMessage } = require('@whiskeysockets/baileys');
4 | const webp = require('node-webpmux');
5 | const crypto = require('crypto');
6 |
7 | async function takeCommand(sock, chatId, message, args) {
8 | try {
9 | // Check if message is a reply to a sticker
10 | const quotedMessage = message.message?.extendedTextMessage?.contextInfo?.quotedMessage;
11 | if (!quotedMessage?.stickerMessage) {
12 | await sock.sendMessage(chatId, { text: '❌ Reply to a sticker with .take ' });
13 | return;
14 | }
15 |
16 | // Get the packname from args or use default
17 | const packname = args.join(' ') || 'Lady bella';
18 |
19 | try {
20 | // Download the sticker
21 | const stickerBuffer = await downloadMediaMessage(
22 | {
23 | key: message.message.extendedTextMessage.contextInfo.stanzaId,
24 | message: quotedMessage,
25 | messageType: 'stickerMessage'
26 | },
27 | 'buffer',
28 | {},
29 | {
30 | logger: console,
31 | reuploadRequest: sock.updateMediaMessage
32 | }
33 | );
34 |
35 | if (!stickerBuffer) {
36 | await sock.sendMessage(chatId, { text: '❌ Failed to download sticker' });
37 | return;
38 | }
39 |
40 | // Add metadata using webpmux
41 | const img = new webp.Image();
42 | await img.load(stickerBuffer);
43 |
44 | // Create metadata
45 | const json = {
46 | 'sticker-pack-id': crypto.randomBytes(32).toString('hex'),
47 | 'sticker-pack-name': packname,
48 | 'emojis': ['🤖']
49 | };
50 |
51 | // Create exif buffer
52 | const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]);
53 | const jsonBuffer = Buffer.from(JSON.stringify(json), 'utf8');
54 | const exif = Buffer.concat([exifAttr, jsonBuffer]);
55 | exif.writeUIntLE(jsonBuffer.length, 14, 4);
56 |
57 | // Set the exif data
58 | img.exif = exif;
59 |
60 | // Get the final buffer with metadata
61 | const finalBuffer = await img.save(null);
62 |
63 | // Send the sticker
64 | await sock.sendMessage(chatId, {
65 | sticker: finalBuffer
66 | }, {
67 | quoted: message
68 | });
69 |
70 | } catch (error) {
71 | console.error('Sticker processing error:', error);
72 | await sock.sendMessage(chatId, { text: '❌ Error processing sticker' });
73 | }
74 |
75 | } catch (error) {
76 | console.error('Error in take command:', error);
77 | await sock.sendMessage(chatId, { text: '❌ Error processing command' });
78 | }
79 | }
80 |
81 | module.exports = takeCommand;
--------------------------------------------------------------------------------
/commands/clearsession.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const os = require('os');
4 |
5 | const channelInfo = {
6 | contextInfo: {
7 | forwardingScore: 999,
8 | isForwarded: true,
9 | forwardedNewsletterMessageInfo: {
10 | newsletterJid: '120363399707841760@newsletter',
11 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
12 | serverMessageId: -1
13 | }
14 | }
15 | };
16 |
17 | async function clearSessionCommand(sock, chatId, msg) {
18 | try {
19 | // Check if sender is owner
20 | if (!msg.key.fromMe) {
21 | await sock.sendMessage(chatId, {
22 | text: '❌ This command can only be used by the owner!',
23 | ...channelInfo
24 | });
25 | return;
26 | }
27 |
28 | // Define session directory
29 | const sessionDir = path.join(__dirname, '../session');
30 |
31 | if (!fs.existsSync(sessionDir)) {
32 | await sock.sendMessage(chatId, {
33 | text: '❌ Session directory not found!',
34 | ...channelInfo
35 | });
36 | return;
37 | }
38 |
39 | let filesCleared = 0;
40 | let errors = 0;
41 | let errorDetails = [];
42 |
43 | // Send initial status
44 | await sock.sendMessage(chatId, {
45 | text: `🔍 Optimizing session files for better performance...`,
46 | ...channelInfo
47 | });
48 |
49 | const files = fs.readdirSync(sessionDir);
50 |
51 | // Count files by type for optimization
52 | let appStateSyncCount = 0;
53 | let preKeyCount = 0;
54 |
55 | for (const file of files) {
56 | if (file.startsWith('app-state-sync-')) appStateSyncCount++;
57 | if (file.startsWith('pre-key-')) preKeyCount++;
58 | }
59 |
60 | // Delete files
61 | for (const file of files) {
62 | if (file === 'creds.json') {
63 | // Skip creds.json file
64 | continue;
65 | }
66 | try {
67 | const filePath = path.join(sessionDir, file);
68 | fs.unlinkSync(filePath);
69 | filesCleared++;
70 | } catch (error) {
71 | errors++;
72 | errorDetails.push(`Failed to delete ${file}: ${error.message}`);
73 | }
74 | }
75 |
76 | // Send completion message
77 | const message = `✅ Session files cleared successfully!\n\n` +
78 | `📊 Statistics:\n` +
79 | `• Total files cleared: ${filesCleared}\n` +
80 | `• App state sync files: ${appStateSyncCount}\n` +
81 | `• Pre-key files: ${preKeyCount}\n` +
82 | (errors > 0 ? `\n⚠️ Errors encountered: ${errors}\n${errorDetails.join('\n')}` : '');
83 |
84 | await sock.sendMessage(chatId, {
85 | text: message,
86 | ...channelInfo
87 | });
88 |
89 | } catch (error) {
90 | console.error('Error in clearsession command:', error);
91 | await sock.sendMessage(chatId, {
92 | text: '❌ Failed to clear session files!',
93 | ...channelInfo
94 | });
95 | }
96 | }
97 |
98 | module.exports = clearSessionCommand;
--------------------------------------------------------------------------------
/lib/uploadImage.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 | const FormData = require('form-data');
3 | const FileType = require('file-type');
4 | const fs = require('fs');
5 | const path = require('path');
6 |
7 | /**
8 | * Upload file to qu.ax
9 | * Supported mimetypes:
10 | * - `image/jpeg`
11 | * - `image/jpg`
12 | * - `image/png`
13 | * @param {Buffer} buffer File Buffer
14 | * @return {Promise}
15 | */
16 | async function uploadImage(buffer) {
17 | try {
18 | // Create temp directory if it doesn't exist
19 | const tmpDir = path.join(process.cwd(), 'tmp');
20 | if (!fs.existsSync(tmpDir)) {
21 | fs.mkdirSync(tmpDir, { recursive: true });
22 | }
23 |
24 | // Get file type
25 | const fileType = await FileType.fromBuffer(buffer);
26 | const { ext, mime } = fileType || { ext: 'png', mime: 'image/png' };
27 | const tempFile = path.join(tmpDir, `temp_${Date.now()}.${ext}`);
28 |
29 | // Save buffer to temp file
30 | fs.writeFileSync(tempFile, buffer);
31 |
32 | // Create form data
33 | const form = new FormData();
34 | form.append('files[]', fs.createReadStream(tempFile));
35 |
36 | // Upload to qu.ax
37 | const response = await fetch('https://qu.ax/upload.php', {
38 | method: 'POST',
39 | body: form,
40 | headers: form.getHeaders()
41 | });
42 |
43 | // Clean up temp file
44 | fs.unlinkSync(tempFile);
45 |
46 | const result = await response.json();
47 | if (result && result.success) {
48 | return result.files[0].url;
49 | } else {
50 | // Fallback to telegraph if qu.ax fails
51 | const telegraphForm = new FormData();
52 | telegraphForm.append('file', buffer, {
53 | filename: `upload.${ext}`,
54 | contentType: mime
55 | });
56 |
57 | const telegraphResponse = await fetch('https://telegra.ph/upload', {
58 | method: 'POST',
59 | body: telegraphForm
60 | });
61 |
62 | const img = await telegraphResponse.json();
63 | if (img[0]?.src) {
64 | return 'https://telegra.ph' + img[0].src;
65 | }
66 |
67 | throw new Error('Failed to upload image to both services');
68 | }
69 | } catch (error) {
70 | console.error('Upload error:', error);
71 | throw error;
72 | }
73 | }
74 |
75 | module.exports = { uploadImage };
76 |
77 | /**
78 | * Alternative upload to telegra.ph (backup)
79 | */
80 | /*
81 | async function uploadImageTelegraph(buffer) {
82 | try {
83 | const { ext, mime } = await fileTypeFromBuffer(buffer);
84 | const form = new FormData();
85 | const blob = new Blob([buffer.toArrayBuffer()], { type: mime });
86 | form.append('file', blob, 'tmp.' + ext);
87 |
88 | const response = await fetch('https://telegra.ph/upload', {
89 | method: 'POST',
90 | body: form
91 | });
92 |
93 | const img = await response.json();
94 | if (img.error) throw img.error;
95 | return 'https://telegra.ph' + img[0].src;
96 | } catch (error) {
97 | throw error;
98 | }
99 | }
100 | */
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | [](https://git.io/typing-svg)
17 | >
18 |
19 | ---
20 | 1. ᴍʏ ᴀᴄᴄᴏᴜɴᴛ
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | ---
29 |
30 | ## 🚀 ᴅᴇᴘʟᴏʏᴍᴇɴᴛ ᴏᴘᴛɪᴏɴs
31 |
32 | ### ⭐ ғᴏʀᴋ & sᴛᴀʀ ʀᴇᴘᴏsɪᴛᴏʀʏ
33 | ғᴏʀᴋ & sᴛᴀʀ ⭐ ᴛᴏ sᴜᴘᴘᴏʀᴛ sɴᴏᴡʙɪʀᴅ!
34 |
35 | [](https://github.com/SNOWBIRD0074/Lady-Bella2/fork)
36 |
37 | ---
38 |
39 | ### 💙ᴘᴀɪʀ ʏᴏᴜʀ #💚ɢᴇᴛ ᴄʀᴇᴅs ғɪʟᴇ💜
40 |
41 | [](https://kkkdjjdjjdjdjdjj.onrender.com/)
42 |
43 | ---
44 |
45 | ### ✔️ ᴅᴏᴡɴʟᴏᴀᴅ ʟᴀᴅʏʙᴇʟʟᴀ3 ᴢɪᴘ
46 |
47 | [](https://github.com/SNOWBIRD0074/Lady-Bella2/archive/refs/heads/main.zip)
48 |
49 | ---
50 |
51 | ### 🤍 ᴅᴇᴘʟᴏʏᴍᴇɴᴛ
52 |
53 | #### ✔️ ʙᴏᴛ ʜᴏsᴛɪɴɢ ɴᴇᴛ
54 | ---
55 | [](https://bot-hosting.net/panel)
56 |
57 |
58 | ---
59 |
60 | #### ✔️ Katabump Hosting
61 | ---
62 | [](https://dashboard.katabump.com/dashboard)
63 |
64 |
65 | ---
66 |
67 | #### ✔️ Vɪᴅᴇᴏ ᴏɴ ʜᴏᴡ ᴛᴏ ᴅᴇᴘʟᴏʏ
68 | ---
69 | [](https://youtu.be/2hrm7riEZRg?si=WGfGJp8M6QZ8OsSu)
70 |
71 |
72 |
73 | ---
74 | ## Fᴏʟʟᴏᴡ ᴏᴜʀ ᴄʜᴀɴɴᴇʟs ғᴏʀ ᴜᴘᴅᴀᴛᴇs
75 |
76 |
77 | 
78 |
79 | ---
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/commands/character.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const { channelInfo } = require('../lib/messageConfig');
3 |
4 | async function characterCommand(sock, chatId, message) {
5 | let userToAnalyze;
6 |
7 | // Check for mentioned users
8 | if (message.message?.extendedTextMessage?.contextInfo?.mentionedJid?.length > 0) {
9 | userToAnalyze = message.message.extendedTextMessage.contextInfo.mentionedJid[0];
10 | }
11 | // Check for replied message
12 | else if (message.message?.extendedTextMessage?.contextInfo?.participant) {
13 | userToAnalyze = message.message.extendedTextMessage.contextInfo.participant;
14 | }
15 |
16 | if (!userToAnalyze) {
17 | await sock.sendMessage(chatId, {
18 | text: 'Please mention someone or reply to their message to analyze their character!',
19 | ...channelInfo
20 | });
21 | return;
22 | }
23 |
24 | try {
25 | // Get user's profile picture
26 | let profilePic;
27 | try {
28 | profilePic = await sock.profilePictureUrl(userToAnalyze, 'image');
29 | } catch {
30 | profilePic = 'https://i.imgur.com/2wzGhpF.jpeg'; // Default image if no profile pic
31 | }
32 |
33 | const traits = [
34 | "Intelligent", "Creative", "Determined", "Ambitious", "Caring",
35 | "Charismatic", "Confident", "Empathetic", "Energetic", "Friendly",
36 | "Generous", "Honest", "Humorous", "Imaginative", "Independent",
37 | "Intuitive", "Kind", "Logical", "Loyal", "Optimistic",
38 | "Passionate", "Patient", "Persistent", "Reliable", "Resourceful",
39 | "Sincere", "Thoughtful", "Understanding", "Versatile", "Wise"
40 | ];
41 |
42 | // Get 3-5 random traits
43 | const numTraits = Math.floor(Math.random() * 3) + 3; // Random number between 3 and 5
44 | const selectedTraits = [];
45 | for (let i = 0; i < numTraits; i++) {
46 | const randomTrait = traits[Math.floor(Math.random() * traits.length)];
47 | if (!selectedTraits.includes(randomTrait)) {
48 | selectedTraits.push(randomTrait);
49 | }
50 | }
51 |
52 | // Calculate random percentages for each trait
53 | const traitPercentages = selectedTraits.map(trait => {
54 | const percentage = Math.floor(Math.random() * 41) + 60; // Random number between 60-100
55 | return `${trait}: ${percentage}%`;
56 | });
57 |
58 | // Create character analysis message
59 | const analysis = `🔮 *Character Analysis* 🔮\n\n` +
60 | `👤 *User:* ${userToAnalyze.split('@')[0]}\n\n` +
61 | `✨ *Key Traits:*\n${traitPercentages.join('\n')}\n\n` +
62 | `🎯 *Overall Rating:* ${Math.floor(Math.random() * 21) + 80}%\n\n` +
63 | `Note: This is a fun analysis and should not be taken seriously!`;
64 |
65 | // Send the analysis with the user's profile picture
66 | await sock.sendMessage(chatId, {
67 | image: { url: profilePic },
68 | caption: analysis,
69 | mentions: [userToAnalyze],
70 | ...channelInfo
71 | });
72 |
73 | } catch (error) {
74 | console.error('Error in character command:', error);
75 | await sock.sendMessage(chatId, {
76 | text: 'Failed to analyze character! Try again later.',
77 | ...channelInfo
78 | });
79 | }
80 | }
81 |
82 | module.exports = characterCommand;
--------------------------------------------------------------------------------
/commands/promote.js:
--------------------------------------------------------------------------------
1 | const { isAdmin } = require('../lib/isAdmin');
2 |
3 | // Function to handle manual promotions via command
4 | async function promoteCommand(sock, chatId, mentionedJids, message) {
5 | let userToPromote = [];
6 |
7 | // Check for mentioned users
8 | if (mentionedJids && mentionedJids.length > 0) {
9 | userToPromote = mentionedJids;
10 | }
11 | // Check for replied message
12 | else if (message.message?.extendedTextMessage?.contextInfo?.participant) {
13 | userToPromote = [message.message.extendedTextMessage.contextInfo.participant];
14 | }
15 |
16 | // If no user found through either method
17 | if (userToPromote.length === 0) {
18 | await sock.sendMessage(chatId, {
19 | text: 'Please mention the user or reply to their message to promote!'
20 | });
21 | return;
22 | }
23 |
24 | try {
25 | await sock.groupParticipantsUpdate(chatId, userToPromote, "promote");
26 |
27 | // Get usernames for each promoted user
28 | const usernames = await Promise.all(userToPromote.map(async jid => {
29 |
30 | return `@${jid.split('@')[0]}`;
31 | }));
32 |
33 | // Get promoter's name (the bot user in this case)
34 | const promoterJid = sock.user.id;
35 |
36 | const promotionMessage = `*『 GROUP PROMOTION 』*\n\n` +
37 | `👥 *Promoted User${userToPromote.length > 1 ? 's' : ''}:*\n` +
38 | `${usernames.map(name => `• ${name}`).join('\n')}\n\n` +
39 | `👑 *Promoted By:* @${promoterJid.split('@')[0]}\n\n` +
40 | `📅 *Date:* ${new Date().toLocaleString()}`;
41 | await sock.sendMessage(chatId, {
42 | text: promotionMessage,
43 | mentions: [...userToPromote, promoterJid]
44 | });
45 | } catch (error) {
46 | console.error('Error in promote command:', error);
47 | await sock.sendMessage(chatId, { text: 'Failed to promote user(s)!'});
48 | }
49 | }
50 |
51 | // Function to handle automatic promotion detection
52 | async function handlePromotionEvent(sock, groupId, participants, author) {
53 | try {
54 | /* console.log('Promotion Event Data:', {
55 | groupId,
56 | participants,
57 | author
58 | });*/
59 |
60 | // Get usernames for promoted participants
61 | const promotedUsernames = await Promise.all(participants.map(async jid => {
62 | return `@${jid.split('@')[0]} `;
63 | }));
64 |
65 | let promotedBy;
66 | let mentionList = [...participants];
67 |
68 | if (author && author.length > 0) {
69 | // Ensure author has the correct format
70 | const authorJid = author;
71 | promotedBy = `@${authorJid.split('@')[0]}`;
72 | mentionList.push(authorJid);
73 | } else {
74 | promotedBy = 'System';
75 | }
76 |
77 | const promotionMessage = `*『 GROUP PROMOTION 』*\n\n` +
78 | `👥 *Promoted User${participants.length > 1 ? 's' : ''}:*\n` +
79 | `${promotedUsernames.map(name => `• ${name}`).join('\n')}\n\n` +
80 | `👑 *Promoted By:* ${promotedBy}\n\n` +
81 | `📅 *Date:* ${new Date().toLocaleString()}`;
82 |
83 | await sock.sendMessage(groupId, {
84 | text: promotionMessage,
85 | mentions: mentionList
86 | });
87 | } catch (error) {
88 | console.error('Error handling promotion event:', error);
89 | }
90 | }
91 |
92 | module.exports = { promoteCommand, handlePromotionEvent };
93 |
--------------------------------------------------------------------------------
/commands/tag.js:
--------------------------------------------------------------------------------
1 | const isAdmin = require('../lib/isAdmin');
2 | const { downloadContentFromMessage } = require('@whiskeysockets/baileys');
3 | const fs = require('fs');
4 | const path = require('path');
5 |
6 | async function downloadMediaMessage(message, mediaType) {
7 | const stream = await downloadContentFromMessage(message, mediaType);
8 | let buffer = Buffer.from([]);
9 | for await (const chunk of stream) {
10 | buffer = Buffer.concat([buffer, chunk]);
11 | }
12 | const filePath = path.join(__dirname, '../temp/', `${Date.now()}.${mediaType}`);
13 | fs.writeFileSync(filePath, buffer);
14 | return filePath;
15 | }
16 |
17 | async function tagCommand(sock, chatId, senderId, messageText, replyMessage, message) {
18 | const { isSenderAdmin, isBotAdmin } = await isAdmin(sock, chatId, senderId);
19 |
20 | if (!isBotAdmin) {
21 | await sock.sendMessage(chatId, { text: 'Please make the bot an admin first.' }, { quoted: message });
22 | return;
23 | }
24 |
25 | if (!isSenderAdmin) {
26 | const stickerPath = './assets/sticktag.webp'; // Path to your sticker
27 | if (fs.existsSync(stickerPath)) {
28 | const stickerBuffer = fs.readFileSync(stickerPath);
29 | await sock.sendMessage(chatId, { sticker: stickerBuffer }, { quoted: message });
30 | }
31 | return;
32 | }
33 |
34 | const groupMetadata = await sock.groupMetadata(chatId);
35 | const participants = groupMetadata.participants;
36 | const mentionedJidList = participants.map(p => p.id);
37 |
38 | if (replyMessage) {
39 | let messageContent = {};
40 |
41 | // Handle image messages
42 | if (replyMessage.imageMessage) {
43 | const filePath = await downloadMediaMessage(replyMessage.imageMessage, 'image');
44 | messageContent = {
45 | image: { url: filePath },
46 | caption: messageText || replyMessage.imageMessage.caption || '',
47 | mentions: mentionedJidList
48 | };
49 | }
50 | // Handle video messages
51 | else if (replyMessage.videoMessage) {
52 | const filePath = await downloadMediaMessage(replyMessage.videoMessage, 'video');
53 | messageContent = {
54 | video: { url: filePath },
55 | caption: messageText || replyMessage.videoMessage.caption || '',
56 | mentions: mentionedJidList
57 | };
58 | }
59 | // Handle text messages
60 | else if (replyMessage.conversation || replyMessage.extendedTextMessage) {
61 | messageContent = {
62 | text: replyMessage.conversation || replyMessage.extendedTextMessage.text,
63 | mentions: mentionedJidList
64 | };
65 | }
66 | // Handle document messages
67 | else if (replyMessage.documentMessage) {
68 | const filePath = await downloadMediaMessage(replyMessage.documentMessage, 'document');
69 | messageContent = {
70 | document: { url: filePath },
71 | fileName: replyMessage.documentMessage.fileName,
72 | caption: messageText || '',
73 | mentions: mentionedJidList
74 | };
75 | }
76 |
77 | if (Object.keys(messageContent).length > 0) {
78 | await sock.sendMessage(chatId, messageContent);
79 | }
80 | } else {
81 | await sock.sendMessage(chatId, {
82 | text: messageText || "Tagged message",
83 | mentions: mentionedJidList
84 | });
85 | }
86 | }
87 |
88 | module.exports = tagCommand;
89 |
--------------------------------------------------------------------------------
/lib/uploader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Knight Bot - A WhatsApp Bot
3 | * Copyright (c) 2024 Professor
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the MIT License.
7 | *
8 | * Credits:
9 | * - Baileys Library by @adiwajshing
10 | * - Pair Code implementation inspired by TechGod143 & DGXEON
11 | */
12 | let axios = require('axios')
13 | let BodyForm = require('form-data')
14 | let { fromBuffer } = require('file-type')
15 | let fetch = require('node-fetch')
16 | let fs = require('fs')
17 | let cheerio = require('cheerio')
18 |
19 |
20 |
21 | function TelegraPh (Path) {
22 | return new Promise (async (resolve, reject) => {
23 | if (!fs.existsSync(Path)) return reject(new Error("File not Found"))
24 | try {
25 | const form = new BodyForm();
26 | form.append("file", fs.createReadStream(Path))
27 | const data = await axios({
28 | url: "https://telegra.ph/upload",
29 | method: "POST",
30 | headers: {
31 | ...form.getHeaders()
32 | },
33 | data: form
34 | })
35 | return resolve("https://telegra.ph" + data.data[0].src)
36 | } catch (err) {
37 | return reject(new Error(String(err)))
38 | }
39 | })
40 | }
41 |
42 | async function UploadFileUgu (input) {
43 | return new Promise (async (resolve, reject) => {
44 | const form = new BodyForm();
45 | form.append("files[]", fs.createReadStream(input))
46 | await axios({
47 | url: "https://uguu.se/upload.php",
48 | method: "POST",
49 | headers: {
50 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36",
51 | ...form.getHeaders()
52 | },
53 | data: form
54 | }).then((data) => {
55 | resolve(data.data.files[0])
56 | }).catch((err) => reject(err))
57 | })
58 | }
59 |
60 | function webp2mp4File(path) {
61 | return new Promise((resolve, reject) => {
62 | const form = new BodyForm()
63 | form.append('new-image-url', '')
64 | form.append('new-image', fs.createReadStream(path))
65 | axios({
66 | method: 'post',
67 | url: 'https://s6.ezgif.com/webp-to-mp4',
68 | data: form,
69 | headers: {
70 | 'Content-Type': `multipart/form-data; boundary=${form._boundary}`
71 | }
72 | }).then(({ data }) => {
73 | const bodyFormThen = new BodyForm()
74 | const $ = cheerio.load(data)
75 | const file = $('input[name="file"]').attr('value')
76 | bodyFormThen.append('file', file)
77 | bodyFormThen.append('convert', "Convert WebP to MP4!")
78 | axios({
79 | method: 'post',
80 | url: 'https://ezgif.com/webp-to-mp4/' + file,
81 | data: bodyFormThen,
82 | headers: {
83 | 'Content-Type': `multipart/form-data; boundary=${bodyFormThen._boundary}`
84 | }
85 | }).then(({ data }) => {
86 | const $ = cheerio.load(data)
87 | const result = 'https:' + $('div#output > p.outfile > video > source').attr('src')
88 | resolve({
89 | status: true,
90 | message: "Created By MRHRTZ",
91 | result: result
92 | })
93 | }).catch(reject)
94 | }).catch(reject)
95 | })
96 | }
97 |
98 | async function floNime(medianya, options = {}) {
99 | const { ext } = await fromBuffer(medianya) || options.ext
100 | var form = new BodyForm()
101 | form.append('file', medianya, 'tmp.'+ext)
102 | let jsonnya = await fetch('https://flonime.my.id/upload', {
103 | method: 'POST',
104 | body: form
105 | })
106 | .then((response) => response.json())
107 | return jsonnya
108 | }
109 |
110 | module.exports = { TelegraPh, UploadFileUgu, webp2mp4File, floNime }
--------------------------------------------------------------------------------
/commands/compliment.js:
--------------------------------------------------------------------------------
1 | const compliments = [
2 | "You're amazing just the way you are!",
3 | "You have a great sense of humor!",
4 | "You're incredibly thoughtful and kind.",
5 | "You are more powerful than you know.",
6 | "You light up the room!",
7 | "You're a true friend.",
8 | "You inspire me!",
9 | "Your creativity knows no bounds!",
10 | "You have a heart of gold.",
11 | "You make a difference in the world.",
12 | "Your positivity is contagious!",
13 | "You have an incredible work ethic.",
14 | "You bring out the best in people.",
15 | "Your smile brightens everyone's day.",
16 | "You're so talented in everything you do.",
17 | "Your kindness makes the world a better place.",
18 | "You have a unique and wonderful perspective.",
19 | "Your enthusiasm is truly inspiring!",
20 | "You are capable of achieving great things.",
21 | "You always know how to make someone feel special.",
22 | "Your confidence is admirable.",
23 | "You have a beautiful soul.",
24 | "Your generosity knows no limits.",
25 | "You have a great eye for detail.",
26 | "Your passion is truly motivating!",
27 | "You are an amazing listener.",
28 | "You're stronger than you think!",
29 | "Your laughter is infectious.",
30 | "You have a natural gift for making others feel valued.",
31 | "You make the world a better place just by being in it."
32 | ];
33 |
34 | async function complimentCommand(sock, chatId, message) {
35 | try {
36 | if (!message || !chatId) {
37 | console.log('Invalid message or chatId:', { message, chatId });
38 | return;
39 | }
40 |
41 | let userToCompliment;
42 |
43 | // Check for mentioned users
44 | if (message.message?.extendedTextMessage?.contextInfo?.mentionedJid?.length > 0) {
45 | userToCompliment = message.message.extendedTextMessage.contextInfo.mentionedJid[0];
46 | }
47 | // Check for replied message
48 | else if (message.message?.extendedTextMessage?.contextInfo?.participant) {
49 | userToCompliment = message.message.extendedTextMessage.contextInfo.participant;
50 | }
51 |
52 | if (!userToCompliment) {
53 | await sock.sendMessage(chatId, {
54 | text: 'Please mention someone or reply to their message to compliment them!'
55 | });
56 | return;
57 | }
58 |
59 | const compliment = compliments[Math.floor(Math.random() * compliments.length)];
60 |
61 | // Add delay to avoid rate limiting
62 | await new Promise(resolve => setTimeout(resolve, 1000));
63 |
64 | await sock.sendMessage(chatId, {
65 | text: `Hey @${userToCompliment.split('@')[0]}, ${compliment}`,
66 | mentions: [userToCompliment]
67 | });
68 | } catch (error) {
69 | console.error('Error in compliment command:', error);
70 | if (error.data === 429) {
71 | await new Promise(resolve => setTimeout(resolve, 2000));
72 | try {
73 | await sock.sendMessage(chatId, {
74 | text: 'Please try again in a few seconds.'
75 | });
76 | } catch (retryError) {
77 | console.error('Error sending retry message:', retryError);
78 | }
79 | } else {
80 | try {
81 | await sock.sendMessage(chatId, {
82 | text: 'An error occurred while sending the compliment.'
83 | });
84 | } catch (sendError) {
85 | console.error('Error sending error message:', sendError);
86 | }
87 | }
88 | }
89 | }
90 |
91 | module.exports = { complimentCommand };
92 |
--------------------------------------------------------------------------------
/lib/reactions.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | // List of emojis for command reactions
5 | const commandEmojis = ['⏳'];
6 |
7 | // Path for storing auto-reaction state
8 | const USER_GROUP_DATA = path.join(__dirname, '../data/userGroupData.json');
9 |
10 | // Load auto-reaction state from file
11 | function loadAutoReactionState() {
12 | try {
13 | if (fs.existsSync(USER_GROUP_DATA)) {
14 | const data = JSON.parse(fs.readFileSync(USER_GROUP_DATA));
15 | return data.autoReaction || false;
16 | }
17 | } catch (error) {
18 | console.error('Error loading auto-reaction state:', error);
19 | }
20 | return false;
21 | }
22 |
23 | // Save auto-reaction state to file
24 | function saveAutoReactionState(state) {
25 | try {
26 | const data = fs.existsSync(USER_GROUP_DATA)
27 | ? JSON.parse(fs.readFileSync(USER_GROUP_DATA))
28 | : { groups: [], chatbot: {} };
29 |
30 | data.autoReaction = state;
31 | fs.writeFileSync(USER_GROUP_DATA, JSON.stringify(data, null, 2));
32 | } catch (error) {
33 | console.error('Error saving auto-reaction state:', error);
34 | }
35 | }
36 |
37 | // Store auto-reaction state
38 | let isAutoReactionEnabled = loadAutoReactionState();
39 |
40 | function getRandomEmoji() {
41 | return commandEmojis[0];
42 | }
43 |
44 | // Function to add reaction to a command message
45 | async function addCommandReaction(sock, message) {
46 | try {
47 | if (!isAutoReactionEnabled || !message?.key?.id) return;
48 |
49 | const emoji = getRandomEmoji();
50 | await sock.sendMessage(message.key.remoteJid, {
51 | react: {
52 | text: emoji,
53 | key: message.key
54 | }
55 | });
56 | } catch (error) {
57 | console.error('Error adding command reaction:', error);
58 | }
59 | }
60 |
61 | // Function to handle areact command
62 | async function handleAreactCommand(sock, chatId, message, isOwner) {
63 | try {
64 | if (!isOwner) {
65 | await sock.sendMessage(chatId, {
66 | text: '❌ This command is only available for the owner!',
67 | quoted: message
68 | });
69 | return;
70 | }
71 |
72 | const args = message.message?.conversation?.split(' ') || [];
73 | const action = args[1]?.toLowerCase();
74 |
75 | if (action === 'on') {
76 | isAutoReactionEnabled = true;
77 | saveAutoReactionState(true);
78 | await sock.sendMessage(chatId, {
79 | text: '✅ Auto-reactions have been enabled globally',
80 | quoted: message
81 | });
82 | } else if (action === 'off') {
83 | isAutoReactionEnabled = false;
84 | saveAutoReactionState(false);
85 | await sock.sendMessage(chatId, {
86 | text: '✅ Auto-reactions have been disabled globally',
87 | quoted: message
88 | });
89 | } else {
90 | const currentState = isAutoReactionEnabled ? 'enabled' : 'disabled';
91 | await sock.sendMessage(chatId, {
92 | text: `Auto-reactions are currently ${currentState} globally.\n\nUse:\n.areact on - Enable auto-reactions\n.areact off - Disable auto-reactions`,
93 | quoted: message
94 | });
95 | }
96 | } catch (error) {
97 | console.error('Error handling areact command:', error);
98 | await sock.sendMessage(chatId, {
99 | text: '❌ Error controlling auto-reactions',
100 | quoted: message
101 | });
102 | }
103 | }
104 |
105 | module.exports = {
106 | addCommandReaction,
107 | handleAreactCommand
108 | };
--------------------------------------------------------------------------------
/commands/cleartmp.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | // Function to clear a single directory
5 | function clearDirectory(dirPath) {
6 | try {
7 | if (!fs.existsSync(dirPath)) {
8 | return { success: false, message: `Directory does not exist: ${dirPath}` };
9 | }
10 | const files = fs.readdirSync(dirPath);
11 | let deletedCount = 0;
12 | for (const file of files) {
13 | try {
14 | const filePath = path.join(dirPath, file);
15 | const stat = fs.lstatSync(filePath);
16 | if (stat.isDirectory()) {
17 | fs.rmSync(filePath, { recursive: true, force: true });
18 | } else {
19 | fs.unlinkSync(filePath);
20 | }
21 | deletedCount++;
22 | } catch (err) {
23 | // Only log errors
24 | console.error(`Error deleting file ${file}:`, err);
25 | }
26 | }
27 | return { success: true, message: `Cleared ${deletedCount} files in ${path.basename(dirPath)}`, count: deletedCount };
28 | } catch (error) {
29 | console.error('Error in clearDirectory:', error);
30 | return { success: false, message: `Failed to clear files in ${path.basename(dirPath)}`, error: error.message };
31 | }
32 | }
33 |
34 | // Function to clear both tmp and temp directories
35 | async function clearTmpDirectory() {
36 | const tmpDir = path.join(process.cwd(), 'tmp');
37 | const tempDir = path.join(process.cwd(), 'temp');
38 | const results = [];
39 | results.push(clearDirectory(tmpDir));
40 | results.push(clearDirectory(tempDir));
41 | // Combine results
42 | const success = results.every(r => r.success);
43 | const totalDeleted = results.reduce((sum, r) => sum + (r.count || 0), 0);
44 | const message = results.map(r => r.message).join(' | ');
45 | return { success, message, count: totalDeleted };
46 | }
47 |
48 | // Function to handle manual command
49 | async function clearTmpCommand(sock, chatId, msg) {
50 | try {
51 | // Check if user is owner
52 | const isOwner = msg.key.fromMe;
53 | if (!isOwner) {
54 | await sock.sendMessage(chatId, {
55 | text: '❌ This command is only available for the owner!'
56 | });
57 | return;
58 | }
59 |
60 | const result = await clearTmpDirectory();
61 |
62 | if (result.success) {
63 | await sock.sendMessage(chatId, {
64 | text: `✅ ${result.message}`
65 | });
66 | } else {
67 | await sock.sendMessage(chatId, {
68 | text: `❌ ${result.message}`
69 | });
70 | }
71 |
72 | } catch (error) {
73 | console.error('Error in cleartmp command:', error);
74 | await sock.sendMessage(chatId, {
75 | text: '❌ Failed to clear temporary files!'
76 | });
77 | }
78 | }
79 |
80 | // Start automatic clearing every 6 hours
81 | function startAutoClear() {
82 | // Run immediately on startup
83 | clearTmpDirectory().then(result => {
84 | if (!result.success) {
85 | console.error(`[Auto Clear] ${result.message}`);
86 | }
87 | // No log for success, regardless of count
88 | });
89 |
90 | // Set interval for every 6 hours
91 | setInterval(async () => {
92 | const result = await clearTmpDirectory();
93 | if (!result.success) {
94 | console.error(`[Auto Clear] ${result.message}`);
95 | }
96 | // No log for success, regardless of count
97 | }, 6 * 60 * 60 * 1000); // 6 hours in milliseconds
98 | }
99 |
100 | // Start the automatic clearing
101 | startAutoClear();
102 |
103 | module.exports = clearTmpCommand;
--------------------------------------------------------------------------------
/commands/emojimix.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 | const fs = require('fs');
3 | const { exec } = require('child_process');
4 | const path = require('path');
5 |
6 | async function emojimixCommand(sock, chatId, msg) {
7 | try {
8 | // Get the text after command
9 | const text = msg.message?.conversation?.trim() ||
10 | msg.message?.extendedTextMessage?.text?.trim() || '';
11 |
12 | const args = text.split(' ').slice(1);
13 |
14 | if (!args[0]) {
15 | await sock.sendMessage(chatId, { text: '🎴 Example: .emojimix 😎+🥰' });
16 | return;
17 | }
18 |
19 | if (!text.includes('+')) {
20 | await sock.sendMessage(chatId, {
21 | text: '✳️ Separate the emoji with a *+* sign\n\n📌 Example: \n*.emojimix* 😎+🥰'
22 | });
23 | return;
24 | }
25 |
26 | let [emoji1, emoji2] = args[0].split('+').map(e => e.trim());
27 |
28 | // Using Tenor API endpoint
29 | const url = `https://tenor.googleapis.com/v2/featured?key=AIzaSyAyimkuYQYF_FXVALexPuGQctUWRURdCYQ&contentfilter=high&media_filter=png_transparent&component=proactive&collection=emoji_kitchen_v5&q=${encodeURIComponent(emoji1)}_${encodeURIComponent(emoji2)}`;
30 |
31 | const response = await fetch(url);
32 | const data = await response.json();
33 |
34 | if (!data.results || data.results.length === 0) {
35 | await sock.sendMessage(chatId, {
36 | text: '❌ These emojis cannot be mixed! Try different ones.'
37 | });
38 | return;
39 | }
40 |
41 | // Get the first result URL
42 | const imageUrl = data.results[0].url;
43 |
44 | // Create temp directory if it doesn't exist
45 | const tmpDir = path.join(process.cwd(), 'tmp');
46 | if (!fs.existsSync(tmpDir)) {
47 | fs.mkdirSync(tmpDir, { recursive: true });
48 | }
49 |
50 | // Generate random filenames with escaped paths
51 | const tempFile = path.join(tmpDir, `temp_${Date.now()}.png`).replace(/\\/g, '/');
52 | const outputFile = path.join(tmpDir, `sticker_${Date.now()}.webp`).replace(/\\/g, '/');
53 |
54 | // Download and save the image
55 | const imageResponse = await fetch(imageUrl);
56 | const buffer = await imageResponse.buffer();
57 | fs.writeFileSync(tempFile, buffer);
58 |
59 | // Convert to WebP using ffmpeg with proper path escaping
60 | const ffmpegCommand = `ffmpeg -i "${tempFile}" -vf "scale=512:512:force_original_aspect_ratio=decrease,format=rgba,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000" "${outputFile}"`;
61 |
62 | await new Promise((resolve, reject) => {
63 | exec(ffmpegCommand, (error) => {
64 | if (error) {
65 | console.error('FFmpeg error:', error);
66 | reject(error);
67 | } else {
68 | resolve();
69 | }
70 | });
71 | });
72 |
73 | // Check if output file exists
74 | if (!fs.existsSync(outputFile)) {
75 | throw new Error('Failed to create sticker file');
76 | }
77 |
78 | // Read the WebP file
79 | const stickerBuffer = fs.readFileSync(outputFile);
80 |
81 | // Send the sticker
82 | await sock.sendMessage(chatId, {
83 | sticker: stickerBuffer
84 | }, { quoted: msg });
85 |
86 | // Cleanup temp files
87 | try {
88 | fs.unlinkSync(tempFile);
89 | fs.unlinkSync(outputFile);
90 | } catch (err) {
91 | console.error('Error cleaning up temp files:', err);
92 | }
93 |
94 | } catch (error) {
95 | console.error('Error in emojimix command:', error);
96 | await sock.sendMessage(chatId, {
97 | text: '❌ Failed to mix emojis! Make sure you\'re using valid emojis.\n\nExample: .emojimix 😎+🥰'
98 | });
99 | }
100 | }
101 |
102 | module.exports = emojimixCommand;
--------------------------------------------------------------------------------
/commands/insult.js:
--------------------------------------------------------------------------------
1 | const insults = [
2 | "You're like a cloud. When you disappear, it's a beautiful day!",
3 | "You bring everyone so much joy when you leave the room!",
4 | "I'd agree with you, but then we'd both be wrong.",
5 | "You're not stupid; you just have bad luck thinking.",
6 | "Your secrets are always safe with me. I never even listen to them.",
7 | "You're proof that even evolution takes a break sometimes.",
8 | "You have something on your chin... no, the third one down.",
9 | "You're like a software update. Whenever I see you, I think, 'Do I really need this right now?'",
10 | "You bring everyone happiness... you know, when you leave.",
11 | "You're like a penny—two-faced and not worth much.",
12 | "You have something on your mind... oh wait, never mind.",
13 | "You're the reason they put directions on shampoo bottles.",
14 | "You're like a cloud. Always floating around with no real purpose.",
15 | "Your jokes are like expired milk—sour and hard to digest.",
16 | "You're like a candle in the wind... useless when things get tough.",
17 | "You have something unique—your ability to annoy everyone equally.",
18 | "You're like a Wi-Fi signal—always weak when needed most.",
19 | "You're proof that not everyone needs a filter to be unappealing.",
20 | "Your energy is like a black hole—it just sucks the life out of the room.",
21 | "You have the perfect face for radio.",
22 | "You're like a traffic jam—nobody wants you, but here you are.",
23 | "You're like a broken pencil—pointless.",
24 | "Your ideas are so original, I'm sure I've heard them all before.",
25 | "You're living proof that even mistakes can be productive.",
26 | "You're not lazy; you're just highly motivated to do nothing.",
27 | "Your brain's running Windows 95—slow and outdated.",
28 | "You're like a speed bump—nobody likes you, but everyone has to deal with you.",
29 | "You're like a cloud of mosquitoes—just irritating.",
30 | "You bring people together... to talk about how annoying you are."
31 | ];
32 |
33 | async function insultCommand(sock, chatId, message) {
34 | try {
35 | if (!message || !chatId) {
36 | console.log('Invalid message or chatId:', { message, chatId });
37 | return;
38 | }
39 |
40 | let userToInsult;
41 |
42 | // Check for mentioned users
43 | if (message.message?.extendedTextMessage?.contextInfo?.mentionedJid?.length > 0) {
44 | userToInsult = message.message.extendedTextMessage.contextInfo.mentionedJid[0];
45 | }
46 | // Check for replied message
47 | else if (message.message?.extendedTextMessage?.contextInfo?.participant) {
48 | userToInsult = message.message.extendedTextMessage.contextInfo.participant;
49 | }
50 |
51 | if (!userToInsult) {
52 | await sock.sendMessage(chatId, {
53 | text: 'Please mention someone or reply to their message to insult them!'
54 | });
55 | return;
56 | }
57 |
58 | const insult = insults[Math.floor(Math.random() * insults.length)];
59 |
60 | // Add delay to avoid rate limiting
61 | await new Promise(resolve => setTimeout(resolve, 1000));
62 |
63 | await sock.sendMessage(chatId, {
64 | text: `Hey @${userToInsult.split('@')[0]}, ${insult}`,
65 | mentions: [userToInsult]
66 | });
67 | } catch (error) {
68 | console.error('Error in insult command:', error);
69 | if (error.data === 429) {
70 | await new Promise(resolve => setTimeout(resolve, 2000));
71 | try {
72 | await sock.sendMessage(chatId, {
73 | text: 'Please try again in a few seconds.'
74 | });
75 | } catch (retryError) {
76 | console.error('Error sending retry message:', retryError);
77 | }
78 | } else {
79 | try {
80 | await sock.sendMessage(chatId, {
81 | text: 'An error occurred while sending the insult.'
82 | });
83 | } catch (sendError) {
84 | console.error('Error sending error message:', sendError);
85 | }
86 | }
87 | }
88 | }
89 |
90 | module.exports = { insultCommand };
91 |
--------------------------------------------------------------------------------
/lib/lightweight_store.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const STORE_FILE = './baileys_store.json'
3 |
4 | // Config: keep last 20 messages per chat (configurable) - More aggressive for lower RAM
5 | let MAX_MESSAGES = 20
6 |
7 | // Try to read config from settings
8 | try {
9 | const settings = require('../settings.js')
10 | if (settings.maxStoreMessages && typeof settings.maxStoreMessages === 'number') {
11 | MAX_MESSAGES = settings.maxStoreMessages
12 | }
13 | } catch (e) {
14 | // Use default if settings not available
15 | }
16 |
17 | const store = {
18 | messages: {},
19 | contacts: {},
20 | chats: {},
21 |
22 | readFromFile(filePath = STORE_FILE) {
23 | try {
24 | if (fs.existsSync(filePath)) {
25 | const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'))
26 | this.contacts = data.contacts || {}
27 | this.chats = data.chats || {}
28 | this.messages = data.messages || {}
29 |
30 | // Clean up any existing data to match new format
31 | this.cleanupData()
32 | }
33 | } catch (e) {
34 | console.warn('Failed to read store file:', e.message)
35 | }
36 | },
37 |
38 | writeToFile(filePath = STORE_FILE) {
39 | try {
40 | const data = JSON.stringify({
41 | contacts: this.contacts,
42 | chats: this.chats,
43 | messages: this.messages
44 | })
45 | fs.writeFileSync(filePath, data)
46 | } catch (e) {
47 | console.warn('Failed to write store file:', e.message)
48 | }
49 | },
50 |
51 | cleanupData() {
52 | // Convert old format messages to new format if needed
53 | if (this.messages) {
54 | Object.keys(this.messages).forEach(jid => {
55 | if (typeof this.messages[jid] === 'object' && !Array.isArray(this.messages[jid])) {
56 | // Old format - convert to new format
57 | const messages = Object.values(this.messages[jid])
58 | this.messages[jid] = messages.slice(-MAX_MESSAGES)
59 | }
60 | })
61 | }
62 | },
63 |
64 | bind(ev) {
65 | ev.on('messages.upsert', ({ messages }) => {
66 | messages.forEach(msg => {
67 | if (!msg.key?.remoteJid) return
68 | const jid = msg.key.remoteJid
69 | this.messages[jid] = this.messages[jid] || []
70 |
71 | // push new message
72 | this.messages[jid].push(msg)
73 |
74 | // trim old ones
75 | if (this.messages[jid].length > MAX_MESSAGES) {
76 | this.messages[jid] = this.messages[jid].slice(-MAX_MESSAGES)
77 | }
78 | })
79 | })
80 |
81 | ev.on('contacts.update', (contacts) => {
82 | contacts.forEach(contact => {
83 | if (contact.id) {
84 | this.contacts[contact.id] = {
85 | id: contact.id,
86 | name: contact.notify || contact.name || ''
87 | }
88 | }
89 | })
90 | })
91 |
92 | ev.on('chats.set', (chats) => {
93 | this.chats = {}
94 | chats.forEach(chat => {
95 | this.chats[chat.id] = { id: chat.id, subject: chat.subject || '' }
96 | })
97 | })
98 | },
99 |
100 | async loadMessage(jid, id) {
101 | return this.messages[jid]?.find(m => m.key.id === id) || null
102 | },
103 |
104 | // Get store statistics
105 | getStats() {
106 | let totalMessages = 0
107 | let totalContacts = Object.keys(this.contacts).length
108 | let totalChats = Object.keys(this.chats).length
109 |
110 | Object.values(this.messages).forEach(chatMessages => {
111 | if (Array.isArray(chatMessages)) {
112 | totalMessages += chatMessages.length
113 | }
114 | })
115 |
116 | return {
117 | messages: totalMessages,
118 | contacts: totalContacts,
119 | chats: totalChats,
120 | maxMessagesPerChat: MAX_MESSAGES
121 | }
122 | }
123 | }
124 |
125 | module.exports = store
126 |
--------------------------------------------------------------------------------
/commands/ai.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const fetch = require('node-fetch');
3 |
4 | async function aiCommand(sock, chatId, message) {
5 | try {
6 | const text = message.message?.conversation || message.message?.extendedTextMessage?.text;
7 |
8 | if (!text) {
9 | return await sock.sendMessage(chatId, {
10 | text: "Please provide a question after .gpt or .gemini\n\nExample: .gpt write a basic html code"
11 | }, {
12 | quoted: message
13 | });
14 | }
15 |
16 | // Get the command and query
17 | const parts = text.split(' ');
18 | const command = parts[0].toLowerCase();
19 | const query = parts.slice(1).join(' ').trim();
20 |
21 | if (!query) {
22 | return await sock.sendMessage(chatId, {
23 | text: "Please provide a question after .gpt or .gemini"
24 | }, {quoted:message});
25 | }
26 |
27 | try {
28 | // Show processing message
29 | await sock.sendMessage(chatId, {
30 | react: { text: '🤖', key: message.key }
31 | });
32 |
33 | if (command === '.gpt') {
34 | // Call the GPT API
35 | const response = await axios.get(`https://api.dreaded.site/api/chatgpt?text=${encodeURIComponent(query)}`);
36 |
37 | if (response.data && response.data.success && response.data.result) {
38 | const answer = response.data.result.prompt;
39 | await sock.sendMessage(chatId, {
40 | text: answer
41 | }, {
42 | quoted: message
43 | });
44 |
45 | } else {
46 | throw new Error('Invalid response from API');
47 | }
48 | } else if (command === '.gemini') {
49 | const apis = [
50 | `https://vapis.my.id/api/gemini?q=${encodeURIComponent(query)}`,
51 | `https://api.siputzx.my.id/api/ai/gemini-pro?content=${encodeURIComponent(query)}`,
52 | `https://api.ryzendesu.vip/api/ai/gemini?text=${encodeURIComponent(query)}`,
53 | `https://api.dreaded.site/api/gemini2?text=${encodeURIComponent(query)}`,
54 | `https://api.giftedtech.my.id/api/ai/geminiai?apikey=gifted&q=${encodeURIComponent(query)}`,
55 | `https://api.giftedtech.my.id/api/ai/geminiaipro?apikey=gifted&q=${encodeURIComponent(query)}`
56 | ];
57 |
58 | for (const api of apis) {
59 | try {
60 | const response = await fetch(api);
61 | const data = await response.json();
62 |
63 | if (data.message || data.data || data.answer || data.result) {
64 | const answer = data.message || data.data || data.answer || data.result;
65 | await sock.sendMessage(chatId, {
66 | text: answer
67 | }, {
68 | quoted: message
69 | });
70 |
71 | return;
72 | }
73 | } catch (e) {
74 | continue;
75 | }
76 | }
77 | throw new Error('All Gemini APIs failed');
78 | }
79 | } catch (error) {
80 | console.error('API Error:', error);
81 | await sock.sendMessage(chatId, {
82 | text: "❌ Failed to get response. Please try again later.",
83 | contextInfo: {
84 | mentionedJid: [message.key.participant || message.key.remoteJid],
85 | quotedMessage: message.message
86 | }
87 | }, {
88 | quoted: message
89 | });
90 | }
91 | } catch (error) {
92 | console.error('AI Command Error:', error);
93 | await sock.sendMessage(chatId, {
94 | text: "❌ An error occurred. Please try again later.",
95 | contextInfo: {
96 | mentionedJid: [message.key.participant || message.key.remoteJid],
97 | quotedMessage: message.message
98 | }
99 | }, {
100 | quoted: message
101 | });
102 | }
103 | }
104 |
105 | module.exports = aiCommand;
--------------------------------------------------------------------------------
/lib/welcome.js:
--------------------------------------------------------------------------------
1 | const { addWelcome, delWelcome, isWelcomeOn, addGoodbye, delGoodBye, isGoodByeOn } = require('../lib/index');
2 | const { delay } = require('@whiskeysockets/baileys');
3 |
4 | async function handleWelcome(sock, chatId, message, match) {
5 | if (!match) {
6 | return sock.sendMessage(chatId, {
7 | text: `📥 *Welcome Message Setup*\n\n✅ *.welcome on* — Enable welcome messages\n🛠️ *.welcome set Your custom message* — Set a custom welcome message\n🚫 *.welcome off* — Disable welcome messages\n\n*Available Variables:*\n• {user} - Mentions the new member\n• {group} - Shows group name\n• {description} - Shows group description`,
8 | quoted: message
9 | });
10 | }
11 |
12 | const [command, ...args] = match.split(' ');
13 | const lowerCommand = command.toLowerCase();
14 | const customMessage = args.join(' ');
15 |
16 | if (lowerCommand === 'on') {
17 | if (await isWelcomeOn(chatId)) {
18 | return sock.sendMessage(chatId, { text: '⚠️ Welcome messages are *already enabled*.', quoted: message });
19 | }
20 | await addWelcome(chatId, true, 'Welcome {user} to {group}! 🎉');
21 | return sock.sendMessage(chatId, { text: '✅ Welcome messages *enabled* with simple message. Use *.welcome set [your message]* to customize.', quoted: message });
22 | }
23 |
24 | if (lowerCommand === 'off') {
25 | if (!(await isWelcomeOn(chatId))) {
26 | return sock.sendMessage(chatId, { text: '⚠️ Welcome messages are *already disabled*.', quoted: message });
27 | }
28 | await delWelcome(chatId);
29 | return sock.sendMessage(chatId, { text: '✅ Welcome messages *disabled* for this group.', quoted: message });
30 | }
31 |
32 | if (lowerCommand === 'set') {
33 | if (!customMessage) {
34 | return sock.sendMessage(chatId, { text: '⚠️ Please provide a custom welcome message. Example: *.welcome set Welcome to the group!*', quoted: message });
35 | }
36 | await addWelcome(chatId, true, customMessage);
37 | return sock.sendMessage(chatId, { text: '✅ Custom welcome message *set successfully*.', quoted: message });
38 | }
39 |
40 | // If no valid command is provided
41 | return sock.sendMessage(chatId, {
42 | text: `❌ Invalid command. Use:\n*.welcome on* - Enable\n*.welcome set [message]* - Set custom message\n*.welcome off* - Disable`,
43 | quoted: message
44 | });
45 | }
46 |
47 | async function handleGoodbye(sock, chatId, message, match) {
48 | const lower = match?.toLowerCase();
49 |
50 | if (!match) {
51 | return sock.sendMessage(chatId, {
52 | text: `📤 *Goodbye Message Setup*\n\n✅ *.goodbye on* — Enable goodbye messages\n🛠️ *.goodbye set Your custom message* — Set a custom goodbye message\n🚫 *.goodbye off* — Disable goodbye messages\n\n*Available Variables:*\n• {user} - Mentions the leaving member\n• {group} - Shows group name`,
53 | quoted: message
54 | });
55 | }
56 |
57 | if (lower === 'on') {
58 | if (await isGoodByeOn(chatId)) {
59 | return sock.sendMessage(chatId, { text: '⚠️ Goodbye messages are *already enabled*.', quoted: message });
60 | }
61 | await addGoodbye(chatId, true, 'Goodbye {user} 👋');
62 | return sock.sendMessage(chatId, { text: '✅ Goodbye messages *enabled* with simple message. Use *.goodbye set [your message]* to customize.', quoted: message });
63 | }
64 |
65 | if (lower === 'off') {
66 | if (!(await isGoodByeOn(chatId))) {
67 | return sock.sendMessage(chatId, { text: '⚠️ Goodbye messages are *already disabled*.', quoted: message });
68 | }
69 | await delGoodBye(chatId);
70 | return sock.sendMessage(chatId, { text: '✅ Goodbye messages *disabled* for this group.', quoted: message });
71 | }
72 |
73 | if (lower.startsWith('set ')) {
74 | const customMessage = match.substring(4);
75 | if (!customMessage) {
76 | return sock.sendMessage(chatId, { text: '⚠️ Please provide a custom goodbye message. Example: *.goodbye set Goodbye!*', quoted: message });
77 | }
78 | await addGoodbye(chatId, true, customMessage);
79 | return sock.sendMessage(chatId, { text: '✅ Custom goodbye message *set successfully*.', quoted: message });
80 | }
81 |
82 | // If no valid command is provided
83 | return sock.sendMessage(chatId, {
84 | text: `❌ Invalid command. Use:\n*.goodbye on* - Enable\n*.goodbye set [message]* - Set custom message\n*.goodbye off* - Disable`,
85 | quoted: message
86 | });
87 | }
88 |
89 | module.exports = { handleWelcome, handleGoodbye };
90 | // This code handles welcome and goodbye messages in a WhatsApp group using the Baileys library.
--------------------------------------------------------------------------------
/commands/translate.js:
--------------------------------------------------------------------------------
1 | const fetch = require('node-fetch');
2 |
3 | async function handleTranslateCommand(sock, chatId, message, match) {
4 | try {
5 | // Show typing indicator
6 | await sock.presenceSubscribe(chatId);
7 | await sock.sendPresenceUpdate('composing', chatId);
8 |
9 | let textToTranslate = '';
10 | let lang = '';
11 |
12 | // Check if it's a reply
13 | const quotedMessage = message.message?.extendedTextMessage?.contextInfo?.quotedMessage;
14 | if (quotedMessage) {
15 | // Get text from quoted message
16 | textToTranslate = quotedMessage.conversation ||
17 | quotedMessage.extendedTextMessage?.text ||
18 | quotedMessage.imageMessage?.caption ||
19 | quotedMessage.videoMessage?.caption ||
20 | '';
21 |
22 | // Get language from command
23 | lang = match.trim();
24 | } else {
25 | // Parse command arguments for direct message
26 | const args = match.trim().split(' ');
27 | if (args.length < 2) {
28 | return sock.sendMessage(chatId, {
29 | text: `*TRANSLATOR*\n\nUsage:\n1. Reply to a message with: .translate or .trt \n2. Or type: .translate or .trt \n\nExample:\n.translate hello fr\n.trt hello fr\n\nLanguage codes:\nfr - French\nes - Spanish\nde - German\nit - Italian\npt - Portuguese\nru - Russian\nja - Japanese\nko - Korean\nzh - Chinese\nar - Arabic\nhi - Hindi`,
30 | quoted: message
31 | });
32 | }
33 |
34 | lang = args.pop(); // Get language code
35 | textToTranslate = args.join(' '); // Get text to translate
36 | }
37 |
38 | if (!textToTranslate) {
39 | return sock.sendMessage(chatId, {
40 | text: '❌ No text found to translate. Please provide text or reply to a message.',
41 | quoted: message
42 | });
43 | }
44 |
45 | // Try multiple translation APIs in sequence
46 | let translatedText = null;
47 | let error = null;
48 |
49 | // Try API 1 (Google Translate API)
50 | try {
51 | const response = await fetch(`https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=${lang}&dt=t&q=${encodeURIComponent(textToTranslate)}`);
52 | if (response.ok) {
53 | const data = await response.json();
54 | if (data && data[0] && data[0][0] && data[0][0][0]) {
55 | translatedText = data[0][0][0];
56 | }
57 | }
58 | } catch (e) {
59 | error = e;
60 | }
61 |
62 | // If API 1 fails, try API 2
63 | if (!translatedText) {
64 | try {
65 | const response = await fetch(`https://api.mymemory.translated.net/get?q=${encodeURIComponent(textToTranslate)}&langpair=auto|${lang}`);
66 | if (response.ok) {
67 | const data = await response.json();
68 | if (data && data.responseData && data.responseData.translatedText) {
69 | translatedText = data.responseData.translatedText;
70 | }
71 | }
72 | } catch (e) {
73 | error = e;
74 | }
75 | }
76 |
77 | // If API 2 fails, try API 3
78 | if (!translatedText) {
79 | try {
80 | const response = await fetch(`https://api.dreaded.site/api/translate?text=${encodeURIComponent(textToTranslate)}&lang=${lang}`);
81 | if (response.ok) {
82 | const data = await response.json();
83 | if (data && data.translated) {
84 | translatedText = data.translated;
85 | }
86 | }
87 | } catch (e) {
88 | error = e;
89 | }
90 | }
91 |
92 | if (!translatedText) {
93 | throw new Error('All translation APIs failed');
94 | }
95 |
96 | // Send translation
97 | await sock.sendMessage(chatId, {
98 | text: `${translatedText}`,
99 | }, {
100 | quoted: message
101 | });
102 |
103 | } catch (error) {
104 | console.error('❌ Error in translate command:', error);
105 | await sock.sendMessage(chatId, {
106 | text: '❌ Failed to translate text. Please try again later.\n\nUsage:\n1. Reply to a message with: .translate or .trt \n2. Or type: .translate or .trt ',
107 | quoted: message
108 | });
109 | }
110 | }
111 |
112 | module.exports = {
113 | handleTranslateCommand
114 | };
--------------------------------------------------------------------------------
/commands/removebg.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const { downloadContentFromMessage } = require('@whiskeysockets/baileys');
3 | const { uploadImage } = require('../lib/uploadImage');
4 |
5 | async function getQuotedOrOwnImageUrl(sock, message) {
6 | // 1) Quoted image (highest priority)
7 | const quoted = message.message?.extendedTextMessage?.contextInfo?.quotedMessage;
8 | if (quoted?.imageMessage) {
9 | const stream = await downloadContentFromMessage(quoted.imageMessage, 'image');
10 | const chunks = [];
11 | for await (const chunk of stream) chunks.push(chunk);
12 | const buffer = Buffer.concat(chunks);
13 | return await uploadImage(buffer);
14 | }
15 |
16 | // 2) Image in the current message
17 | if (message.message?.imageMessage) {
18 | const stream = await downloadContentFromMessage(message.message.imageMessage, 'image');
19 | const chunks = [];
20 | for await (const chunk of stream) chunks.push(chunk);
21 | const buffer = Buffer.concat(chunks);
22 | return await uploadImage(buffer);
23 | }
24 |
25 | return null;
26 | }
27 |
28 | module.exports = {
29 | name: 'removebg',
30 | alias: ['rmbg', 'nobg'],
31 | category: 'general',
32 | desc: 'Remove background from images',
33 | async exec(sock, message, args) {
34 | try {
35 | const chatId = message.key.remoteJid;
36 | let imageUrl = null;
37 |
38 | // Check if args contain a URL
39 | if (args.length > 0) {
40 | const url = args.join(' ');
41 | if (isValidUrl(url)) {
42 | imageUrl = url;
43 | } else {
44 | return sock.sendMessage(chatId, {
45 | text: '❌ Invalid URL provided.\n\nUsage: `.removebg https://example.com/image.jpg`'
46 | }, { quoted: message });
47 | }
48 | } else {
49 | // Try to get image from message or quoted message
50 | imageUrl = await getQuotedOrOwnImageUrl(sock, message);
51 |
52 | if (!imageUrl) {
53 | return sock.sendMessage(chatId, {
54 | text: '📸 *Remove Background Command*\n\nUsage:\n• `.removebg `\n• Reply to an image with `.removebg`\n• Send image with `.removebg`\n\nExample: `.removebg https://example.com/image.jpg`'
55 | }, { quoted: message });
56 | }
57 | }
58 |
59 |
60 | // Call the remove background API
61 | const apiUrl = `https://api.siputzx.my.id/api/iloveimg/removebg?image=${encodeURIComponent(imageUrl)}`;
62 |
63 | const response = await axios.get(apiUrl, {
64 | responseType: 'arraybuffer',
65 | timeout: 30000, // 30 second timeout
66 | headers: {
67 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
68 | }
69 | });
70 |
71 | if (response.status === 200 && response.data) {
72 | // Send the processed image
73 | await sock.sendMessage(chatId, {
74 | image: response.data,
75 | caption: '✨ *Background removed successfully!*\n\nPOWERED BY SNOWBIRD'
76 | }, { quoted: message });
77 | } else {
78 | throw new Error('Failed to process image');
79 | }
80 |
81 | } catch (error) {
82 | console.error('RemoveBG Error:', error.message);
83 |
84 | let errorMessage = '❌ Failed to remove background.';
85 |
86 | if (error.response?.status === 429) {
87 | errorMessage = '⏰ Rate limit exceeded. Please try again later.';
88 | } else if (error.response?.status === 400) {
89 | errorMessage = '❌ Invalid image URL or format.';
90 | } else if (error.response?.status === 500) {
91 | errorMessage = '🔧 Server error. Please try again later.';
92 | } else if (error.code === 'ECONNABORTED') {
93 | errorMessage = '⏰ Request timeout. Please try again.';
94 | } else if (error.message.includes('ENOTFOUND') || error.message.includes('ECONNREFUSED')) {
95 | errorMessage = '🌐 Network error. Please check your connection.';
96 | }
97 |
98 | await sock.sendMessage(chatId, {
99 | text: errorMessage
100 | }, { quoted: message });
101 | }
102 | }
103 | };
104 |
105 | // Helper function to validate URL
106 | function isValidUrl(string) {
107 | try {
108 | new URL(string);
109 | return true;
110 | } catch (_) {
111 | return false;
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/commands/delete.js:
--------------------------------------------------------------------------------
1 | const isAdmin = require('../lib/isAdmin');
2 | const store = require('../lib/lightweight_store');
3 |
4 | async function deleteCommand(sock, chatId, message, senderId) {
5 | try {
6 | const { isSenderAdmin, isBotAdmin } = await isAdmin(sock, chatId, senderId);
7 |
8 | if (!isBotAdmin) {
9 | await sock.sendMessage(chatId, { text: 'I need to be an admin to delete messages.' }, { quoted: message });
10 | return;
11 | }
12 |
13 | if (!isSenderAdmin) {
14 | await sock.sendMessage(chatId, { text: 'Only admins can use the .delete command.' }, { quoted: message });
15 | return;
16 | }
17 |
18 | // Determine target user and count
19 | const text = message.message?.conversation || message.message?.extendedTextMessage?.text || '';
20 | const parts = text.trim().split(/\s+/);
21 | let countArg = 1;
22 | if (parts.length > 1) {
23 | const maybeNum = parseInt(parts[1], 10);
24 | if (!isNaN(maybeNum) && maybeNum > 0) countArg = Math.min(maybeNum, 50);
25 | }
26 |
27 | const ctxInfo = message.message?.extendedTextMessage?.contextInfo || {};
28 | const mentioned = Array.isArray(ctxInfo.mentionedJid) && ctxInfo.mentionedJid.length > 0 ? ctxInfo.mentionedJid[0] : null;
29 | const repliedParticipant = ctxInfo.participant || null;
30 |
31 | // Determine target user: replied > mentioned; if neither, do not proceed
32 | let targetUser = null;
33 | let repliedMsgId = null;
34 | if (repliedParticipant && ctxInfo.stanzaId) {
35 | targetUser = repliedParticipant;
36 | repliedMsgId = ctxInfo.stanzaId;
37 | } else if (mentioned) {
38 | targetUser = mentioned;
39 | } else {
40 | await sock.sendMessage(chatId, { text: 'Please reply to a user\'s message or mention a user to delete their recent messages.' }, { quoted: message });
41 | return;
42 | }
43 |
44 | // Gather last N messages from targetUser in this chat
45 | const chatMessages = Array.isArray(store.messages[chatId]) ? store.messages[chatId] : [];
46 | // Newest last; we traverse from end backwards
47 | const toDelete = [];
48 | const seenIds = new Set();
49 |
50 | // If replying, prioritize deleting the exact replied message first (counts toward N)
51 | if (repliedMsgId) {
52 | const repliedInStore = chatMessages.find(m => m.key.id === repliedMsgId && (m.key.participant || m.key.remoteJid) === targetUser);
53 | if (repliedInStore) {
54 | toDelete.push(repliedInStore);
55 | seenIds.add(repliedInStore.key.id);
56 | } else {
57 | // If not found in store, still attempt delete directly
58 | try {
59 | await sock.sendMessage(chatId, {
60 | delete: {
61 | remoteJid: chatId,
62 | fromMe: false,
63 | id: repliedMsgId,
64 | participant: repliedParticipant
65 | }
66 | });
67 | // Count this as one deleted and reduce required count
68 | countArg = Math.max(0, countArg - 1);
69 | } catch {}
70 | }
71 | }
72 | for (let i = chatMessages.length - 1; i >= 0 && toDelete.length < countArg; i--) {
73 | const m = chatMessages[i];
74 | const participant = m.key.participant || m.key.remoteJid;
75 | if (participant === targetUser && !seenIds.has(m.key.id)) {
76 | // skip protocol/system messages
77 | if (!m.message?.protocolMessage) {
78 | toDelete.push(m);
79 | seenIds.add(m.key.id);
80 | }
81 | }
82 | }
83 |
84 | if (toDelete.length === 0) {
85 | await sock.sendMessage(chatId, { text: 'No recent messages found for the target user.' }, { quoted: message });
86 | return;
87 | }
88 |
89 | // Delete sequentially with small delay
90 | for (const m of toDelete) {
91 | try {
92 | const msgParticipant = m.key.participant || targetUser;
93 | await sock.sendMessage(chatId, {
94 | delete: {
95 | remoteJid: chatId,
96 | fromMe: false,
97 | id: m.key.id,
98 | participant: msgParticipant
99 | }
100 | });
101 | await new Promise(r => setTimeout(r, 300));
102 | } catch (e) {
103 | // continue
104 | }
105 | }
106 |
107 | await sock.sendMessage(chatId, { text: `Deleted ${toDelete.length} message(s) from @${(targetUser||'').split('@')[0]}`, mentions: [targetUser] }, { quoted: message });
108 | } catch (err) {
109 | await sock.sendMessage(chatId, { text: 'Failed to delete messages.' }, { quoted: message });
110 | }
111 | }
112 |
113 | module.exports = deleteCommand;
114 |
115 |
--------------------------------------------------------------------------------
/commands/remini.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const { downloadContentFromMessage } = require('@whiskeysockets/baileys');
3 | const { uploadImage } = require('../lib/uploadImage');
4 |
5 | async function getQuotedOrOwnImageUrl(sock, message) {
6 | // 1) Quoted image (highest priority)
7 | const quoted = message.message?.extendedTextMessage?.contextInfo?.quotedMessage;
8 | if (quoted?.imageMessage) {
9 | const stream = await downloadContentFromMessage(quoted.imageMessage, 'image');
10 | const chunks = [];
11 | for await (const chunk of stream) chunks.push(chunk);
12 | const buffer = Buffer.concat(chunks);
13 | return await uploadImage(buffer);
14 | }
15 |
16 | // 2) Image in the current message
17 | if (message.message?.imageMessage) {
18 | const stream = await downloadContentFromMessage(message.message.imageMessage, 'image');
19 | const chunks = [];
20 | for await (const chunk of stream) chunks.push(chunk);
21 | const buffer = Buffer.concat(chunks);
22 | return await uploadImage(buffer);
23 | }
24 |
25 | return null;
26 | }
27 |
28 | async function reminiCommand(sock, chatId, message, args) {
29 | try {
30 | let imageUrl = null;
31 |
32 | // Check if args contain a URL
33 | if (args.length > 0) {
34 | const url = args.join(' ');
35 | if (isValidUrl(url)) {
36 | imageUrl = url;
37 | } else {
38 | return sock.sendMessage(chatId, {
39 | text: '❌ Invalid URL provided.\n\nUsage: `.remini https://example.com/image.jpg`'
40 | }, { quoted: message });
41 | }
42 | } else {
43 | // Try to get image from message or quoted message
44 | imageUrl = await getQuotedOrOwnImageUrl(sock, message);
45 |
46 | if (!imageUrl) {
47 | return sock.sendMessage(chatId, {
48 | text: '📸 *Remini AI Enhancement Command*\n\nUsage:\n• `.remini `\n• Reply to an image with `.remini`\n• Send image with `.remini`\n\nExample: `.remini https://example.com/image.jpg`'
49 | }, { quoted: message });
50 | }
51 | }
52 |
53 | // Call the Remini API
54 | const apiUrl = `https://api.princetechn.com/api/tools/remini?apikey=prince&url=${encodeURIComponent(imageUrl)}`;
55 |
56 | const response = await axios.get(apiUrl, {
57 | timeout: 60000, // 60 second timeout (AI processing takes longer)
58 | headers: {
59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
60 | }
61 | });
62 |
63 |
64 | if (response.data && response.data.success && response.data.result) {
65 | const result = response.data.result;
66 |
67 | if (result.image_url) {
68 | // Download the enhanced image
69 | const imageResponse = await axios.get(result.image_url, {
70 | responseType: 'arraybuffer',
71 | timeout: 30000
72 | });
73 |
74 | if (imageResponse.status === 200 && imageResponse.data) {
75 | // Send the enhanced image
76 | await sock.sendMessage(chatId, {
77 | image: imageResponse.data,
78 | caption: '✨ *Image enhanced successfully!*\n\nPOWERED BY SNOWBIRD'
79 | }, { quoted: message });
80 | } else {
81 | throw new Error('Failed to download enhanced image');
82 | }
83 | } else {
84 | throw new Error(result.message || 'Failed to enhance image');
85 | }
86 | } else {
87 | throw new Error('API returned invalid response');
88 | }
89 |
90 | } catch (error) {
91 | console.error('Remini Error:', error.message);
92 |
93 | let errorMessage = '❌ Failed to enhance image.';
94 |
95 | if (error.response?.status === 429) {
96 | errorMessage = '⏰ Rate limit exceeded. Please try again later.';
97 | } else if (error.response?.status === 400) {
98 | errorMessage = '❌ Invalid image URL or format.';
99 | } else if (error.response?.status === 500) {
100 | errorMessage = '🔧 Server error. Please try again later.';
101 | } else if (error.code === 'ECONNABORTED') {
102 | errorMessage = '⏰ Request timeout. Please try again.';
103 | } else if (error.message.includes('ENOTFOUND') || error.message.includes('ECONNREFUSED')) {
104 | errorMessage = '🌐 Network error. Please check your connection.';
105 | } else if (error.message.includes('Error processing image')) {
106 | errorMessage = '❌ Image processing failed. Please try with a different image.';
107 | }
108 |
109 | await sock.sendMessage(chatId, {
110 | text: errorMessage
111 | }, { quoted: message });
112 | }
113 | }
114 |
115 | // Helper function to validate URL
116 | function isValidUrl(string) {
117 | try {
118 | new URL(string);
119 | return true;
120 | } catch (_) {
121 | return false;
122 | }
123 | }
124 |
125 | module.exports = { reminiCommand };
126 |
--------------------------------------------------------------------------------
/commands/facebook.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const fs = require('fs');
3 | const path = require('path');
4 |
5 | async function facebookCommand(sock, chatId, message) {
6 | try {
7 | const text = message.message?.conversation || message.message?.extendedTextMessage?.text;
8 | const url = text.split(' ').slice(1).join(' ').trim();
9 |
10 | if (!url) {
11 | return await sock.sendMessage(chatId, {
12 | text: "Please provide a Facebook video URL.\nExample: .fb https://www.facebook.com/..."
13 | }, { quoted: message });
14 | }
15 |
16 | // Validate Facebook URL
17 | if (!url.includes('facebook.com')) {
18 | return await sock.sendMessage(chatId, {
19 | text: "That is not a Facebook link."
20 | }, { quoted: message });
21 | }
22 |
23 | // Send loading reaction
24 | await sock.sendMessage(chatId, {
25 | react: { text: '🔄', key: message.key }
26 | });
27 |
28 | // Resolve share/short URLs to their final destination first
29 | let resolvedUrl = url;
30 | try {
31 | const res = await axios.get(url, { timeout: 20000, maxRedirects: 10, headers: { 'User-Agent': 'Mozilla/5.0' } });
32 | const possible = res?.request?.res?.responseUrl;
33 | if (possible && typeof possible === 'string') {
34 | resolvedUrl = possible;
35 | }
36 | } catch {
37 | // ignore resolution errors; use original url
38 | }
39 |
40 | // Helper to call API with retries and variants
41 | async function fetchFromApi(u) {
42 | const apiUrl = `https://api.princetechn.com/api/download/facebook?apikey=prince&url=${encodeURIComponent(u)}`;
43 | return axios.get(apiUrl, {
44 | timeout: 40000,
45 | headers: {
46 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36',
47 | 'Accept': 'application/json, text/plain, */*'
48 | },
49 | maxRedirects: 5,
50 | validateStatus: s => s >= 200 && s < 500
51 | });
52 | }
53 |
54 | // Try resolved URL, then fallback to original URL
55 | let response;
56 | try {
57 | response = await fetchFromApi(resolvedUrl);
58 | if (!response || response.status >= 400 || !response.data) throw new Error('bad');
59 | } catch {
60 | response = await fetchFromApi(url);
61 | }
62 |
63 | const data = response.data;
64 |
65 | if (!data || data.status !== 200 || !data.success || !data.result) {
66 | return await sock.sendMessage(chatId, {
67 | text: 'Sorry the API did not return a valid response. Please try again later!'
68 | }, { quoted: message });
69 | }
70 |
71 | const fbvid = data.result.hd_video || data.result.sd_video;
72 |
73 | if (!fbvid) {
74 | return await sock.sendMessage(chatId, {
75 | text: 'Wrong Facebook data. Please ensure the video exists.'
76 | }, { quoted: message });
77 | }
78 |
79 | // Create temp directory if it doesn't exist
80 | const tmpDir = path.join(process.cwd(), 'tmp');
81 | if (!fs.existsSync(tmpDir)) {
82 | fs.mkdirSync(tmpDir, { recursive: true });
83 | }
84 |
85 | // Generate temp file path
86 | const tempFile = path.join(tmpDir, `fb_${Date.now()}.mp4`);
87 |
88 | // Download the video
89 | const videoResponse = await axios({
90 | method: 'GET',
91 | url: fbvid,
92 | responseType: 'stream',
93 | headers: {
94 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
95 | 'Accept': 'video/mp4,video/*;q=0.9,*/*;q=0.8',
96 | 'Accept-Language': 'en-US,en;q=0.5',
97 | 'Range': 'bytes=0-',
98 | 'Connection': 'keep-alive',
99 | 'Referer': 'https://www.facebook.com/'
100 | }
101 | });
102 |
103 | const writer = fs.createWriteStream(tempFile);
104 | videoResponse.data.pipe(writer);
105 |
106 | await new Promise((resolve, reject) => {
107 | writer.on('finish', resolve);
108 | writer.on('error', reject);
109 | });
110 |
111 | // Check if file was downloaded successfully
112 | if (!fs.existsSync(tempFile) || fs.statSync(tempFile).size === 0) {
113 | throw new Error('Failed to download video');
114 | }
115 |
116 | // Send the video
117 | await sock.sendMessage(chatId, {
118 | video: { url: tempFile },
119 | mimetype: "video/mp4",
120 | caption: "POWERED BY SNOWBIRD"
121 | }, { quoted: message });
122 |
123 | // Clean up temp file
124 | try {
125 | fs.unlinkSync(tempFile);
126 | } catch (err) {
127 | console.error('Error cleaning up temp file:', err);
128 | }
129 |
130 | } catch (error) {
131 | console.error('Error in Facebook command:', error);
132 | await sock.sendMessage(chatId, {
133 | text: "An error occurred. API might be down. Error: " + error.message
134 | }, { quoted: message });
135 | }
136 | }
137 |
138 | module.exports = facebookCommand;
--------------------------------------------------------------------------------
/commands/instagram.js:
--------------------------------------------------------------------------------
1 | const { igdl } = require("ruhend-scraper");
2 |
3 | // Store processed message IDs to prevent duplicates
4 | const processedMessages = new Set();
5 |
6 | // Function to extract unique media URLs with simple deduplication
7 | function extractUniqueMedia(mediaData) {
8 | const uniqueMedia = [];
9 | const seenUrls = new Set();
10 |
11 | for (const media of mediaData) {
12 | if (!media.url) continue;
13 |
14 | // Only check for exact URL duplicates
15 | if (!seenUrls.has(media.url)) {
16 | seenUrls.add(media.url);
17 | uniqueMedia.push(media);
18 | }
19 | }
20 |
21 | return uniqueMedia;
22 | }
23 |
24 | // Function to validate media URL
25 | function isValidMediaUrl(url) {
26 | if (!url || typeof url !== 'string') return false;
27 |
28 | // Accept any URL that looks like media
29 | return url.includes('cdninstagram.com') ||
30 | url.includes('instagram') ||
31 | url.includes('http');
32 | }
33 |
34 | async function instagramCommand(sock, chatId, message) {
35 | try {
36 | // Check if message has already been processed
37 | if (processedMessages.has(message.key.id)) {
38 | return;
39 | }
40 |
41 | // Add message ID to processed set
42 | processedMessages.add(message.key.id);
43 |
44 | // Clean up old message IDs after 5 minutes
45 | setTimeout(() => {
46 | processedMessages.delete(message.key.id);
47 | }, 5 * 60 * 1000);
48 |
49 | const text = message.message?.conversation || message.message?.extendedTextMessage?.text;
50 |
51 | if (!text) {
52 | return await sock.sendMessage(chatId, {
53 | text: "Please provide an Instagram link for the video."
54 | });
55 | }
56 |
57 | // Check for various Instagram URL formats
58 | const instagramPatterns = [
59 | /https?:\/\/(?:www\.)?instagram\.com\//,
60 | /https?:\/\/(?:www\.)?instagr\.am\//,
61 | /https?:\/\/(?:www\.)?instagram\.com\/p\//,
62 | /https?:\/\/(?:www\.)?instagram\.com\/reel\//,
63 | /https?:\/\/(?:www\.)?instagram\.com\/tv\//
64 | ];
65 |
66 | const isValidUrl = instagramPatterns.some(pattern => pattern.test(text));
67 |
68 | if (!isValidUrl) {
69 | return await sock.sendMessage(chatId, {
70 | text: "That is not a valid Instagram link. Please provide a valid Instagram post, reel, or video link."
71 | });
72 | }
73 |
74 | await sock.sendMessage(chatId, {
75 | react: { text: '🔄', key: message.key }
76 | });
77 |
78 | const downloadData = await igdl(text);
79 |
80 | if (!downloadData || !downloadData.data || downloadData.data.length === 0) {
81 | return await sock.sendMessage(chatId, {
82 | text: "❌ No media found at the provided link. The post might be private or the link is invalid."
83 | });
84 | }
85 |
86 | const mediaData = downloadData.data;
87 |
88 | // Simple deduplication - just remove exact URL duplicates
89 | const uniqueMedia = extractUniqueMedia(mediaData);
90 |
91 | // Limit to maximum 20 unique media items
92 | const mediaToDownload = uniqueMedia.slice(0, 20);
93 |
94 | if (mediaToDownload.length === 0) {
95 | return await sock.sendMessage(chatId, {
96 | text: "❌ No valid media found to download. This might be a private post or the scraper failed."
97 | });
98 | }
99 |
100 | // Download all media silently without status messages
101 | for (let i = 0; i < mediaToDownload.length; i++) {
102 | try {
103 | const media = mediaToDownload[i];
104 | const mediaUrl = media.url;
105 |
106 | // Check if URL ends with common video extensions
107 | const isVideo = /\.(mp4|mov|avi|mkv|webm)$/i.test(mediaUrl) ||
108 | media.type === 'video' ||
109 | text.includes('/reel/') ||
110 | text.includes('/tv/');
111 |
112 | if (isVideo) {
113 | await sock.sendMessage(chatId, {
114 | video: { url: mediaUrl },
115 | mimetype: "video/mp4",
116 | caption: "POWERED BY SNOWBIRD"
117 | }, { quoted: message });
118 | } else {
119 | await sock.sendMessage(chatId, {
120 | image: { url: mediaUrl },
121 | caption: "POWERED BY SNOWBIRD"
122 | }, { quoted: message });
123 | }
124 |
125 | // Add small delay between downloads to prevent rate limiting
126 | if (i < mediaToDownload.length - 1) {
127 | await new Promise(resolve => setTimeout(resolve, 1000));
128 | }
129 |
130 | } catch (mediaError) {
131 | console.error(`Error downloading media ${i + 1}:`, mediaError);
132 | // Continue with next media if one fails
133 | }
134 | }
135 |
136 | } catch (error) {
137 | console.error('Error in Instagram command:', error);
138 | await sock.sendMessage(chatId, {
139 | text: "❌ An error occurred while processing the Instagram request. Please try again."
140 | });
141 | }
142 | }
143 |
144 | module.exports = instagramCommand;
145 |
--------------------------------------------------------------------------------
/commands/pair.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const { sleep } = require('../lib/myfunc');
3 |
4 | async function pairCommand(sock, chatId, message, q) {
5 | try {
6 | if (!q) {
7 | return await sock.sendMessage(chatId, {
8 | text: "Please provide valid WhatsApp number\nExample: .pair 91702395XXXX",
9 | contextInfo: {
10 | forwardingScore: 1,
11 | isForwarded: true,
12 | forwardedNewsletterMessageInfo: {
13 | newsletterJid: '120363399707841760@newsletter+',
14 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
15 | serverMessageId: -1
16 | }
17 | }
18 | });
19 | }
20 |
21 | const numbers = q.split(',')
22 | .map((v) => v.replace(/[^0-9]/g, ''))
23 | .filter((v) => v.length > 5 && v.length < 20);
24 |
25 | if (numbers.length === 0) {
26 | return await sock.sendMessage(chatId, {
27 | text: "Invalid number❌️ Please use the correct format!",
28 | contextInfo: {
29 | forwardingScore: 1,
30 | isForwarded: true,
31 | forwardedNewsletterMessageInfo: {
32 | newsletterJid: '120363399707841760@newsletter',
33 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
34 | serverMessageId: -1
35 | }
36 | }
37 | });
38 | }
39 |
40 | for (const number of numbers) {
41 | const whatsappID = number + '@s.whatsapp.net';
42 | const result = await sock.onWhatsApp(whatsappID);
43 |
44 | if (!result[0]?.exists) {
45 | return await sock.sendMessage(chatId, {
46 | text: `That number is not registered on WhatsApp❗️`,
47 | contextInfo: {
48 | forwardingScore: 1,
49 | isForwarded: true,
50 | forwardedNewsletterMessageInfo: {
51 | newsletterJid: '120363399707841760@newsletter',
52 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
53 | serverMessageId: -1
54 | }
55 | }
56 | });
57 | }
58 |
59 | await sock.sendMessage(chatId, {
60 | text: "Wait a moment for the code",
61 | contextInfo: {
62 | forwardingScore: 1,
63 | isForwarded: true,
64 | forwardedNewsletterMessageInfo: {
65 | newsletterJid: '120363399707841760@newsletter',
66 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
67 | serverMessageId: -1
68 | }
69 | }
70 | });
71 |
72 | try {
73 | const response = await axios.get(`https://knight-bot-paircode.onrender.com/code?number=${number}`);
74 |
75 | if (response.data && response.data.code) {
76 | const code = response.data.code;
77 | if (code === "Service Unavailable") {
78 | throw new Error('Service Unavailable');
79 | }
80 |
81 | await sleep(5000);
82 | await sock.sendMessage(chatId, {
83 | text: `Your pairing code: ${code}`,
84 | contextInfo: {
85 | forwardingScore: 1,
86 | isForwarded: true,
87 | forwardedNewsletterMessageInfo: {
88 | newsletterJid: '120363399707841760@newsletter',
89 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
90 | serverMessageId: -1
91 | }
92 | }
93 | });
94 | } else {
95 | throw new Error('Invalid response from server');
96 | }
97 | } catch (apiError) {
98 | console.error('API Error:', apiError);
99 | const errorMessage = apiError.message === 'Service Unavailable'
100 | ? "Service is currently unavailable. Please try again later."
101 | : "Failed to generate pairing code. Please try again later.";
102 |
103 | await sock.sendMessage(chatId, {
104 | text: errorMessage,
105 | contextInfo: {
106 | forwardingScore: 1,
107 | isForwarded: true,
108 | forwardedNewsletterMessageInfo: {
109 | newsletterJid: '120363399707841760@newsletter',
110 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
111 | serverMessageId: -1
112 | }
113 | }
114 | });
115 | }
116 | }
117 | } catch (error) {
118 | console.error(error);
119 | await sock.sendMessage(chatId, {
120 | text: "An error occurred. Please try again later.",
121 | contextInfo: {
122 | forwardingScore: 1,
123 | isForwarded: true,
124 | forwardedNewsletterMessageInfo: {
125 | newsletterJid: '120363399707841760@newsletter',
126 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
127 | serverMessageId: -1
128 | }
129 | }
130 | });
131 | }
132 | }
133 |
134 | module.exports = pairCommand;
--------------------------------------------------------------------------------
/commands/textmaker.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const mumaker = require('mumaker');
3 |
4 | // Base channel info template
5 | const channelInfo = {
6 | forwardingScore: 1,
7 | isForwarded: true,
8 | forwardedNewsletterMessageInfo: {
9 | newsletterJid: '120363399707841760@newsletter',
10 | newsletterName: 'ʟᴀᴅʏ ʙᴇʟʟᴀ ᴠ3',
11 | serverMessageId: -1
12 | }
13 | };
14 |
15 | // Reusable message templates
16 | const messageTemplates = {
17 | error: (message) => ({
18 | text: message,
19 | contextInfo: channelInfo
20 | }),
21 | success: (text, imageUrl) => ({
22 | image: { url: imageUrl },
23 | caption: "POWERED BY SNOWBIRD",
24 | contextInfo: channelInfo
25 | })
26 | };
27 |
28 | async function textmakerCommand(sock, chatId, message, q, type) {
29 | try {
30 | if (!q) {
31 | return await sock.sendMessage(chatId, messageTemplates.error("Please provide text to generate\nExample: .metallic Nick"));
32 | }
33 |
34 | // Extract text
35 | const text = q.split(' ').slice(1).join(' ');
36 |
37 | if (!text) {
38 | return await sock.sendMessage(chatId, messageTemplates.error("Please provide text to generate\nExample: .metallic Nick"));
39 | }
40 |
41 | try {
42 | let result;
43 | switch (type) {
44 | case 'metallic':
45 | result = await mumaker.ephoto("https://en.ephoto360.com/impressive-decorative-3d-metal-text-effect-798.html", text);
46 | break;
47 | case 'ice':
48 | result = await mumaker.ephoto("https://en.ephoto360.com/ice-text-effect-online-101.html", text);
49 | break;
50 | case 'snow':
51 | result = await mumaker.ephoto("https://en.ephoto360.com/create-a-snow-3d-text-effect-free-online-621.html", text);
52 | break;
53 | case 'impressive':
54 | result = await mumaker.ephoto("https://en.ephoto360.com/create-3d-colorful-paint-text-effect-online-801.html", text);
55 | break;
56 | case 'matrix':
57 | result = await mumaker.ephoto("https://en.ephoto360.com/matrix-text-effect-154.html", text);
58 | break;
59 | case 'light':
60 | result = await mumaker.ephoto("https://en.ephoto360.com/light-text-effect-futuristic-technology-style-648.html", text);
61 | break;
62 | case 'neon':
63 | result = await mumaker.ephoto("https://en.ephoto360.com/create-colorful-neon-light-text-effects-online-797.html", text);
64 | break;
65 | case 'devil':
66 | result = await mumaker.ephoto("https://en.ephoto360.com/neon-devil-wings-text-effect-online-683.html", text);
67 | break;
68 | case 'purple':
69 | result = await mumaker.ephoto("https://en.ephoto360.com/purple-text-effect-online-100.html", text);
70 | break;
71 | case 'thunder':
72 | result = await mumaker.ephoto("https://en.ephoto360.com/thunder-text-effect-online-97.html", text);
73 | break;
74 | case 'leaves':
75 | result = await mumaker.ephoto("https://en.ephoto360.com/green-brush-text-effect-typography-maker-online-153.html", text);
76 | break;
77 | case '1917':
78 | result = await mumaker.ephoto("https://en.ephoto360.com/1917-style-text-effect-523.html", text);
79 | break;
80 | case 'arena':
81 | result = await mumaker.ephoto("https://en.ephoto360.com/create-cover-arena-of-valor-by-mastering-360.html", text);
82 | break;
83 | case 'hacker':
84 | result = await mumaker.ephoto("https://en.ephoto360.com/create-anonymous-hacker-avatars-cyan-neon-677.html", text);
85 | break;
86 | case 'sand':
87 | result = await mumaker.ephoto("https://en.ephoto360.com/write-names-and-messages-on-the-sand-online-582.html", text);
88 | break;
89 | case 'blackpink':
90 | result = await mumaker.ephoto("https://en.ephoto360.com/create-a-blackpink-style-logo-with-members-signatures-810.html", text);
91 | break;
92 | case 'glitch':
93 | result = await mumaker.ephoto("https://en.ephoto360.com/create-digital-glitch-text-effects-online-767.html", text);
94 | break;
95 | case 'fire':
96 | result = await mumaker.ephoto("https://en.ephoto360.com/flame-lettering-effect-372.html", text);
97 | break;
98 | default:
99 | return await sock.sendMessage(chatId, messageTemplates.error("Invalid text generator type"));
100 | }
101 |
102 | if (!result || !result.image) {
103 | throw new Error('No image URL received from the API');
104 | }
105 |
106 | await sock.sendMessage(chatId, messageTemplates.success(text, result.image));
107 | } catch (error) {
108 | console.error('Error in text generator:', error);
109 | await sock.sendMessage(chatId, messageTemplates.error(`Error: ${error.message}`));
110 | }
111 | } catch (error) {
112 | console.error('Error in textmaker command:', error);
113 | await sock.sendMessage(chatId, messageTemplates.error("An error occurred. Please try again later."));
114 | }
115 | }
116 |
117 | module.exports = textmakerCommand;
--------------------------------------------------------------------------------
/lib/myfunc2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Knight Bot - A WhatsApp Bot
3 | * Copyright (c) 2024 Professor
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the MIT License.
7 | *
8 | * Credits:
9 | * - Baileys Library by @adiwajshing
10 | * - Pair Code implementation inspired by TechGod143 & DGXEON
11 | */
12 | var __importDefault = (this && this.__importDefault) || function (mod) {
13 | return (mod && mod.__esModule) ? mod : { "default": mod }
14 | }
15 | Object.defineProperty(exports, "__esModule", { value: true })
16 |
17 | const axios = require("axios")
18 | const cheerio = require("cheerio")
19 | const { resolve } = require("path")
20 | const util = require("util")
21 | let BodyForm = require('form-data')
22 | let { fromBuffer } = require('file-type')
23 | //let fetch = require('node-fetch')
24 | let fs = require('fs')
25 | const child_process = require('child_process')
26 | const ffmpeg = require('fluent-ffmpeg')
27 |
28 | const {unlink } = require ('fs').promises
29 |
30 |
31 | exports.sleep = async (ms) => {
32 | return new Promise(resolve => setTimeout(resolve, ms));
33 | }
34 | exports.fetchJson = async (url, options) => {
35 | try {
36 | options ? options : {}
37 | const res = await axios({
38 | method: 'GET',
39 | url: url,
40 | headers: {
41 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
42 | },
43 | ...options
44 | })
45 | return res.data
46 | } catch (err) {
47 | return err
48 | }
49 | }
50 | exports.fetchBuffer = async (url, options) => {
51 | try {
52 | options ? options : {}
53 | const res = await axios({
54 | method: "GET",
55 | url,
56 | headers: {
57 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36",
58 | 'DNT': 1,
59 | 'Upgrade-Insecure-Request': 1
60 | },
61 | ...options,
62 | responseType: 'arraybuffer'
63 | })
64 | return res.data
65 | } catch (err) {
66 | return err
67 | }
68 | }
69 | exports.webp2mp4File=async(path) =>{
70 | return new Promise((resolve, reject) => {
71 | const form = new BodyForm()
72 | form.append('new-image-url', '')
73 | form.append('new-image', fs.createReadStream(path))
74 | axios({
75 | method: 'post',
76 | url: 'https://s6.ezgif.com/webp-to-mp4',
77 | data: form,
78 | headers: {
79 | 'Content-Type': `multipart/form-data; boundary=${form._boundary}`
80 | }
81 | }).then(({ data }) => {
82 | const bodyFormThen = new BodyForm()
83 | const $ = cheerio.load(data)
84 | const file = $('input[name="file"]').attr('value')
85 | bodyFormThen.append('file', file)
86 | bodyFormThen.append('convert', "Convert WebP to MP4!")
87 | axios({
88 | method: 'post',
89 | url: 'https://ezgif.com/webp-to-mp4/' + file,
90 | data: bodyFormThen,
91 | headers: {
92 | 'Content-Type': `multipart/form-data; boundary=${bodyFormThen._boundary}`
93 | }
94 | }).then(({ data }) => {
95 | const $ = cheerio.load(data)
96 | const result = 'https:' + $('div#output > p.outfile > video > source').attr('src')
97 | resolve({
98 | status: true,
99 | message: "Created By Eternity",
100 | result: result
101 | })
102 | }).catch(reject)
103 | }).catch(reject)
104 | })
105 | }
106 |
107 | exports.fetchUrl = async (url, options) => {
108 | try {
109 | options ? options : {}
110 | const res = await axios({
111 | method: 'GET',
112 | url: url,
113 | headers: {
114 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
115 | },
116 | ...options
117 | })
118 | return res.data
119 | } catch (err) {
120 | return err
121 | }
122 | }
123 |
124 | exports.WAVersion = async () => {
125 | let get = await exports.fetchUrl("https://web.whatsapp.com/check-update?version=1&platform=web")
126 | let version = [get.currentVersion.replace(/[.]/g, ", ")]
127 | return version
128 | }
129 |
130 | exports.getRandom = (ext) => {
131 | return `${Math.floor(Math.random() * 10000)}${ext}`
132 | }
133 |
134 | exports.isUrl = (url) => {
135 | return url.match(new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/, 'gi'))
136 | }
137 |
138 | exports.isNumber = (number) => {
139 | const int = parseInt(number)
140 | return typeof int === 'number' && !isNaN(int)
141 | }
142 | exports.TelegraPh= (Path) =>{
143 | return new Promise (async (resolve, reject) => {
144 | if (!fs.existsSync(Path)) return reject(new Error("File not Found"))
145 | try {
146 | const form = new BodyForm();
147 | form.append("file", fs.createReadStream(Path))
148 | const data = await axios({
149 | url: "https://telegra.ph/upload",
150 | method: "POST",
151 | headers: {
152 | ...form.getHeaders()
153 | },
154 | data: form
155 | })
156 | return resolve("https://telegra.ph" + data.data[0].src)
157 | } catch (err) {
158 | return reject(new Error(String(err)))
159 | }
160 | })
161 | }
162 | const sleepy = async (ms) => {
163 | return new Promise(resolve => setTimeout(resolve, ms));
164 | }
165 | exports.buffergif = async (image) => {
166 |
167 | const filename = `${Math.random().toString(36)}`
168 | await fs.writeFileSync(`./XeonMedia/trash/${filename}.gif`, image)
169 | child_process.exec(
170 | `ffmpeg -i ./XeonMedia/trash/${filename}.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" ./XeonMedia/trash/${filename}.mp4`
171 | )
172 | await sleepy(4000)
173 |
174 | var buffer5 = await fs.readFileSync(`./XeonMedia/trash/${filename}.mp4`)
175 | Promise.all([unlink(`./XeonMedia/video/${filename}.mp4`), unlink(`./XeonMedia/gif/${filename}.gif`)])
176 | return buffer5
177 | }
--------------------------------------------------------------------------------