├── auth └── ArslanMD ├── data ├── banned.json ├── Arslan-Ai ├── warnings.json ├── autoStatus.json ├── autoread.json ├── owner.json ├── premium.json ├── antidelete.json ├── autotyping.json ├── messageCount.json └── userGroupData.json ├── lib ├── Arslan-Ai ├── isBanned.js ├── isOwner.js ├── antilinkHelper.js ├── tictactoe.js ├── converter.js ├── isAdmin.js ├── antilink.js ├── uploadImage.js ├── uploader.js ├── reactions.js ├── lightweight_store.js └── welcome.js ├── temp └── ArslanMD ├── session └── ArslanMD ├── ArslanMedia ├── media │ ├── new.mp4 │ ├── menu.gif(1) │ ├── gang.mp4 │ ├── menu.gif │ └── menu.mp4 ├── audio │ ├── marco.mp3 │ ├── welcome.mp3 │ └── welcome.mp3(1) └── stickers │ └── loading.webp ├── Procfile ├── .dockerignore ├── assets ├── audio.mp3 ├── funny.mp4 ├── vnote.mp4 ├── bot_banner.jpg ├── bot_image.jpg ├── sticktag.webp └── stickintro.webp ├── baileys_store.json ├── autos └── autoreply.json ├── .upm └── store.json ├── commands ├── unmute.js ├── owner.js ├── fact.js ├── joke.js ├── clear.js ├── goodbye.js ├── welcome.js ├── eightball.js ├── weather.js ├── quote.js ├── funny.js ├── dare.js ├── truth.js ├── flirt.js ├── news.js ├── roseday.js ├── goodnight.js ├── antibadword.js ├── warnings.js ├── tts.js ├── delete.js ├── shayari.js ├── ship.js ├── gif.js ├── meme.js ├── alive.js ├── github.js ├── mute.js ├── resetlink.js ├── lyrics.js ├── tagall.js ├── staff.js ├── tagnotadmin.js ├── anticall.js ├── trivia.js ├── simage-alt.js ├── groupinfo.js ├── attp.js ├── ban.js ├── stupid.js ├── topmembers.js ├── sora.js ├── unban.js ├── pies.js ├── wasted.js ├── hangman.js ├── simage.js ├── ss.js ├── play.js ├── spotify.js ├── simp.js ├── kick.js ├── ping.js ├── sticker-alt.js ├── setpp.js ├── hidetag.js ├── pmblocker.js ├── img-blur.js ├── sudo.js ├── imagine.js ├── take.js ├── clearsession.js ├── character.js ├── instagram.js ├── cleartmp.js ├── tag.js ├── promote.js ├── compliment.js ├── groupmanage.js ├── facebook.js ├── emojimix.js ├── song.js ├── ai.js ├── insult.js ├── settings.js ├── url.js ├── translate.js └── removebg.js ├── .gitignore ├── .koyeb.yaml ├── Dockerfile ├── app.json ├── server.js ├── config.js ├── public └── index.html ├── package.json └── settings.js /auth/ArslanMD: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data/banned.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /lib/Arslan-Ai: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /temp/ArslanMD: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data/Arslan-Ai: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data/warnings.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /session/ArslanMD: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ArslanMedia/media/new.mp4: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node index.js 2 | -------------------------------------------------------------------------------- /ArslanMedia/media/menu.gif(1): -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data/autoStatus.json: -------------------------------------------------------------------------------- 1 | {"enabled":false} -------------------------------------------------------------------------------- /data/autoread.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": false 3 | } -------------------------------------------------------------------------------- /data/owner.json: -------------------------------------------------------------------------------- 1 | ["920000000000","923237045919"] -------------------------------------------------------------------------------- /data/premium.json: -------------------------------------------------------------------------------- 1 | ["920000000000","923237045919"] -------------------------------------------------------------------------------- /data/antidelete.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": false 3 | } -------------------------------------------------------------------------------- /data/autotyping.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": false 3 | } -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | session 3 | creds.json 4 | .env 5 | -------------------------------------------------------------------------------- /data/messageCount.json: -------------------------------------------------------------------------------- 1 | { 2 | "isPublic": true, 3 | "messageCount": {} 4 | } -------------------------------------------------------------------------------- /assets/audio.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/assets/audio.mp3 -------------------------------------------------------------------------------- /assets/funny.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/assets/funny.mp4 -------------------------------------------------------------------------------- /assets/vnote.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/assets/vnote.mp4 -------------------------------------------------------------------------------- /baileys_store.json: -------------------------------------------------------------------------------- 1 | {"chats":[],"contacts":{},"messages":{},"labels":[],"labelAssociations":[]} -------------------------------------------------------------------------------- /assets/bot_banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/assets/bot_banner.jpg -------------------------------------------------------------------------------- /assets/bot_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/assets/bot_image.jpg -------------------------------------------------------------------------------- /assets/sticktag.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/assets/sticktag.webp -------------------------------------------------------------------------------- /assets/stickintro.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/assets/stickintro.webp -------------------------------------------------------------------------------- /ArslanMedia/media/gang.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/ArslanMedia/media/gang.mp4 -------------------------------------------------------------------------------- /ArslanMedia/media/menu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/ArslanMedia/media/menu.gif -------------------------------------------------------------------------------- /ArslanMedia/media/menu.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/ArslanMedia/media/menu.mp4 -------------------------------------------------------------------------------- /ArslanMedia/audio/marco.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/ArslanMedia/audio/marco.mp3 -------------------------------------------------------------------------------- /ArslanMedia/audio/welcome.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/ArslanMedia/audio/welcome.mp3 -------------------------------------------------------------------------------- /ArslanMedia/audio/welcome.mp3(1): -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/ArslanMedia/audio/welcome.mp3(1) -------------------------------------------------------------------------------- /ArslanMedia/stickers/loading.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arslan-MD/Arslan-Ai/HEAD/ArslanMedia/stickers/loading.webp -------------------------------------------------------------------------------- /autos/autoreply.json: -------------------------------------------------------------------------------- 1 | { 2 | "hi": "👋 Hello! Welcome to Arslan-MD Bot.", 3 | "hello": "✨ Hello there! Need help?", 4 | "bye": "👋 Goodbye! Have a great day.", 5 | "thanks": "❤️ You're welcome!" 6 | } 7 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /.upm/store.json: -------------------------------------------------------------------------------- 1 | {"version":2,"languages":{"nodejs-npm":{"specfileHash":"1a7bcd182ba015d3a367c2edb9a0a2cc","lockfileHash":"3cb1b27979891b1b6f92722f59408902","guessedImports":["qrcode-terminal","@whiskeysockets/baileys"],"guessedImportsHash":"d5690403c3de8f56bde9d02d049e9cfa"}}} 2 | -------------------------------------------------------------------------------- /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/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 }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json 3 | 4 | # Runtime data 5 | tmp/ 6 | temp/ 7 | 8 | # Session files 9 | session/ 10 | 11 | 12 | # Environment variables 13 | .env 14 | 15 | # Log files 16 | *.log 17 | npm-debug.log* 18 | yarn-debug.log* 19 | yarn-error.log* 20 | 21 | # Editor directories and files 22 | .idea/ 23 | .vscode/ 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | -------------------------------------------------------------------------------- /.koyeb.yaml: -------------------------------------------------------------------------------- 1 | name: arslan-md 2 | routes: 3 | - src: / 4 | dest: / 5 | - src: /health 6 | dest: /health 7 | 8 | services: 9 | - name: arslan-md-bot 10 | git: 11 | repo: https://github.com/Arslan-MD/Arslan-MD 12 | branch: main 13 | buildCommand: npm install 14 | runCommand: node server.js 15 | env: 16 | - key: PORT 17 | value: "8000" 18 | regions: 19 | - fra 20 | instanceType: micro 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # ✅ Base image - official Node.js 2 | FROM node:18 3 | 4 | # ✅ Set working directory 5 | WORKDIR /usr/src/app 6 | 7 | # ✅ Copy only package.json to install dependencies 8 | COPY package.json ./ 9 | 10 | # ✅ Install dependencies without lockfile 11 | RUN npm install 12 | 13 | # ✅ Copy all remaining bot files 14 | COPY . . 15 | 16 | # ✅ Expose port (optional, if using express or API) 17 | EXPOSE 3000 18 | 19 | # ✅ Start the bot with server.js 20 | CMD ["node", "server.js"] 21 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Arslan-Ai", 3 | "description": "WhatsApp bot using Baileys and creds.json session.", 4 | "repository": "https://github.com/Arslan-MD/Arslan-Ai", 5 | "keywords": ["whatsapp", "bot", "baileys", "arslan-ai"], 6 | "buildpacks": [ 7 | { 8 | "url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git" 9 | }, 10 | { 11 | "url": "heroku/nodejs" 12 | } 13 | ], 14 | "scripts": { 15 | "postdeploy": "echo '✅ Arslan-Ai deployed on Heroku!'" 16 | } 17 | } 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 | -------------------------------------------------------------------------------- /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/weather.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | 3 | module.exports = async function (sock, chatId, 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 }); 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.' }); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const path = require('path'); 3 | const { spawn } = require('child_process'); 4 | 5 | const app = express(); 6 | const PORT = process.env.PORT || 3000; 7 | 8 | // ✅ Start WhatsApp bot (index.js) 9 | const botProcess = spawn('node', ['index.js'], { 10 | stdio: 'inherit', 11 | }); 12 | 13 | // ✅ Serve static files from "public" folder 14 | app.use(express.static(path.join(__dirname, 'public'))); 15 | 16 | // ✅ Homepage route 17 | app.get('/', (req, res) => { 18 | res.sendFile(path.join(__dirname, 'public/index.html')); 19 | }); 20 | 21 | // ✅ Health check route (MUST for Koyeb) 22 | app.get('/health', (req, res) => res.status(200).send('OK')); 23 | 24 | // ✅ Start web server 25 | app.listen(PORT, () => { 26 | console.log(`✅ Web server running on http://localhost:${PORT}`); 27 | }); 28 | -------------------------------------------------------------------------------- /commands/quote.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | 3 | module.exports = async function quoteCommand(sock, chatId, message) { 4 | try { 5 | const shizokeys = 'Arslan-Ai'; 6 | const res = await fetch(`https://api.shizo.top/api/quote/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/funny.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | module.exports = async function (sock, chatId, message) { 5 | try { 6 | const videoPath = path.join(__dirname, '../assets/funny.mp4'); 7 | 8 | if (!fs.existsSync(videoPath)) { 9 | return await sock.sendMessage(chatId, { text: '❌ Funny video not found!' }); 10 | } 11 | 12 | await sock.sendMessage(chatId, { 13 | video: fs.readFileSync(videoPath), 14 | caption: '🤣 Here\'s something funny for you!', 15 | mimetype: 'video/mp4', 16 | gifPlayback: false 17 | }, { quoted: message }); 18 | 19 | } catch (err) { 20 | console.error('Funny command error:', err); 21 | await sock.sendMessage(chatId, { text: '❌ Failed to send funny video.' }); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /commands/dare.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | 3 | async function dareCommand(sock, chatId, message) { 4 | try { 5 | const shizokeys = 'knightbot'; 6 | const res = await fetch(`https://api.shizo.top/api/quote/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/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 = 'Arslan-Ai'; 6 | const res = await fetch(`https://api.shizo.top/api/quote/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 }; 24 | -------------------------------------------------------------------------------- /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/roseday.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | 3 | async function rosedayCommand(sock, chatId, message) { 4 | try { 5 | const shizokeys = 'Arslan-Ai'; 6 | const res = await fetch(`https://api.shizo.top/quote/roseday?apikey=${shizokeys}`); 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/goodnight.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | 3 | async function goodnightCommand(sock, chatId, message) { 4 | try { 5 | const shizokeys = 'Arslan-Ai'; 6 | const res = await fetch(`https://api.shizo.top/api/quote/gnsd?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 }; 24 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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!```' }); 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*' }); 20 | } 21 | } 22 | 23 | module.exports = antibadwordCommand; -------------------------------------------------------------------------------- /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/delete.js: -------------------------------------------------------------------------------- 1 | const isAdmin = require('../lib/isAdmin'); 2 | 3 | async function deleteCommand(sock, chatId, message, senderId) { 4 | const { isSenderAdmin, isBotAdmin } = await isAdmin(sock, chatId, senderId); 5 | 6 | if (!isBotAdmin) { 7 | await sock.sendMessage(chatId, { text: 'I need to be an admin to delete messages.' }); 8 | return; 9 | } 10 | 11 | if (!isSenderAdmin) { 12 | await sock.sendMessage(chatId, { text: 'Only admins can use the .delete command.' }); 13 | return; 14 | } 15 | 16 | const quotedMessage = message.message?.extendedTextMessage?.contextInfo?.stanzaId; 17 | const quotedParticipant = message.message?.extendedTextMessage?.contextInfo?.participant; 18 | 19 | if (quotedMessage) { 20 | await sock.sendMessage(chatId, { delete: { remoteJid: chatId, fromMe: false, id: quotedMessage, participant: quotedParticipant } }); 21 | } else { 22 | await sock.sendMessage(chatId, { text: 'Please reply to a message you want to delete.' }); 23 | } 24 | } 25 | 26 | module.exports = deleteCommand; 27 | -------------------------------------------------------------------------------- /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://api.shizo.top/api/quote/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 }; 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | }); 31 | } 32 | } 33 | 34 | module.exports = memeCommand; 35 | -------------------------------------------------------------------------------- /commands/alive.js: -------------------------------------------------------------------------------- 1 | const settings = require("../settings"); 2 | async function aliveCommand(sock, chatId, message) { 3 | try { 4 | const message1 = `*🤖 Arslan-Ai is Active!*\n\n` + 5 | `*Version:* ${settings.version}\n` + 6 | `*Status:* Online\n` + 7 | `*Mode:* Public\n\n` + 8 | `*🌟 Features:*\n` + 9 | `• Group Management\n` + 10 | `• Antilink Protection\n` + 11 | `• Fun Commands\n` + 12 | `• And more!\n\n` + 13 | `Type *.menu* for full command list`; 14 | 15 | await sock.sendMessage(chatId, { 16 | text: message1, 17 | contextInfo: { 18 | forwardingScore: 999, 19 | isForwarded: true, 20 | forwardedNewsletterMessageInfo: { 21 | newsletterJid: '120363348739987203@newsletter', 22 | newsletterName: 'Arslan-Ai', 23 | serverMessageId: -1 24 | } 25 | } 26 | }, { quoted: message }); 27 | } catch (error) { 28 | console.error('Error in alive command:', error); 29 | await sock.sendMessage(chatId, { text: 'Bot is alive and running!' }, { quoted: message }); 30 | } 31 | } 32 | 33 | module.exports = aliveCommand; 34 | -------------------------------------------------------------------------------- /commands/github.js: -------------------------------------------------------------------------------- 1 | const moment = require('moment-timezone'); 2 | const fetch = require('node-fetch'); 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | 6 | 7 | async function githubCommand(sock, chatId, message) { 8 | try { 9 | const res = await fetch('https://api.github.com/repos/Arslan-MD/Arslan-Ai'); 10 | if (!res.ok) throw new Error('Error fetching repository data'); 11 | const json = await res.json(); 12 | 13 | let txt = `*乂 Arslan-Ai 乂*\n\n`; 14 | txt += `✩ *Name* : ${json.name}\n`; 15 | txt += `✩ *Watchers* : ${json.watchers_count}\n`; 16 | txt += `✩ *Size* : ${(json.size / 1024).toFixed(2)} MB\n`; 17 | txt += `✩ *Last Updated* : ${moment(json.updated_at).format('DD/MM/YY - HH:mm:ss')}\n`; 18 | txt += `✩ *URL* : ${json.html_url}\n`; 19 | txt += `✩ *Forks* : ${json.forks_count}\n`; 20 | txt += `✩ *Stars* : ${json.stargazers_count}\n\n`; 21 | txt += `💥 *Arslan-Ai*`; 22 | 23 | // Use the local asset image 24 | const imgPath = path.join(__dirname, '../assets/bot_image.jpg'); 25 | const imgBuffer = fs.readFileSync(imgPath); 26 | 27 | await sock.sendMessage(chatId, { image: imgBuffer, caption: txt }, { quoted: message }); 28 | } catch (error) { 29 | await sock.sendMessage(chatId, { text: '❌ Error fetching repository information.' }, { quoted: message }); 30 | } 31 | } 32 | 33 | module.exports = githubCommand; 34 | -------------------------------------------------------------------------------- /commands/mute.js: -------------------------------------------------------------------------------- 1 | const isAdmin = require('../lib/isAdmin'); 2 | 3 | async function muteCommand(sock, chatId, senderId, durationInMinutes) { 4 | console.log(`Attempting to mute the group for ${durationInMinutes} minutes.`); // Log for debugging 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.' }); 9 | return; 10 | } 11 | 12 | if (!isSenderAdmin) { 13 | await sock.sendMessage(chatId, { text: 'Only group admins can use the mute command.' }); 14 | return; 15 | } 16 | 17 | const durationInMilliseconds = durationInMinutes * 60 * 1000; 18 | try { 19 | await sock.groupSettingUpdate(chatId, 'announcement'); // Mute the group 20 | await sock.sendMessage(chatId, { text: `The group has been muted for ${durationInMinutes} minutes.` }); 21 | 22 | setTimeout(async () => { 23 | await sock.groupSettingUpdate(chatId, 'not_announcement'); // Unmute after the duration 24 | await sock.sendMessage(chatId, { text: 'The group has been unmuted.' }); 25 | }, durationInMilliseconds); 26 | } catch (error) { 27 | console.error('Error muting/unmuting the group:', error); 28 | await sock.sendMessage(chatId, { text: 'An error occurred while muting/unmuting the group. Please try again.' }); 29 | } 30 | } 31 | 32 | module.exports = muteCommand; 33 | -------------------------------------------------------------------------------- /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/lyrics.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | 3 | async function lyricsCommand(sock, chatId, songTitle) { 4 | if (!songTitle) { 5 | await sock.sendMessage(chatId, { 6 | text: '🔍 Please enter the song name to get the lyrics! Usage: *lyrics *' 7 | }); 8 | return; 9 | } 10 | 11 | try { 12 | // Fetch song lyrics using the some-random-api.com API 13 | const apiUrl = `https://some-random-api.com/lyrics?title=${encodeURIComponent(songTitle)}`; 14 | const res = await fetch(apiUrl); 15 | 16 | if (!res.ok) { 17 | throw await res.text(); 18 | } 19 | 20 | const json = await res.json(); 21 | 22 | if (!json.lyrics) { 23 | await sock.sendMessage(chatId, { 24 | text: `❌ Sorry, I couldn't find any lyrics for "${songTitle}".` 25 | }); 26 | return; 27 | } 28 | 29 | // Sending the formatted result to the user 30 | await sock.sendMessage(chatId, { 31 | text: `🎵 *Song Lyrics* 🎶\n\n▢ *Title:* ${json.title || songTitle}\n▢ *Artist:* ${json.author || 'Unknown'}\n\n📜 *Lyrics:*\n${json.lyrics}\n\nHope you enjoy the music! 🎧 🎶` 32 | }); 33 | } catch (error) { 34 | console.error('Error in lyrics command:', error); 35 | await sock.sendMessage(chatId, { 36 | text: `❌ An error occurred while fetching the lyrics for "${songTitle}".` 37 | }); 38 | } 39 | } 40 | 41 | module.exports = { lyricsCommand }; 42 | -------------------------------------------------------------------------------- /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/tagnotadmin.js: -------------------------------------------------------------------------------- 1 | const isAdmin = require('../lib/isAdmin'); 2 | 3 | async function tagNotAdminCommand(sock, chatId, senderId, message) { 4 | try { 5 | const { isSenderAdmin, isBotAdmin } = await isAdmin(sock, chatId, senderId); 6 | 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 admins can use the .tagnotadmin command.' }, { quoted: message }); 14 | return; 15 | } 16 | 17 | const groupMetadata = await sock.groupMetadata(chatId); 18 | const participants = groupMetadata.participants || []; 19 | 20 | const nonAdmins = participants.filter(p => !p.admin).map(p => p.id); 21 | if (nonAdmins.length === 0) { 22 | await sock.sendMessage(chatId, { text: 'No non-admin members to tag.' }, { quoted: message }); 23 | return; 24 | } 25 | 26 | let text = '🔊 *Hello Everyone:*\n\n'; 27 | nonAdmins.forEach(jid => { 28 | text += `@${jid.split('@')[0]}\n`; 29 | }); 30 | 31 | await sock.sendMessage(chatId, { text, mentions: nonAdmins }, { quoted: message }); 32 | } catch (error) { 33 | console.error('Error in tagnotadmin command:', error); 34 | await sock.sendMessage(chatId, { text: 'Failed to tag non-admin members.' }, { quoted: message }); 35 | } 36 | } 37 | 38 | module.exports = tagNotAdminCommand; 39 | 40 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/attp.js: -------------------------------------------------------------------------------- 1 | const sharp = require('sharp'); 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | const Jimp = require('jimp'); 5 | 6 | async function attpCommand(sock, chatId, message) { 7 | const userMessage = message.message.conversation || message.message.extendedTextMessage?.text || ''; 8 | const text = userMessage.split(' ').slice(1).join(' '); 9 | 10 | if (!text) { 11 | await sock.sendMessage(chatId, { text: 'Please provide text after the .attp command.' }); 12 | return; 13 | } 14 | 15 | const width = 512; 16 | const height = 512; 17 | const stickerPath = path.join(__dirname, './temp', `sticker-${Date.now()}.png`); 18 | 19 | try { 20 | const font = await Jimp.loadFont(Jimp.FONT_SANS_64_BLACK); 21 | const image = new Jimp(width, height, '#FFFFFF'); 22 | 23 | const textWidth = Jimp.measureText(font, text); 24 | const textHeight = Jimp.measureTextHeight(font, text, width); 25 | 26 | const x = (width - textWidth) / 2; 27 | const y = (height - textHeight) / 2; 28 | 29 | image.print(font, x, y, text, width); 30 | await image.writeAsync(stickerPath); 31 | 32 | const stickerBuffer = await sharp(stickerPath) 33 | .resize(512, 512, { fit: 'cover' }) 34 | .webp() 35 | .toBuffer(); 36 | 37 | await sock.sendMessage(chatId, { 38 | sticker: stickerBuffer, 39 | mimetype: 'image/webp', 40 | packname: 'My Sticker Pack', 41 | author: 'My Bot', 42 | }); 43 | 44 | fs.unlinkSync(stickerPath); 45 | } catch (error) { 46 | console.error('Error generating sticker:', error); 47 | await sock.sendMessage(chatId, { text: 'Failed to generate the sticker. Please try again later.' }); 48 | } 49 | } 50 | 51 | module.exports = attpCommand; 52 | -------------------------------------------------------------------------------- /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/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/sora.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | 3 | async function soraCommand(sock, chatId, message) { 4 | try { 5 | const rawText = message.message?.conversation?.trim() || 6 | message.message?.extendedTextMessage?.text?.trim() || 7 | message.message?.imageMessage?.caption?.trim() || 8 | message.message?.videoMessage?.caption?.trim() || 9 | ''; 10 | 11 | // Extract prompt after command keyword or use quoted text 12 | const used = (rawText || '').split(/\s+/)[0] || '.sora'; 13 | const args = rawText.slice(used.length).trim(); 14 | const quoted = message.message?.extendedTextMessage?.contextInfo?.quotedMessage; 15 | const quotedText = quoted?.conversation || quoted?.extendedTextMessage?.text || ''; 16 | const input = args || quotedText; 17 | 18 | if (!input) { 19 | await sock.sendMessage(chatId, { text: 'Provide a prompt. Example: .sora anime girl with short blue hair' }, { quoted: message }); 20 | return; 21 | } 22 | 23 | const apiUrl = `https://okatsu-rolezapiiz.vercel.app/ai/txt2video?text=${encodeURIComponent(input)}`; 24 | const { data } = await axios.get(apiUrl, { timeout: 60000, headers: { 'user-agent': 'Mozilla/5.0' } }); 25 | 26 | const videoUrl = data?.videoUrl || data?.result || data?.data?.videoUrl; 27 | if (!videoUrl) { 28 | throw new Error('No videoUrl in API response'); 29 | } 30 | 31 | await sock.sendMessage(chatId, { 32 | video: { url: videoUrl }, 33 | mimetype: 'video/mp4', 34 | caption: `Prompt: ${input}` 35 | }, { quoted: message }); 36 | 37 | } catch (error) { 38 | console.error('[SORA] error:', error?.message || error); 39 | await sock.sendMessage(chatId, { text: 'Failed to generate video. Try a different prompt later.' }, { quoted: message }); 40 | } 41 | } 42 | 43 | module.exports = soraCommand; 44 | 45 | -------------------------------------------------------------------------------- /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 | }); 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 }); 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/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 | }); 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 | }); 53 | } 54 | } 55 | 56 | module.exports = wastedCommand; -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Arslan-MD MULTIPLE WHATSAPP BOT ALIVE 7 | 57 | 58 | 59 |

Arslan-MD

60 |

The Ultimate WhatsApp Bot ALIVE 🚀

61 | 62 | 68 | 69 |
70 | Made with ❤️ by Arslan-MD 71 |
72 | 73 | 74 | -------------------------------------------------------------------------------- /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*`*/ 64 | -------------------------------------------------------------------------------- /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/spotify.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | 3 | async function spotifyCommand(sock, chatId, message) { 4 | try { 5 | const rawText = message.message?.conversation?.trim() || 6 | message.message?.extendedTextMessage?.text?.trim() || 7 | message.message?.imageMessage?.caption?.trim() || 8 | message.message?.videoMessage?.caption?.trim() || 9 | ''; 10 | 11 | const used = (rawText || '').split(/\s+/)[0] || '.spotify'; 12 | const query = rawText.slice(used.length).trim(); 13 | 14 | if (!query) { 15 | await sock.sendMessage(chatId, { text: 'Usage: .spotify \nExample: .spotify con calma' }, { quoted: message }); 16 | return; 17 | } 18 | 19 | const apiUrl = `https://okatsu-rolezapiiz.vercel.app/search/spotify?q=${encodeURIComponent(query)}`; 20 | const { data } = await axios.get(apiUrl, { timeout: 20000, headers: { 'user-agent': 'Mozilla/5.0' } }); 21 | 22 | if (!data?.status || !data?.result) { 23 | throw new Error('No result from Spotify API'); 24 | } 25 | 26 | const r = data.result; 27 | const audioUrl = r.audio; 28 | if (!audioUrl) { 29 | await sock.sendMessage(chatId, { text: 'No downloadable audio found for this query.' }, { quoted: message }); 30 | return; 31 | } 32 | 33 | const caption = `🎵 ${r.title || r.name || 'Unknown Title'}\n👤 ${r.artist || ''}\n⏱ ${r.duration || ''}\n🔗 ${r.url || ''}`.trim(); 34 | 35 | // Send cover and info as a follow-up (optional) 36 | if (r.thumbnails) { 37 | await sock.sendMessage(chatId, { image: { url: r.thumbnails }, caption }, { quoted: message }); 38 | } else if (caption) { 39 | await sock.sendMessage(chatId, { text: caption }, { quoted: message }); 40 | } 41 | await sock.sendMessage(chatId, { 42 | audio: { url: audioUrl }, 43 | mimetype: 'audio/mpeg', 44 | fileName: `${(r.title || r.name || 'track').replace(/[\\/:*?"<>|]/g, '')}.mp3` 45 | }, { quoted: message }); 46 | 47 | 48 | 49 | } catch (error) { 50 | console.error('[SPOTIFY] error:', error?.message || error); 51 | await sock.sendMessage(chatId, { text: 'Failed to fetch Spotify audio. Try another query later.' }, { quoted: message }); 52 | } 53 | } 54 | 55 | module.exports = spotifyCommand; 56 | -------------------------------------------------------------------------------- /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: '120363348739987203@newsletter', 41 | newsletterName: 'Arslan-Ai', 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: '120363348739987203@newsletter', 56 | newsletterName: 'Arslan-Ai', 57 | serverMessageId: -1 58 | } 59 | } 60 | }); 61 | } 62 | } 63 | 64 | module.exports = { simpCommand }; 65 | -------------------------------------------------------------------------------- /lib/converter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Arslan-Ai 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 | * - Arslan-Ai 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 | } -------------------------------------------------------------------------------- /lib/isAdmin.js: -------------------------------------------------------------------------------- 1 | // isAdmin.js 2 | async function isAdmin(sock, chatId, senderId) { 3 | try { 4 | const metadata = await sock.groupMetadata(chatId); 5 | const participants = metadata.participants || []; 6 | 7 | // Extract bot's pure phone number 8 | const botNumber = sock.user.id.split(':')[0]; // 16305199236 9 | 10 | const senderNumber = senderId.split(':')[0]; 11 | 12 | // Check if bot is admin 13 | const isBotAdmin = participants.some(p => { 14 | // Check multiple possible ID formats 15 | const pPhoneNumber = p.phoneNumber ? p.phoneNumber.split('@')[0] : ''; 16 | const pId = p.id ? p.id.split('@')[0] : ''; 17 | 18 | // Match against bot ID in multiple ways 19 | const botMatches = ( 20 | sock.user.id === p.id || // Direct ID match 21 | botNumber === pPhoneNumber || // Phone number match 22 | botNumber === pId || // ID portion match 23 | sock.user.id.split('@')[0] === pPhoneNumber || // Bot ID phone vs participant phone 24 | sock.user.id.split('@')[0] === pId // Bot ID phone vs participant ID 25 | ); 26 | 27 | return botMatches && (p.admin === 'admin' || p.admin === 'superadmin'); 28 | }); 29 | 30 | // Check if sender is admin 31 | const isSenderAdmin = participants.some(p => { 32 | // Check multiple possible ID formats 33 | const pPhoneNumber = p.phoneNumber ? p.phoneNumber.split('@')[0] : ''; 34 | const pId = p.id ? p.id.split('@')[0] : ''; 35 | 36 | // Match against sender ID in multiple ways 37 | const senderMatches = ( 38 | senderId === p.id || // Direct ID match 39 | senderNumber === pPhoneNumber || // Phone number match 40 | senderNumber === pId || // ID portion match 41 | senderId.split('@')[0] === pPhoneNumber || // Sender ID phone vs participant phone 42 | senderId.split('@')[0] === pId // Sender ID phone vs participant ID 43 | ); 44 | 45 | return senderMatches && (p.admin === 'admin' || p.admin === 'superadmin'); 46 | }); 47 | 48 | return { isSenderAdmin, isBotAdmin }; 49 | } catch (err) { 50 | console.error('❌ Error in isAdmin:', err); 51 | return { isSenderAdmin: false, isBotAdmin: false }; 52 | } 53 | } 54 | 55 | module.exports = isAdmin; 56 | -------------------------------------------------------------------------------- /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/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 %= (24 * 60 * 60); 7 | const hours = Math.floor(seconds / (60 * 60)); 8 | 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 | // Auto reaction ⚡ 24 | await sock.sendMessage(chatId, { react: { text: "⚡", key: message.key } }); 25 | 26 | const start = performance.now(); 27 | const sentMsg = await sock.sendMessage(chatId, { text: "⚙️ *Pinging... Please wait!*" }, { quoted: message }); 28 | const end = performance.now(); 29 | 30 | const ping = Math.round(end - start); 31 | const uptimeFormatted = formatTime(process.uptime()); 32 | const totalRam = (os.totalmem() / (1024 ** 3)).toFixed(2); 33 | const freeRam = (os.freemem() / (1024 ** 3)).toFixed(2); 34 | const usedRam = (totalRam - freeRam).toFixed(2); 35 | const cpu = os.cpus()[0]?.model || "Unknown CPU"; 36 | const platform = `${os.type()} (${os.arch()})`; 37 | 38 | const botInfo = ` 39 | ╭━〔 ⚡ *${settings.botName || "ARSLAN-AI"} STATUS* ⚡ 〕━━╮ 40 | ┃ 🤖 *Bot Name:* ${settings.botName || "Arslan-Ai"} 41 | ┃ 👑 *Owner:* ${settings.ownerName || "ArslanMD Official"} 42 | ┃ 🔖 *Version:* v${settings.version || "2.0"} 43 | ┃ ⚡ *Ping:* ${ping} ms 44 | ┃ ⏱️ *Uptime:* ${uptimeFormatted} 45 | ┃ 💻 *Platform:* ${platform} 46 | ┃ 🧠 *CPU:* ${cpu} 47 | ┃ 🖥️ *RAM:* ${usedRam} / ${totalRam} GB 48 | ┃ 📡 *Mode:* ${settings.mode?.toUpperCase() || "PUBLIC"} 49 | ╰━━━━━━━━━━━━━━━╯ 50 | 51 | * *© 2025 ${settings.botName || "Arslan-Ai"}* 52 | > *Power By ArslanMD Official 🔥* 53 | `.trim(); 54 | 55 | // Stylish message send karein 💫 56 | await sock.sendMessage(chatId, { text: botInfo }, { quoted: sentMsg }); 57 | 58 | } catch (error) { 59 | console.error("❌ Ping Command Error:", error); 60 | await sock.sendMessage(chatId, { text: "❌ Error fetching system status! Please try again later." }, { quoted: message }); 61 | } 62 | } 63 | 64 | module.exports = pingCommand; 65 | -------------------------------------------------------------------------------- /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; -------------------------------------------------------------------------------- /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": "Arslan-Ai", 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 Arslan-Ai" 17 | }, 18 | "keywords": [ 19 | "whatsapp-bot" 20 | ], 21 | "author": "Arslan-MD", 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": "^v7.0.0-rc.3", 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.x" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /commands/hidetag.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 hideTagCommand(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 | await sock.sendMessage(chatId, { text: 'Only admins can use the .hidetag command.' }, { quoted: message }); 27 | return; 28 | } 29 | 30 | const groupMetadata = await sock.groupMetadata(chatId); 31 | const participants = groupMetadata.participants || []; 32 | const nonAdmins = participants.filter(p => !p.admin).map(p => p.id); 33 | 34 | if (replyMessage) { 35 | let content = {}; 36 | if (replyMessage.imageMessage) { 37 | const filePath = await downloadMediaMessage(replyMessage.imageMessage, 'image'); 38 | content = { image: { url: filePath }, caption: messageText || replyMessage.imageMessage.caption || '', mentions: nonAdmins }; 39 | } else if (replyMessage.videoMessage) { 40 | const filePath = await downloadMediaMessage(replyMessage.videoMessage, 'video'); 41 | content = { video: { url: filePath }, caption: messageText || replyMessage.videoMessage.caption || '', mentions: nonAdmins }; 42 | } else if (replyMessage.conversation || replyMessage.extendedTextMessage) { 43 | content = { text: replyMessage.conversation || replyMessage.extendedTextMessage.text, mentions: nonAdmins }; 44 | } else if (replyMessage.documentMessage) { 45 | const filePath = await downloadMediaMessage(replyMessage.documentMessage, 'document'); 46 | content = { document: { url: filePath }, fileName: replyMessage.documentMessage.fileName, caption: messageText || '', mentions: nonAdmins }; 47 | } 48 | 49 | if (Object.keys(content).length > 0) { 50 | await sock.sendMessage(chatId, content); 51 | } 52 | } else { 53 | await sock.sendMessage(chatId, { text: messageText || 'Tagged members (excluding admins).', mentions: nonAdmins }); 54 | } 55 | } 56 | 57 | module.exports = hideTagCommand; 58 | 59 | -------------------------------------------------------------------------------- /commands/pmblocker.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | const PMBLOCKER_PATH = './data/pmblocker.json'; 4 | 5 | function readState() { 6 | try { 7 | if (!fs.existsSync(PMBLOCKER_PATH)) return { enabled: false, message: '⚠️ Direct messages are blocked!\nYou cannot DM this bot. Please contact the owner in group chats only.' }; 8 | const raw = fs.readFileSync(PMBLOCKER_PATH, 'utf8'); 9 | const data = JSON.parse(raw || '{}'); 10 | return { 11 | enabled: !!data.enabled, 12 | message: typeof data.message === 'string' && data.message.trim() ? data.message : '⚠️ Direct messages are blocked!\nYou cannot DM this bot. Please contact the owner in group chats only.' 13 | }; 14 | } catch { 15 | return { enabled: false, message: '⚠️ Direct messages are blocked!\nYou cannot DM this bot. Please contact the owner in group chats only.' }; 16 | } 17 | } 18 | 19 | function writeState(enabled, message) { 20 | try { 21 | if (!fs.existsSync('./data')) fs.mkdirSync('./data', { recursive: true }); 22 | const current = readState(); 23 | const payload = { 24 | enabled: !!enabled, 25 | message: typeof message === 'string' && message.trim() ? message : current.message 26 | }; 27 | fs.writeFileSync(PMBLOCKER_PATH, JSON.stringify(payload, null, 2)); 28 | } catch {} 29 | } 30 | 31 | async function pmblockerCommand(sock, chatId, message, args) { 32 | const argStr = (args || '').trim(); 33 | const [sub, ...rest] = argStr.split(' '); 34 | const state = readState(); 35 | 36 | if (!sub || !['on', 'off', 'status', 'setmsg'].includes(sub.toLowerCase())) { 37 | await sock.sendMessage(chatId, { text: '*PMBLOCKER (Owner only)*\n\n.pmblocker on - Enable PM auto-block\n.pmblocker off - Disable PM blocker\n.pmblocker status - Show current status\n.pmblocker setmsg - Set warning message' }, { quoted: message }); 38 | return; 39 | } 40 | 41 | if (sub.toLowerCase() === 'status') { 42 | await sock.sendMessage(chatId, { text: `PM Blocker is currently *${state.enabled ? 'ON' : 'OFF'}*\nMessage: ${state.message}` }, { quoted: message }); 43 | return; 44 | } 45 | 46 | if (sub.toLowerCase() === 'setmsg') { 47 | const newMsg = rest.join(' ').trim(); 48 | if (!newMsg) { 49 | await sock.sendMessage(chatId, { text: 'Usage: .pmblocker setmsg ' }, { quoted: message }); 50 | return; 51 | } 52 | writeState(state.enabled, newMsg); 53 | await sock.sendMessage(chatId, { text: 'PM Blocker message updated.' }, { quoted: message }); 54 | return; 55 | } 56 | 57 | const enable = sub.toLowerCase() === 'on'; 58 | writeState(enable); 59 | await sock.sendMessage(chatId, { text: `PM Blocker is now *${enable ? 'ENABLED' : 'DISABLED'}*.` }, { quoted: message }); 60 | } 61 | 62 | module.exports = { pmblockerCommand, readState }; 63 | 64 | -------------------------------------------------------------------------------- /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 | }); 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 | }); 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: '120363348739987203@newsletter', 69 | newsletterName: 'Arslan-Ai', 70 | serverMessageId: -1 71 | } 72 | } 73 | }); 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 | }); 80 | } 81 | } 82 | 83 | module.exports = blurCommand; 84 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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://api.shizo.top/ai/imagine/flux`, { 34 | params: { 35 | apikey: 'knightbot', 36 | prompt: enhancedPrompt 37 | }, 38 | responseType: 'arraybuffer' 39 | }); 40 | 41 | // Convert response to buffer 42 | const imageBuffer = Buffer.from(response.data); 43 | 44 | // Send the generated image 45 | await sock.sendMessage(chatId, { 46 | image: imageBuffer, 47 | caption: `🎨 Generated image for prompt: "${imagePrompt}"` 48 | }, { 49 | quoted: message 50 | }); 51 | 52 | } catch (error) { 53 | console.error('Error in imagine command:', error); 54 | await sock.sendMessage(chatId, { 55 | text: '❌ Failed to generate image. Please try again later.' 56 | }, { 57 | quoted: message 58 | }); 59 | } 60 | } 61 | 62 | // Function to enhance the prompt 63 | function enhancePrompt(prompt) { 64 | // Quality enhancing keywords 65 | const qualityEnhancers = [ 66 | 'high quality', 67 | 'detailed', 68 | 'masterpiece', 69 | 'best quality', 70 | 'ultra realistic', 71 | '4k', 72 | 'highly detailed', 73 | 'professional photography', 74 | 'cinematic lighting', 75 | 'sharp focus' 76 | ]; 77 | 78 | // Randomly select 3-4 enhancers 79 | const numEnhancers = Math.floor(Math.random() * 2) + 3; // Random number between 3-4 80 | const selectedEnhancers = qualityEnhancers 81 | .sort(() => Math.random() - 0.5) 82 | .slice(0, numEnhancers); 83 | 84 | // Combine original prompt with enhancers 85 | return `${prompt}, ${selectedEnhancers.join(', ')}`; 86 | } 87 | 88 | module.exports = imagineCommand; -------------------------------------------------------------------------------- /lib/antilink.js: -------------------------------------------------------------------------------- 1 | const { isJidGroup } = require('@whiskeysockets/baileys'); 2 | const { getAntilink, incrementWarningCount, resetWarningCount, isSudo } = require('../lib/index'); 3 | const isAdmin = require('../lib/isAdmin'); 4 | const config = require('../config'); 5 | 6 | const WARN_COUNT = config.WARN_COUNT || 3; 7 | 8 | /** 9 | * Checks if a string contains a URL. 10 | * 11 | * @param {string} str - The string to check. 12 | * @returns {boolean} - True if the string contains a URL, otherwise false. 13 | */ 14 | function containsURL(str) { 15 | const urlRegex = /(https?:\/\/)?([a-z0-9-]+\.)+[a-z]{2,}(\/[^\s]*)?/i; 16 | return urlRegex.test(str); 17 | } 18 | 19 | /** 20 | * Handles the Antilink functionality for group chats. 21 | * 22 | * @param {object} msg - The message object to process. 23 | * @param {object} sock - The socket object to use for sending messages. 24 | */ 25 | async function Antilink(msg, sock) { 26 | const jid = msg.key.remoteJid; 27 | if (!isJidGroup(jid)) return; 28 | 29 | const SenderMessage = msg.message?.conversation || 30 | msg.message?.extendedTextMessage?.text || ''; 31 | if (!SenderMessage || typeof SenderMessage !== 'string') return; 32 | 33 | const sender = msg.key.participant; 34 | if (!sender) return; 35 | 36 | // Skip if sender is group admin or sudo 37 | try { 38 | const { isSenderAdmin } = await isAdmin(sock, jid, sender); 39 | if (isSenderAdmin) return; 40 | } catch (_) {} 41 | const senderIsSudo = await isSudo(sender); 42 | if (senderIsSudo) return; 43 | 44 | if (!containsURL(SenderMessage.trim())) return; 45 | 46 | const antilinkConfig = await getAntilink(jid, 'on'); 47 | if (!antilinkConfig) return; 48 | 49 | const action = antilinkConfig.action; 50 | 51 | try { 52 | // Delete message first 53 | await sock.sendMessage(jid, { delete: msg.key }); 54 | 55 | switch (action) { 56 | case 'delete': 57 | await sock.sendMessage(jid, { 58 | text: `\`\`\`@${sender.split('@')[0]} link are not allowed here\`\`\``, 59 | mentions: [sender] 60 | }); 61 | break; 62 | 63 | case 'kick': 64 | await sock.groupParticipantsUpdate(jid, [sender], 'remove'); 65 | await sock.sendMessage(jid, { 66 | text: `\`\`\`@${sender.split('@')[0]} has been kicked for sending links\`\`\``, 67 | mentions: [sender] 68 | }); 69 | break; 70 | 71 | case 'warn': 72 | const warningCount = await incrementWarningCount(jid, sender); 73 | if (warningCount >= WARN_COUNT) { 74 | await sock.groupParticipantsUpdate(jid, [sender], 'remove'); 75 | await resetWarningCount(jid, sender); 76 | await sock.sendMessage(jid, { 77 | text: `\`\`\`@${sender.split('@')[0]} has been kicked after ${WARN_COUNT} warnings\`\`\``, 78 | mentions: [sender] 79 | }); 80 | } else { 81 | await sock.sendMessage(jid, { 82 | text: `\`\`\`@${sender.split('@')[0]} warning ${warningCount}/${WARN_COUNT} for sending links\`\`\``, 83 | mentions: [sender] 84 | }); 85 | } 86 | break; 87 | } 88 | } catch (error) { 89 | console.error('Error in Antilink:', error); 90 | } 91 | } 92 | 93 | module.exports = { Antilink }; -------------------------------------------------------------------------------- /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(' ') || 'Knight Bot'; 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: '120363348739987203@newsletter', 11 | newsletterName: 'Arslan-Ai', 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; 99 | -------------------------------------------------------------------------------- /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 | */ -------------------------------------------------------------------------------- /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/instagram.js: -------------------------------------------------------------------------------- 1 | const { igdl } = require("ruhend-scraper"); 2 | 3 | // Store processed message IDs to prevent duplicates 4 | const processedMessages = new Set(); 5 | 6 | async function instagramCommand(sock, chatId, message) { 7 | try { 8 | // Check if message has already been processed 9 | if (processedMessages.has(message.key.id)) { 10 | return; 11 | } 12 | 13 | // Add message ID to processed set 14 | processedMessages.add(message.key.id); 15 | 16 | // Clean up old message IDs after 5 minutes 17 | setTimeout(() => { 18 | processedMessages.delete(message.key.id); 19 | }, 5 * 60 * 1000); 20 | 21 | const text = message.message?.conversation || message.message?.extendedTextMessage?.text; 22 | 23 | if (!text) { 24 | return await sock.sendMessage(chatId, { 25 | text: "Please provide an Instagram link for the video." 26 | }); 27 | } 28 | 29 | // Check for various Instagram URL formats 30 | const instagramPatterns = [ 31 | /https?:\/\/(?:www\.)?instagram\.com\//, 32 | /https?:\/\/(?:www\.)?instagr\.am\//, 33 | /https?:\/\/(?:www\.)?instagram\.com\/p\//, 34 | /https?:\/\/(?:www\.)?instagram\.com\/reel\//, 35 | /https?:\/\/(?:www\.)?instagram\.com\/tv\// 36 | ]; 37 | 38 | const isValidUrl = instagramPatterns.some(pattern => pattern.test(text)); 39 | 40 | if (!isValidUrl) { 41 | return await sock.sendMessage(chatId, { 42 | text: "That is not a valid Instagram link. Please provide a valid Instagram post, reel, or video link." 43 | }); 44 | } 45 | 46 | await sock.sendMessage(chatId, { 47 | react: { text: '🔄', key: message.key } 48 | }); 49 | 50 | const downloadData = await igdl(text); 51 | 52 | if (!downloadData || !downloadData.data || downloadData.data.length === 0) { 53 | return await sock.sendMessage(chatId, { 54 | text: "No media found at the provided link." 55 | }); 56 | } 57 | 58 | const mediaData = downloadData.data; 59 | for (let i = 0; i < Math.min(20, mediaData.length); i++) { 60 | const media = mediaData[i]; 61 | const mediaUrl = media.url; 62 | 63 | // Check if URL ends with common video extensions 64 | const isVideo = /\.(mp4|mov|avi|mkv|webm)$/i.test(mediaUrl) || 65 | media.type === 'video' || 66 | text.includes('/reel/') || 67 | text.includes('/tv/'); 68 | 69 | if (isVideo) { 70 | await sock.sendMessage(chatId, { 71 | video: { url: mediaUrl }, 72 | mimetype: "video/mp4", 73 | caption: "DOWNLOADED BY Arslan-Ai" 74 | }, { quoted: message }); 75 | } else { 76 | await sock.sendMessage(chatId, { 77 | image: { url: mediaUrl }, 78 | caption: "DOWNLOADED BY Arslan-Ai" 79 | }, { quoted: message }); 80 | } 81 | } 82 | } catch (error) { 83 | console.error('Error in Instagram command:', error); 84 | await sock.sendMessage(chatId, { 85 | text: "An error occurred while processing the request." 86 | }); 87 | } 88 | } 89 | 90 | module.exports = instagramCommand; 91 | -------------------------------------------------------------------------------- /settings.js: -------------------------------------------------------------------------------- 1 | // 🔒 ULTRA PRO MAX SECURITY SYSTEM 2 | const fs = require("fs"); 3 | const crypto = require("crypto"); 4 | 5 | // 🔐 Anti-Tamper & Clone Protection 6 | const botName = "Arslan-MD"; 7 | const ownerNumber = "923237045919"; 8 | const securityHash = "a1b2c3d4e5f6g7h8i9j0"; // Change this to your unique hash 9 | 10 | // 🚨 Security Check 11 | if (__filename.includes('node_modules') === false) { 12 | const currentFile = fs.readFileSync(__filename, "utf8"); 13 | const fileHash = crypto.createHash('sha256').update(currentFile).digest('hex'); 14 | 15 | if (!currentFile.includes(botName) || !currentFile.includes(ownerNumber) || 16 | !currentFile.includes(securityHash)) { 17 | console.log(` 18 | ╔══════════════════════════════════╗ 19 | ║ 🚨 UNAUTHORIZED ACCESS ALERT ║ 20 | ╠══════════════════════════════════╣ 21 | ║ ║ 22 | ║ Bot Security Violation Detected ║ 23 | ║ Original Owner: ${ownerNumber} ║ 24 | ║ Current Hash: ${fileHash.slice(0, 12)}... ║ 25 | ║ ║ 26 | ║ ❌ SYSTEM SHUTDOWN INITIATED ║ 27 | ╚══════════════════════════════════╝ 28 | `); 29 | process.exit(1); 30 | } 31 | } 32 | 33 | // ⚡ ULTRA PRO MAX SETTINGS 34 | const settings = { 35 | // 🌟 Branding & Identity 36 | botName: "Arslan-Ai", 37 | packname: "Arslan-Ai Premium Pack", 38 | author: "ArslanMD Official", 39 | version: "3.0.0", // Major version upgrade 40 | 41 | // 👑 Ownership 42 | botOwner: "ArslanMD", 43 | ownerNumber: "923237045919", 44 | coOwners: [], // Add secondary owners if needed 45 | 46 | // ⚙️ Operation Modes 47 | MODE: "public", // public/private/group-only 48 | CommandMode: "public", // Legacy support 49 | 50 | // 💎 Premium Features 51 | autoreact: { 52 | status: true, 53 | emoji: "❤️", // Default reaction 54 | whitelist: [] // Numbers to always react to 55 | }, 56 | 57 | autoReply: { 58 | status: true, 59 | message: "🤖 Arslan-MD is currently busy. I'll reply soon!" 60 | }, 61 | 62 | // 🔐 Security 63 | antiSpam: true, 64 | antiVirusScan: true, 65 | maxCommandUsage: 30, // Commands per minute limit 66 | 67 | // 🌐 APIs 68 | giphyApiKey: "qnl7ssQChTdPjsKta2Ax2LMaGXz303tq", 69 | updateZipUrl: "https://github.com/Arslan-MD/Arslan-Ai/archive/refs/heads/main.zip", 70 | openaiKey: "sk-proj-xxxxxxxxxxxxxxxx", // New format 71 | removeBgKey: "rmbg-xxxxxxxxxxxx", 72 | 73 | // 🎨 Media 74 | menuMedia: { 75 | image: "ArslanMedia/media/bot_image.jpg", 76 | video: "ArslanMedia/media/menu.mp4", 77 | gif: "ArslanMedia/media/menu.gif" 78 | }, 79 | 80 | // 📊 Analytics 81 | analytics: true, 82 | errorReporting: true, 83 | 84 | // 🌍 Metadata 85 | description: "⚡ The Most Advanced WhatsApp Bot with ULTRA PRO MAX Features", 86 | website: "https://arslan-md.com", 87 | ytchannel: "https://youtube.com/@arslanmdofficial", 88 | repo: "https://github.com/Arslan-MD/Arslan-Ai", 89 | 90 | // 🔄 System 91 | autoUpdate: true, 92 | backupInterval: 24, // Hours 93 | maxLogSize: 50 // MB 94 | }; 95 | 96 | // 💻 Developer Options 97 | settings.devMode = false; 98 | settings.debugLevel = "error"; // error/warning/info/debug 99 | 100 | // 🛡️ Security Enhancements 101 | settings.securityHash = securityHash; 102 | settings.encryptionKey = "ultrapro-max-secure-key"; // For sensitive data 103 | 104 | // ✅ Backward Compatibility 105 | settings.commandMode = settings.MODE; 106 | 107 | module.exports = settings; 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 | fs.unlinkSync(filePath); 16 | deletedCount++; 17 | } catch (err) { 18 | // Only log errors 19 | console.error(`Error deleting file ${file}:`, err); 20 | } 21 | } 22 | return { success: true, message: `Cleared ${deletedCount} files in ${path.basename(dirPath)}`, count: deletedCount }; 23 | } catch (error) { 24 | console.error('Error in clearDirectory:', error); 25 | return { success: false, message: `Failed to clear files in ${path.basename(dirPath)}`, error: error.message }; 26 | } 27 | } 28 | 29 | // Function to clear both tmp and temp directories 30 | async function clearTmpDirectory() { 31 | const tmpDir = path.join(process.cwd(), 'tmp'); 32 | const tempDir = path.join(process.cwd(), 'temp'); 33 | const results = []; 34 | results.push(clearDirectory(tmpDir)); 35 | results.push(clearDirectory(tempDir)); 36 | // Combine results 37 | const success = results.every(r => r.success); 38 | const totalDeleted = results.reduce((sum, r) => sum + (r.count || 0), 0); 39 | const message = results.map(r => r.message).join(' | '); 40 | return { success, message, count: totalDeleted }; 41 | } 42 | 43 | // Function to handle manual command 44 | async function clearTmpCommand(sock, chatId, msg) { 45 | try { 46 | // Check if user is owner 47 | const isOwner = msg.key.fromMe; 48 | if (!isOwner) { 49 | await sock.sendMessage(chatId, { 50 | text: '❌ This command is only available for the owner!' 51 | }); 52 | return; 53 | } 54 | 55 | const result = await clearTmpDirectory(); 56 | 57 | if (result.success) { 58 | await sock.sendMessage(chatId, { 59 | text: `✅ ${result.message}` 60 | }); 61 | } else { 62 | await sock.sendMessage(chatId, { 63 | text: `❌ ${result.message}` 64 | }); 65 | } 66 | 67 | } catch (error) { 68 | console.error('Error in cleartmp command:', error); 69 | await sock.sendMessage(chatId, { 70 | text: '❌ Failed to clear temporary files!' 71 | }); 72 | } 73 | } 74 | 75 | // Start automatic clearing every 6 hours 76 | function startAutoClear() { 77 | // Run immediately on startup 78 | clearTmpDirectory().then(result => { 79 | if (!result.success) { 80 | console.error(`[Auto Clear] ${result.message}`); 81 | } 82 | // No log for success, regardless of count 83 | }); 84 | 85 | // Set interval for every 6 hours 86 | setInterval(async () => { 87 | const result = await clearTmpDirectory(); 88 | if (!result.success) { 89 | console.error(`[Auto Clear] ${result.message}`); 90 | } 91 | // No log for success, regardless of count 92 | }, 6 * 60 * 60 * 1000); // 6 hours in milliseconds 93 | } 94 | 95 | // Start the automatic clearing 96 | startAutoClear(); 97 | 98 | module.exports = clearTmpCommand; -------------------------------------------------------------------------------- /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) { 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.' }); 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 }); 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/uploader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Arslan-Ai 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 Arslan-Ai 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 Arslan-Ai", 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/groupmanage.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const { downloadContentFromMessage } = require('@whiskeysockets/baileys'); 4 | 5 | async function ensureGroupAndAdmin(sock, chatId, senderId) { 6 | const isGroup = chatId.endsWith('@g.us'); 7 | if (!isGroup) { 8 | await sock.sendMessage(chatId, { text: 'This command can only be used in groups.' }); 9 | return { ok: false }; 10 | } 11 | // Check admin status of sender and bot 12 | const isAdmin = require('../lib/isAdmin'); 13 | const adminStatus = await isAdmin(sock, chatId, senderId); 14 | if (!adminStatus.isBotAdmin) { 15 | await sock.sendMessage(chatId, { text: 'Please make the bot an admin first.' }); 16 | return { ok: false }; 17 | } 18 | if (!adminStatus.isSenderAdmin) { 19 | await sock.sendMessage(chatId, { text: 'Only group admins can use this command.' }); 20 | return { ok: false }; 21 | } 22 | return { ok: true }; 23 | } 24 | 25 | async function setGroupDescription(sock, chatId, senderId, text, message) { 26 | const check = await ensureGroupAndAdmin(sock, chatId, senderId); 27 | if (!check.ok) return; 28 | const desc = (text || '').trim(); 29 | if (!desc) { 30 | await sock.sendMessage(chatId, { text: 'Usage: .setgdesc ' }, { quoted: message }); 31 | return; 32 | } 33 | try { 34 | await sock.groupUpdateDescription(chatId, desc); 35 | await sock.sendMessage(chatId, { text: '✅ Group description updated.' }, { quoted: message }); 36 | } catch (e) { 37 | await sock.sendMessage(chatId, { text: '❌ Failed to update group description.' }, { quoted: message }); 38 | } 39 | } 40 | 41 | async function setGroupName(sock, chatId, senderId, text, message) { 42 | const check = await ensureGroupAndAdmin(sock, chatId, senderId); 43 | if (!check.ok) return; 44 | const name = (text || '').trim(); 45 | if (!name) { 46 | await sock.sendMessage(chatId, { text: 'Usage: .setgname ' }, { quoted: message }); 47 | return; 48 | } 49 | try { 50 | await sock.groupUpdateSubject(chatId, name); 51 | await sock.sendMessage(chatId, { text: '✅ Group name updated.' }, { quoted: message }); 52 | } catch (e) { 53 | await sock.sendMessage(chatId, { text: '❌ Failed to update group name.' }, { quoted: message }); 54 | } 55 | } 56 | 57 | async function setGroupPhoto(sock, chatId, senderId, message) { 58 | const check = await ensureGroupAndAdmin(sock, chatId, senderId); 59 | if (!check.ok) return; 60 | 61 | const quoted = message.message?.extendedTextMessage?.contextInfo?.quotedMessage; 62 | const imageMessage = quoted?.imageMessage || quoted?.stickerMessage; 63 | if (!imageMessage) { 64 | await sock.sendMessage(chatId, { text: 'Reply to an image/sticker with .setgpp' }, { quoted: message }); 65 | return; 66 | } 67 | try { 68 | const tmpDir = path.join(process.cwd(), 'tmp'); 69 | if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir, { recursive: true }); 70 | 71 | const stream = await downloadContentFromMessage(imageMessage, 'image'); 72 | let buffer = Buffer.from([]); 73 | for await (const chunk of stream) buffer = Buffer.concat([buffer, chunk]); 74 | 75 | const imgPath = path.join(tmpDir, `gpp_${Date.now()}.jpg`); 76 | fs.writeFileSync(imgPath, buffer); 77 | 78 | await sock.updateProfilePicture(chatId, { url: imgPath }); 79 | try { fs.unlinkSync(imgPath); } catch (_) {} 80 | await sock.sendMessage(chatId, { text: '✅ Group profile photo updated.' }, { quoted: message }); 81 | } catch (e) { 82 | await sock.sendMessage(chatId, { text: '❌ Failed to update group profile photo.' }, { quoted: message }); 83 | } 84 | } 85 | 86 | module.exports = { 87 | setGroupDescription, 88 | setGroupName, 89 | setGroupPhoto 90 | }; 91 | 92 | -------------------------------------------------------------------------------- /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 | }); 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 | }); 21 | } 22 | 23 | // Send loading reaction 24 | await sock.sendMessage(chatId, { 25 | react: { text: '🔄', key: message.key } 26 | }); 27 | 28 | // Fetch video data from API 29 | const response = await axios.get(`https://api.dreaded.site/api/facebook?url=${url}`); 30 | const data = response.data; 31 | 32 | if (!data || data.status !== 200 || !data.facebook || !data.facebook.sdVideo) { 33 | return await sock.sendMessage(chatId, { 34 | text: "Sorry the API didn't respond correctly. Please try Again later!" 35 | }); 36 | } 37 | 38 | const fbvid = data.facebook.sdVideo; 39 | 40 | if (!fbvid) { 41 | return await sock.sendMessage(chatId, { 42 | text: "Wrong Facebook data. Please ensure the video exists." 43 | }); 44 | } 45 | 46 | // Create temp directory if it doesn't exist 47 | const tmpDir = path.join(process.cwd(), 'tmp'); 48 | if (!fs.existsSync(tmpDir)) { 49 | fs.mkdirSync(tmpDir, { recursive: true }); 50 | } 51 | 52 | // Generate temp file path 53 | const tempFile = path.join(tmpDir, `fb_${Date.now()}.mp4`); 54 | 55 | // Download the video 56 | const videoResponse = await axios({ 57 | method: 'GET', 58 | url: fbvid, 59 | responseType: 'stream', 60 | headers: { 61 | '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', 62 | 'Accept': 'video/mp4,video/*;q=0.9,*/*;q=0.8', 63 | 'Accept-Language': 'en-US,en;q=0.5', 64 | 'Range': 'bytes=0-', 65 | 'Connection': 'keep-alive', 66 | 'Referer': 'https://www.facebook.com/' 67 | } 68 | }); 69 | 70 | const writer = fs.createWriteStream(tempFile); 71 | videoResponse.data.pipe(writer); 72 | 73 | await new Promise((resolve, reject) => { 74 | writer.on('finish', resolve); 75 | writer.on('error', reject); 76 | }); 77 | 78 | // Check if file was downloaded successfully 79 | if (!fs.existsSync(tempFile) || fs.statSync(tempFile).size === 0) { 80 | throw new Error('Failed to download video'); 81 | } 82 | 83 | // Send the video 84 | await sock.sendMessage(chatId, { 85 | video: { url: tempFile }, 86 | mimetype: "video/mp4", 87 | caption: "DOWNLOADED BY Arslan-Ai" 88 | }, { quoted: message }); 89 | 90 | // Clean up temp file 91 | try { 92 | fs.unlinkSync(tempFile); 93 | } catch (err) { 94 | console.error('Error cleaning up temp file:', err); 95 | } 96 | 97 | } catch (error) { 98 | console.error('Error in Facebook command:', error); 99 | await sock.sendMessage(chatId, { 100 | text: "An error occurred. API might be down. Error: " + error.message 101 | }); 102 | } 103 | } 104 | 105 | module.exports = facebookCommand; 106 | -------------------------------------------------------------------------------- /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/song.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | const yts = require('yt-search'); 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | 6 | const AXIOS_DEFAULTS = { 7 | timeout: 60000, 8 | headers: { 9 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 10 | 'Accept': 'application/json, text/plain, */*' 11 | } 12 | }; 13 | 14 | async function tryRequest(getter, attempts = 3) { 15 | let lastError; 16 | for (let attempt = 1; attempt <= attempts; attempt++) { 17 | try { 18 | return await getter(); 19 | } catch (err) { 20 | lastError = err; 21 | if (attempt < attempts) { 22 | await new Promise(r => setTimeout(r, 1000 * attempt)); 23 | } 24 | } 25 | } 26 | throw lastError; 27 | } 28 | 29 | async function getIzumiDownloadByUrl(youtubeUrl) { 30 | const apiUrl = `https://izumiiiiiiii.dpdns.org/downloader/youtube?url=${encodeURIComponent(youtubeUrl)}&format=mp3`; 31 | const res = await tryRequest(() => axios.get(apiUrl, AXIOS_DEFAULTS)); 32 | if (res?.data?.result?.download) return res.data.result; 33 | throw new Error('Izumi youtube?url returned no download'); 34 | } 35 | 36 | async function getIzumiDownloadByQuery(query) { 37 | const apiUrl = `https://izumiiiiiiii.dpdns.org/downloader/youtube-play?query=${encodeURIComponent(query)}`; 38 | const res = await tryRequest(() => axios.get(apiUrl, AXIOS_DEFAULTS)); 39 | if (res?.data?.result?.download) return res.data.result; 40 | throw new Error('Izumi youtube-play returned no download'); 41 | } 42 | 43 | async function getOkatsuDownloadByUrl(youtubeUrl) { 44 | const apiUrl = `https://okatsu-rolezapiiz.vercel.app/downloader/ytmp3?url=${encodeURIComponent(youtubeUrl)}`; 45 | const res = await tryRequest(() => axios.get(apiUrl, AXIOS_DEFAULTS)); 46 | // Okatsu response shape: { status, creator, title, format, thumb, duration, cached, dl } 47 | if (res?.data?.dl) { 48 | return { 49 | download: res.data.dl, 50 | title: res.data.title, 51 | thumbnail: res.data.thumb 52 | }; 53 | } 54 | throw new Error('Okatsu ytmp3 returned no download'); 55 | } 56 | 57 | async function songCommand(sock, chatId, message) { 58 | try { 59 | const text = message.message?.conversation || message.message?.extendedTextMessage?.text || ''; 60 | if (!text) { 61 | await sock.sendMessage(chatId, { text: 'Usage: .song ' }, { quoted: message }); 62 | return; 63 | } 64 | 65 | let video; 66 | if (text.includes('youtube.com') || text.includes('youtu.be')) { 67 | video = { url: text }; 68 | } else { 69 | const search = await yts(text); 70 | if (!search || !search.videos.length) { 71 | await sock.sendMessage(chatId, { text: 'No results found.' }, { quoted: message }); 72 | return; 73 | } 74 | video = search.videos[0]; 75 | } 76 | 77 | // Inform user 78 | await sock.sendMessage(chatId, { 79 | image: { url: video.thumbnail }, 80 | caption: `🎵 Downloading: *${video.title}*\n⏱ Duration: ${video.timestamp}` 81 | }, { quoted: message }); 82 | 83 | // Try Izumi primary by URL, then by query, then Okatsu fallback 84 | let audioData; 85 | try { 86 | // 1) Primary: Izumi by youtube url 87 | audioData = await getIzumiDownloadByUrl(video.url); 88 | } catch (e1) { 89 | try { 90 | // 2) Secondary: Izumi search by query/title 91 | const query = video.title || text; 92 | audioData = await getIzumiDownloadByQuery(query); 93 | } catch (e2) { 94 | // 3) Fallback: Okatsu by youtube url 95 | audioData = await getOkatsuDownloadByUrl(video.url); 96 | } 97 | } 98 | 99 | await sock.sendMessage(chatId, { 100 | audio: { url: audioData.download || audioData.dl || audioData.url }, 101 | mimetype: 'audio/mpeg', 102 | fileName: `${(audioData.title || video.title || 'song')}.mp3`, 103 | ptt: false 104 | }, { quoted: message }); 105 | 106 | } catch (err) { 107 | console.error('Song command error:', err); 108 | await sock.sendMessage(chatId, { text: '❌ Failed to download song.' }, { quoted: message }); 109 | } 110 | } 111 | 112 | module.exports = songCommand; 113 | -------------------------------------------------------------------------------- /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 | } 13 | 14 | // Get the command and query 15 | const parts = text.split(' '); 16 | const command = parts[0].toLowerCase(); 17 | const query = parts.slice(1).join(' ').trim(); 18 | 19 | if (!query) { 20 | return await sock.sendMessage(chatId, { 21 | text: "Please provide a question after .gpt or .gemini" 22 | }); 23 | } 24 | 25 | try { 26 | // Show processing message 27 | await sock.sendMessage(chatId, { 28 | react: { text: '🤖', key: message.key } 29 | }); 30 | 31 | if (command === '.gpt') { 32 | // Call the GPT API 33 | const response = await axios.get(`https://api.dreaded.site/api/chatgpt?text=${encodeURIComponent(query)}`); 34 | 35 | if (response.data && response.data.success && response.data.result) { 36 | const answer = response.data.result.prompt; 37 | await sock.sendMessage(chatId, { 38 | text: answer 39 | }, { 40 | quoted: message 41 | }); 42 | 43 | } else { 44 | throw new Error('Invalid response from API'); 45 | } 46 | } else if (command === '.gemini') { 47 | const apis = [ 48 | `https://vapis.my.id/api/gemini?q=${encodeURIComponent(query)}`, 49 | `https://api.siputzx.my.id/api/ai/gemini-pro?content=${encodeURIComponent(query)}`, 50 | `https://api.ryzendesu.vip/api/ai/gemini?text=${encodeURIComponent(query)}`, 51 | `https://api.dreaded.site/api/gemini2?text=${encodeURIComponent(query)}`, 52 | `https://api.giftedtech.my.id/api/ai/geminiai?apikey=gifted&q=${encodeURIComponent(query)}`, 53 | `https://api.giftedtech.my.id/api/ai/geminiaipro?apikey=gifted&q=${encodeURIComponent(query)}` 54 | ]; 55 | 56 | for (const api of apis) { 57 | try { 58 | const response = await fetch(api); 59 | const data = await response.json(); 60 | 61 | if (data.message || data.data || data.answer || data.result) { 62 | const answer = data.message || data.data || data.answer || data.result; 63 | await sock.sendMessage(chatId, { 64 | text: answer 65 | }, { 66 | quoted: message 67 | }); 68 | 69 | return; 70 | } 71 | } catch (e) { 72 | continue; 73 | } 74 | } 75 | throw new Error('All Gemini APIs failed'); 76 | } 77 | } catch (error) { 78 | console.error('API Error:', error); 79 | await sock.sendMessage(chatId, { 80 | text: "❌ Failed to get response. Please try again later.", 81 | contextInfo: { 82 | mentionedJid: [message.key.participant || message.key.remoteJid], 83 | quotedMessage: message.message 84 | } 85 | }); 86 | } 87 | } catch (error) { 88 | console.error('AI Command Error:', error); 89 | await sock.sendMessage(chatId, { 90 | text: "❌ An error occurred. Please try again later.", 91 | contextInfo: { 92 | mentionedJid: [message.key.participant || message.key.remoteJid], 93 | quotedMessage: message.message 94 | } 95 | }); 96 | } 97 | } 98 | 99 | module.exports = aiCommand; -------------------------------------------------------------------------------- /commands/insult.js: -------------------------------------------------------------------------------- 1 | const insults = [ 2 | "Tu badal ki tarah hai, jab chala jaye to din haseen ho jata hai!", 3 | "Jab tu room se nikalta hai na, sab ke chehron pe khushi aa jati hai!", 4 | "Main tujhse agree karun? Bhai phir dono hi galat ho jaenge.", 5 | "Tu bewakoof nahi hai, bas teri soch badnaseeb hai.", 6 | "Tere raaz hamesha mere paas safe hain... sunta hi nahi main!", 7 | "Tu zinda example hai ke evolution bhi kabhi kabhi break pe chala jata hai.", 8 | "Tere thoday thoday chins nahi... teesra wala saaf kar le zara.", 9 | "Tu software update jaisa lagta hai... har baar dekho to lage zaroori nahi hai abhi.", 10 | "Tu sabko khushi deta hai... jab tu chala jata hai.", 11 | "Tu ek penny jaisa hai—do chehray wala aur kisi kaam ka nahi.", 12 | "Kuch dimaag me chal raha tha? Arey rehne de, chhoro!", 13 | "Shampoo bottles pe instructions teri wajah se likhte hain bhai.", 14 | "Tu badal jaisa hai... idhar udhar ghoomta rehta hai bina kisi kaam ke.", 15 | "Tere jokes expired doodh jese hain—na hasate hain na hazam hote hain.", 16 | "Tu candle ki tarah hai... halki si hawa mein bujh jata hai.", 17 | "Tera talent hi yeh hai ke sabko barabar tang karta hai.", 18 | "Tu Wi-Fi jaisa hai—jab zaroorat ho tab signal weak ho jata hai.", 19 | "Tu proof hai ke bina filter ke bhi log bure lag sakte hain.", 20 | "Teri energy black hole jaisi hai—sab ki jaan choos leta hai.", 21 | "Tera chehra sirf radio ke liye hi theek hai.", 22 | "Tu traffic jam jaisa hai—koi nahi chahta, lekin sabko jhelna padta hai.", 23 | "Tu tooti hui pencil jaisa hai—bilkul bekaar aur pointless.", 24 | "Tere ideas itne naye hain ke main unhein pehle hi sun chuka hoon.", 25 | "Tu zinda saboot hai ke galtiyan bhi kabhi kabhi kaam ki hoti hain.", 26 | "Tu lazy nahi hai... bas kuch nahi karne ka bada shauk hai tujhe.", 27 | "Tera dimaag Windows 95 pe chal raha hai—slow aur outdated.", 28 | "Tu speed bump jaisa hai—na koi pasand karta hai, na koi chharta hai.", 29 | "Tu machharon ke jhund jaisa hai—sirf irritate karta hai.", 30 | "Tu logon ko sirf isliye ikattha karta hai... taake wo milke tujhe gali de saken." 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/settings.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | function readJsonSafe(path, fallback) { 4 | try { 5 | const txt = fs.readFileSync(path, 'utf8'); 6 | return JSON.parse(txt); 7 | } catch (_) { 8 | return fallback; 9 | } 10 | } 11 | 12 | async function settingsCommand(sock, chatId, message) { 13 | try { 14 | // Owner-only 15 | if (!message.key.fromMe) { 16 | await sock.sendMessage(chatId, { text: 'Only bot owner can use this command!' }, { quoted: message }); 17 | return; 18 | } 19 | 20 | const isGroup = chatId.endsWith('@g.us'); 21 | const dataDir = './data'; 22 | 23 | const mode = readJsonSafe(`${dataDir}/messageCount.json`, { isPublic: true }); 24 | const autoStatus = readJsonSafe(`${dataDir}/autoStatus.json`, { enabled: false }); 25 | const autoread = readJsonSafe(`${dataDir}/autoread.json`, { enabled: false }); 26 | const autotyping = readJsonSafe(`${dataDir}/autotyping.json`, { enabled: false }); 27 | const pmblocker = readJsonSafe(`${dataDir}/pmblocker.json`, { enabled: false }); 28 | const anticall = readJsonSafe(`${dataDir}/anticall.json`, { enabled: false }); 29 | const userGroupData = readJsonSafe(`${dataDir}/userGroupData.json`, { 30 | antilink: {}, antibadword: {}, welcome: {}, goodbye: {}, chatbot: {}, antitag: {} 31 | }); 32 | const autoReaction = Boolean(userGroupData.autoReaction); 33 | 34 | // Per-group features 35 | const groupId = isGroup ? chatId : null; 36 | const antilinkOn = groupId ? Boolean(userGroupData.antilink && userGroupData.antilink[groupId]) : false; 37 | const antibadwordOn = groupId ? Boolean(userGroupData.antibadword && userGroupData.antibadword[groupId]) : false; 38 | const welcomeOn = groupId ? Boolean(userGroupData.welcome && userGroupData.welcome[groupId]) : false; 39 | const goodbyeOn = groupId ? Boolean(userGroupData.goodbye && userGroupData.goodbye[groupId]) : false; 40 | const chatbotOn = groupId ? Boolean(userGroupData.chatbot && userGroupData.chatbot[groupId]) : false; 41 | const antitagCfg = groupId ? (userGroupData.antitag && userGroupData.antitag[groupId]) : null; 42 | 43 | const lines = []; 44 | lines.push('*BOT SETTINGS*'); 45 | lines.push(''); 46 | lines.push(`• Mode: ${mode.isPublic ? 'Public' : 'Private'}`); 47 | lines.push(`• Auto Status: ${autoStatus.enabled ? 'ON' : 'OFF'}`); 48 | lines.push(`• Autoread: ${autoread.enabled ? 'ON' : 'OFF'}`); 49 | lines.push(`• Autotyping: ${autotyping.enabled ? 'ON' : 'OFF'}`); 50 | lines.push(`• PM Blocker: ${pmblocker.enabled ? 'ON' : 'OFF'}`); 51 | lines.push(`• Anticall: ${anticall.enabled ? 'ON' : 'OFF'}`); 52 | lines.push(`• Auto Reaction: ${autoReaction ? 'ON' : 'OFF'}`); 53 | if (groupId) { 54 | lines.push(''); 55 | lines.push(`Group: ${groupId}`); 56 | if (antilinkOn) { 57 | const al = userGroupData.antilink[groupId]; 58 | lines.push(`• Antilink: ON (action: ${al.action || 'delete'})`); 59 | } else { 60 | lines.push('• Antilink: OFF'); 61 | } 62 | if (antibadwordOn) { 63 | const ab = userGroupData.antibadword[groupId]; 64 | lines.push(`• Antibadword: ON (action: ${ab.action || 'delete'})`); 65 | } else { 66 | lines.push('• Antibadword: OFF'); 67 | } 68 | lines.push(`• Welcome: ${welcomeOn ? 'ON' : 'OFF'}`); 69 | lines.push(`• Goodbye: ${goodbyeOn ? 'ON' : 'OFF'}`); 70 | lines.push(`• Chatbot: ${chatbotOn ? 'ON' : 'OFF'}`); 71 | if (antitagCfg && antitagCfg.enabled) { 72 | lines.push(`• Antitag: ON (action: ${antitagCfg.action || 'delete'})`); 73 | } else { 74 | lines.push('• Antitag: OFF'); 75 | } 76 | } else { 77 | lines.push(''); 78 | lines.push('Note: Per-group settings will be shown when used inside a group.'); 79 | } 80 | 81 | await sock.sendMessage(chatId, { text: lines.join('\n') }, { quoted: message }); 82 | } catch (error) { 83 | console.error('Error in settings command:', error); 84 | await sock.sendMessage(chatId, { text: 'Failed to read settings.' }, { quoted: message }); 85 | } 86 | } 87 | 88 | module.exports = settingsCommand; 89 | 90 | -------------------------------------------------------------------------------- /commands/url.js: -------------------------------------------------------------------------------- 1 | const { downloadContentFromMessage } = require('@whiskeysockets/baileys'); 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | const { UploadFileUgu, TelegraPh } = require('../lib/uploader'); 5 | 6 | async function getMediaBufferAndExt(message) { 7 | const m = message.message || {}; 8 | if (m.imageMessage) { 9 | const stream = await downloadContentFromMessage(m.imageMessage, 'image'); 10 | const chunks = []; 11 | for await (const chunk of stream) chunks.push(chunk); 12 | return { buffer: Buffer.concat(chunks), ext: '.jpg' }; 13 | } 14 | if (m.videoMessage) { 15 | const stream = await downloadContentFromMessage(m.videoMessage, 'video'); 16 | const chunks = []; 17 | for await (const chunk of stream) chunks.push(chunk); 18 | return { buffer: Buffer.concat(chunks), ext: '.mp4' }; 19 | } 20 | if (m.audioMessage) { 21 | const stream = await downloadContentFromMessage(m.audioMessage, 'audio'); 22 | const chunks = []; 23 | for await (const chunk of stream) chunks.push(chunk); 24 | // default mp3 for voice/ptt may be opus; still use .mp3 generically 25 | return { buffer: Buffer.concat(chunks), ext: '.mp3' }; 26 | } 27 | if (m.documentMessage) { 28 | const stream = await downloadContentFromMessage(m.documentMessage, 'document'); 29 | const chunks = []; 30 | for await (const chunk of stream) chunks.push(chunk); 31 | const fileName = m.documentMessage.fileName || 'file.bin'; 32 | const ext = path.extname(fileName) || '.bin'; 33 | return { buffer: Buffer.concat(chunks), ext }; 34 | } 35 | if (m.stickerMessage) { 36 | const stream = await downloadContentFromMessage(m.stickerMessage, 'sticker'); 37 | const chunks = []; 38 | for await (const chunk of stream) chunks.push(chunk); 39 | return { buffer: Buffer.concat(chunks), ext: '.webp' }; 40 | } 41 | return null; 42 | } 43 | 44 | async function getQuotedMediaBufferAndExt(message) { 45 | const quoted = message.message?.extendedTextMessage?.contextInfo?.quotedMessage || null; 46 | if (!quoted) return null; 47 | return getMediaBufferAndExt({ message: quoted }); 48 | } 49 | 50 | async function urlCommand(sock, chatId, message) { 51 | try { 52 | // Prefer current message media, else quoted media 53 | let media = await getMediaBufferAndExt(message); 54 | if (!media) media = await getQuotedMediaBufferAndExt(message); 55 | 56 | if (!media) { 57 | await sock.sendMessage(chatId, { text: 'Send or reply to a media (image, video, audio, sticker, document) to get a URL.' }, { quoted: message }); 58 | return; 59 | } 60 | 61 | const tempDir = path.join(__dirname, '../temp'); 62 | if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir, { recursive: true }); 63 | const tempPath = path.join(tempDir, `${Date.now()}${media.ext}`); 64 | fs.writeFileSync(tempPath, media.buffer); 65 | 66 | let url = ''; 67 | try { 68 | if (media.ext === '.jpg' || media.ext === '.png' || media.ext === '.webp') { 69 | // Try TelegraPh for images/webp first (fast, simple) 70 | try { 71 | url = await TelegraPh(tempPath); 72 | } catch { 73 | // Fallback to Uguu for any file type 74 | const res = await UploadFileUgu(tempPath); 75 | url = typeof res === 'string' ? res : (res.url || res.url_full || JSON.stringify(res)); 76 | } 77 | } else { 78 | const res = await UploadFileUgu(tempPath); 79 | url = typeof res === 'string' ? res : (res.url || res.url_full || JSON.stringify(res)); 80 | } 81 | } finally { 82 | setTimeout(() => { 83 | try { if (fs.existsSync(tempPath)) fs.unlinkSync(tempPath); } catch {} 84 | }, 2000); 85 | } 86 | 87 | if (!url) { 88 | await sock.sendMessage(chatId, { text: 'Failed to upload media.' }, { quoted: message }); 89 | return; 90 | } 91 | 92 | await sock.sendMessage(chatId, { text: `URL: ${url}` }, { quoted: message }); 93 | } catch (error) { 94 | console.error('[URL] error:', error?.message || error); 95 | await sock.sendMessage(chatId, { text: 'Failed to convert media to URL.' }, { quoted: message }); 96 | } 97 | } 98 | 99 | module.exports = urlCommand; 100 | 101 | -------------------------------------------------------------------------------- /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\n> *_PROCESSED BY ARSLAN-AI_*' 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 | --------------------------------------------------------------------------------