├── 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 | Typing Animation 7 |

8 | 9 | 10 |

11 | 12 | 13 | 14 |

15 | 16 | [![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Rockstar-ExtraBold&color=blue&lines=PLEASE+FORK+THE+REPO+FOR+MORE+UPDATES)](https://git.io/typing-svg) 17 | > 18 | 19 | --- 20 |

1. ᴍʏ ᴀᴄᴄᴏᴜɴᴛ

21 |

22 | Github 23 |

24 | 25 | 26 | 27 | 28 | --- 29 | 30 | ## 🚀 ᴅᴇᴘʟᴏʏᴍᴇɴᴛ ᴏᴘᴛɪᴏɴs 31 | 32 | ### ⭐ ғᴏʀᴋ & sᴛᴀʀ ʀᴇᴘᴏsɪᴛᴏʀʏ 33 | ғᴏʀᴋ & sᴛᴀʀ ⭐ ᴛᴏ sᴜᴘᴘᴏʀᴛ sɴᴏᴡʙɪʀᴅ! 34 | 35 | [![Fork Repo](https://img.shields.io/badge/Github-Fork%20Repo-red?style=for-the-badge&logo=Github)](https://github.com/SNOWBIRD0074/Lady-Bella2/fork) 36 | 37 | --- 38 | 39 | ### 💙ᴘᴀɪʀ ʏᴏᴜʀ #💚ɢᴇᴛ ᴄʀᴇᴅs ғɪʟᴇ💜 40 | 41 | [![Pair Code](https://img.shields.io/badge/Google-Pair%20Code-blue?style=for-the-badge&logo=Google)](https://kkkdjjdjjdjdjdjj.onrender.com/) 42 | 43 | --- 44 | 45 | ### ✔️ ᴅᴏᴡɴʟᴏᴀᴅ ʟᴀᴅʏʙᴇʟʟᴀ3 ᴢɪᴘ 46 | 47 | [![Deploy on Bot hosting net](https://img.shields.io/badge/-Download-blue?style=for-the-badge&logo=heroku&logoColor=white)](https://github.com/SNOWBIRD0074/Lady-Bella2/archive/refs/heads/main.zip) 48 | 49 | --- 50 | 51 | ### 🤍 ᴅᴇᴘʟᴏʏᴍᴇɴᴛ 52 | 53 | #### ✔️ ʙᴏᴛ ʜᴏsᴛɪɴɢ ɴᴇᴛ 54 | --- 55 | [![Deploy on Bot hosting net](https://img.shields.io/badge/-DEPLOY-blue?style=for-the-badge&logo=heroku&logoColor=white)](https://bot-hosting.net/panel) 56 | 57 | 58 | --- 59 | 60 | #### ✔️ Katabump Hosting 61 | --- 62 | [![Deploy on Katabump](https://img.shields.io/badge/-DEPLOY-blue?style=for-the-badge&logo=heroku&logoColor=white)](https://dashboard.katabump.com/dashboard) 63 | 64 | 65 | --- 66 | 67 | #### ✔️ Vɪᴅᴇᴏ ᴏɴ ʜᴏᴡ ᴛᴏ ᴅᴇᴘʟᴏʏ 68 | --- 69 | [![Deploy on Heroku](https://img.shields.io/badge/-Watch-blue?style=for-the-badge&logo=heroku&logoColor=white)](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 | Footer Animation 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 | } --------------------------------------------------------------------------------