├── lib ├── ROMEK-XD ├── binary.cjs ├── converter.cjs └── exif.cjs ├── src ├── event │ ├── take.js │ ├── romek-xd │ ├── index.js │ ├── call-handler.js │ ├── group-handler.js │ ├── handler.js │ └── antilink.js ├── romek-xd ├── romek.jpg ├── romek1.jpg ├── romek2.jpg ├── watermark.png ├── plugin │ ├── dbinary.js │ ├── ebinary.js │ ├── restart.js │ ├── ping.js │ ├── autoaction.js │ ├── owner.js │ ├── exit.js │ ├── setprefix.js │ ├── flirt.js │ ├── block.js │ ├── tomp3.js │ ├── unblock.js │ ├── readqr.js │ ├── waifu.js │ ├── del.js │ ├── linkgc.js │ ├── statusmsg.js │ ├── autoread.js │ ├── autoblock.js │ ├── autoreact.js │ ├── take.js │ ├── autotyping.js │ ├── enhancer.js │ ├── Anticall.js │ ├── mode.js │ ├── alwaysonline.js │ ├── setgroupname.js │ ├── autorecording.js │ ├── setdesc.js │ ├── statusreply.js │ ├── autos.js │ ├── report.js │ ├── emojimix.js │ ├── gdrive.js │ ├── pinterestdl.js │ ├── tagall.js │ ├── cal.js │ ├── join.js │ ├── welcome.js │ ├── fetch.js │ ├── gemini.js │ ├── qrgenerater.js │ ├── insta.js │ ├── play.js │ ├── hd.js │ ├── status.js │ ├── invite.js │ ├── dl-ringtone.js │ ├── remove.js │ ├── demote.js │ ├── hidetag.js │ ├── romovebg.js │ ├── insta-dl.js │ ├── imagetotext.js │ ├── gimage.js │ ├── imdb.js │ ├── rvo.js │ ├── whatmusic.js │ ├── qc.js │ ├── fb-dl.js │ ├── gcfullpp.js │ ├── dl-tiktok.js │ ├── promote.js │ ├── vv2.js │ ├── fullpp.js │ ├── sticker.js │ ├── audioeffect.js │ ├── trt.js │ ├── crick.js │ ├── fetch-vv.js │ ├── githubstalk.js │ ├── lyrics.js │ ├── autogroup.js │ ├── tourl.js │ ├── alive.js │ ├── repo.js │ ├── tohd2.js │ ├── gpinfo.js │ ├── help.js │ ├── gpt.js │ └── fbdown.js ├── generateProfilePicture.js ├── remini.cjs └── uploader.js ├── heroku.yml ├── Procfile ├── .env ├── Dockerfile ├── LICENSE ├── config.cjs ├── app.json ├── package.json └── README.md /lib/ROMEK-XD: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/event/take.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/romek-xd: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/event/romek-xd: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/romek.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ROMEKTRICKS/ROMEK-XD/HEAD/src/romek.jpg -------------------------------------------------------------------------------- /src/romek1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ROMEKTRICKS/ROMEK-XD/HEAD/src/romek1.jpg -------------------------------------------------------------------------------- /src/romek2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ROMEKTRICKS/ROMEK-XD/HEAD/src/romek2.jpg -------------------------------------------------------------------------------- /src/watermark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ROMEKTRICKS/ROMEK-XD/HEAD/src/watermark.png -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | web: Dockerfile 4 | 5 | run: 6 | web: node . 7 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: npm i pm2 -g && pm2 install ffmpeg && pm2 start index.js --deep-monitoring --attach --name Ethix-MD -------------------------------------------------------------------------------- /src/event/index.js: -------------------------------------------------------------------------------- 1 | import Handler from './handler.js' 2 | import Callupdate from './call-handler.js' 3 | import GroupUpdate from './group-handler.js' 4 | 5 | export { Handler, Callupdate, GroupUpdate }; -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | SESSION_ID= 2 | AUTO_STATUS_SEEN=true 3 | AUTO_STATUS_REPLY=true 4 | STATUS_READ_MSG= 5 | REJECT_CALL=false 6 | MODE=private 7 | WELCOME=false 8 | AUTO_READ=false 9 | AUTO_TYPING=false 10 | AUTO_RECORDING=false 11 | ALWAYS_ONLINE=false 12 | AUTO_BLOCK=true 13 | AUTO_REACT=false 14 | PREFIX=. 15 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-buster 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y \ 5 | ffmpeg \ 6 | imagemagick \ 7 | webp && \ 8 | apt-get upgrade -y && \ 9 | rm -rf /var/lib/apt/lists/* 10 | 11 | COPY package.json . 12 | 13 | RUN npm install && npm install -g qrcode-terminal pm2 14 | 15 | COPY . . 16 | 17 | EXPOSE 3000 18 | 19 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /lib/binary.cjs: -------------------------------------------------------------------------------- 1 | async function dBinary(str) { 2 | var newBin = str.split(" ") 3 | var binCode = [] 4 | for (i = 0; i < newBin.length; i++) { 5 | binCode.push(String.fromCharCode(parseInt(newBin[i], 2))) 6 | } 7 | return binCode.join("") 8 | } 9 | 10 | async function eBinary(str = ''){ 11 | let res = '' 12 | res = str.split('').map(char => { 13 | return char.charCodeAt(0).toString(2); 14 | }).join(' ') 15 | return res 16 | } 17 | 18 | module.exports = { dBinary, eBinary } -------------------------------------------------------------------------------- /src/event/call-handler.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const Callupdate = async (json, sock) => { 4 | for (const id of json) { 5 | if (id.status === 'offer' && config.REJECT_CALL ) { 6 | let msg = await sock.sendMessage(id.from, { 7 | text: `*_📞 Auto Reject Call Mode Activated_* \n*_📵 No Calls Allowed_*`, 8 | mentions: [id.from], 9 | }); 10 | await sock.rejectCall(id.id, id.from); 11 | } 12 | } 13 | }; 14 | 15 | export default Callupdate; 16 | -------------------------------------------------------------------------------- /src/plugin/dbinary.js: -------------------------------------------------------------------------------- 1 | import { dBinary } from '../../lib/binary.cjs'; 2 | import config from '../../config.cjs'; 3 | 4 | const dbinary = async (m, gss) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const validCommands = ['dbinary']; 10 | 11 | if (validCommands.includes(cmd)) { 12 | if (!text) return m.reply('Please provide a text.'); 13 | let db = await dBinary(text) 14 | m.reply(db) 15 | } 16 | }; 17 | 18 | export default dbinary; -------------------------------------------------------------------------------- /src/plugin/ebinary.js: -------------------------------------------------------------------------------- 1 | import { eBinary } from '../../lib/binary.cjs'; 2 | import config from '../../config.cjs'; 3 | 4 | const ebinary = async (m, gss) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const validCommands = ['ebinary']; 10 | 11 | if (validCommands.includes(cmd)) { 12 | if (!text) return m.reply('Please provide a question.'); 13 | let db = await eBinary(text) 14 | m.reply(db) 15 | } 16 | }; 17 | 18 | export default ebinary; -------------------------------------------------------------------------------- /src/plugin/restart.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const restartBot = async (m) => { 4 | const prefix = config.PREFIX; 5 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 6 | const text = m.body.slice(prefix.length + cmd.length).trim(); 7 | 8 | if (cmd === 'restart') { 9 | try { 10 | m.reply('Proses....') 11 | await process.exit() 12 | } catch (error) { 13 | console.error(error); 14 | await m.React("❌"); 15 | return m.reply(`An error occurred while restarting the bot: ${error.message}`); 16 | } 17 | } 18 | }; 19 | 20 | export default restartBot; 21 | -------------------------------------------------------------------------------- /src/plugin/ping.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const ping = async (m, sock) => { 4 | const prefix = config.PREFIX; 5 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 6 | const text = m.body.slice(prefix.length + cmd.length).trim(); 7 | 8 | if (cmd === "ping") { 9 | const start = new Date().getTime(); 10 | await m.React('⤵️'); 11 | const end = new Date().getTime(); 12 | const responseTime = (end - start) / 1000; 13 | 14 | const text = `🧿𝗥𝗢𝗠𝗘𝗞-𝗫𝗗🪀: ${responseTime.toFixed(2)} s_*`; 15 | sock.sendMessage(m.from, { text }, { quoted: m }); 16 | } 17 | } 18 | 19 | export default ping; 20 | -------------------------------------------------------------------------------- /src/plugin/autoaction.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | async function handleCommand(m, gss) { 4 | 5 | if (config.AUTO_TYPING && m.from) { 6 | gss.sendPresenceUpdate("composing", m.from); 7 | } 8 | 9 | if (config.AUTO_RECORDING && m.from) { 10 | gss.sendPresenceUpdate("recording", m.from); 11 | } 12 | 13 | if (m.from) { 14 | gss.sendPresenceUpdate(config.ALWAYS_ONLINE ? 'available' : 'unavailable', m.from); 15 | } 16 | 17 | if (config.AUTO_READ) { 18 | await gss.readMessages([m.key]); 19 | } 20 | 21 | if (config.AUTO_BLOCK && m.sender.startsWith('212')) { 22 | await gss.updateBlockStatus(m.sender, 'block'); 23 | } 24 | } 25 | 26 | export default handleCommand; 27 | -------------------------------------------------------------------------------- /src/plugin/owner.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const ownerContact = async (m, gss) => { 4 | const ownernumber = config.OWNER_NUMBER; 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | if (cmd === 'owner') { 10 | try { 11 | await gss.sendContact(m.from, [ownernumber], m); 12 | await m.React("✅"); 13 | } catch (error) { 14 | console.error('Error sending owner contact:', error); 15 | m.reply('Error sending owner contact.'); 16 | await m.React("❌"); 17 | } 18 | } 19 | }; 20 | 21 | export default ownerContact; 22 | -------------------------------------------------------------------------------- /src/plugin/exit.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const leaveGroup = async (m, gss) => { 4 | try { 5 | const botNumber = await gss.decodeJid(gss.user.id); 6 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | const validCommands = ['leave', 'exit', 'left']; 12 | 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | if (!m.isGroup) return m.reply("*❌ THIS COMMAND CAN ONLY BE USED IN GROUPS*"); 16 | 17 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 18 | 19 | await gss.groupLeave(m.from); 20 | } catch (error) { 21 | console.error('Error:', error); 22 | } 23 | }; 24 | 25 | export default leaveGroup; 26 | -------------------------------------------------------------------------------- /src/plugin/setprefix.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const setprefixCommand = async (m, Matrix) => { 4 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 5 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | if (cmd === 'setprefix') { 11 | if (!isCreator) { 12 | await Matrix.sendMessage(m.from, { text: "*❌ THIS IS AN OWNER COMMAND*" }, { quoted: m }); 13 | return; 14 | } 15 | 16 | if (text) { 17 | config.PREFIX = text; 18 | m.reply(`Prefix has been changed to '${text}'.`); 19 | } else { 20 | m.reply("Please specify a new prefix."); 21 | } 22 | } 23 | }; 24 | 25 | export default setprefixCommand; 26 | -------------------------------------------------------------------------------- /src/plugin/flirt.js: -------------------------------------------------------------------------------- 1 | import nodeFetch from 'node-fetch'; 2 | import config from '../config.cjs'; 3 | 4 | const flirting = async (m, Matrix) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | const validCommands = ['flirt']; 9 | 10 | if (validCommands.includes(cmd)) { 11 | try { 12 | const apiKey = 'shizo'; 13 | 14 | const response = await nodeFetch(`https://shizoapi.onrender.com/api/texts/flirt?apikey=${apiKey}`); 15 | if (!response.ok) { 16 | throw new Error(`Failed to fetch flirt message: ${await response.text()}`); 17 | } 18 | 19 | const json = await response.json(); 20 | const result = json.result; 21 | await Matrix.sendMessage(m.from, { text: result, mentions: [m.sender] }, { quoted: m }); 22 | } catch (error) { 23 | console.error('Error fetching flirt message:', error); 24 | await Matrix.sendMessage(m.from, { text: "Failed to retrieve flirt message. Please try again later." }); 25 | } 26 | } 27 | }; 28 | 29 | export default flirting; 30 | -------------------------------------------------------------------------------- /src/plugin/block.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const block = async (m, gss) => { 4 | try { 5 | const botNumber = await gss.decodeJid(gss.user.id); 6 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | const validCommands = ['block']; 12 | 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 16 | 17 | let users = m.mentionedJid[0] ? m.mentionedJid[0] : m.quoted ? m.quoted.sender : text.replace(/[^0-9]/g, '') + '@s.whatsapp.net'; 18 | 19 | await gss.updateBlockStatus(users, 'block') 20 | .then((res) => m.reply(`Blocked ${users.split('@')[0]} successfully.`)) 21 | .catch((err) => m.reply(`Failed to block user: ${err}`)); 22 | } catch (error) { 23 | console.error('Error:', error); 24 | m.reply('An error occurred while processing the command.'); 25 | } 26 | }; 27 | 28 | export default block; 29 | -------------------------------------------------------------------------------- /src/plugin/tomp3.js: -------------------------------------------------------------------------------- 1 | import { toAudio } from '../../lib/converter.cjs'; 2 | import config from '../../config.cjs'; 3 | 4 | const tomp3 = async (m, gss) => { 5 | try { 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['tomp3', 'mp3']; 11 | 12 | if (!validCommands.includes(cmd)) return; 13 | 14 | if (!m.quoted || m.quoted.mtype !== 'videoMessage') { 15 | return m.reply(`Send/Reply with Video to convert into MP3 with caption ${prefix + cmd}`); 16 | } 17 | 18 | m.reply('Converting to MP3, please wait...'); 19 | const media = await m.quoted.download(); 20 | const audio = await toAudio(media, 'mp4'); // Correctly importing toAudio function 21 | 22 | await gss.sendMessage(m.from, { document: audio, mimetype: 'audio/mpeg', fileName: `Converted By ${gss.user.name}.mp3` }, { quoted: m }); 23 | } catch (error) { 24 | console.error('Error:', error); 25 | m.reply('An error occurred while processing the command.'); 26 | } 27 | }; 28 | 29 | export default tomp3; 30 | -------------------------------------------------------------------------------- /src/plugin/unblock.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const unblock = async (m, gss) => { 4 | try { 5 | const botNumber = await gss.decodeJid(gss.user.id); 6 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | const validCommands = ['unblock']; 12 | 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 16 | 17 | let users = m.mentionedJid[0] ? m.mentionedJid[0] : m.quoted ? m.quoted.sender : text.replace(/[^0-9]/g, '') + '@s.whatsapp.net'; 18 | 19 | await gss.updateBlockStatus(users, 'unblock') 20 | .then((res) => m.reply(`Unblocked ${users.split('@')[0]} successfully.`)) 21 | .catch((err) => m.reply(`Failed to unblock user: ${err}`)); 22 | } catch (error) { 23 | console.error('Error:', error); 24 | m.reply('An error occurred while processing the command.'); 25 | } 26 | }; 27 | 28 | export default unblock; 29 | -------------------------------------------------------------------------------- /src/plugin/readqr.js: -------------------------------------------------------------------------------- 1 | import Jimp from 'jimp'; 2 | import jsQR from 'jsqr'; 3 | import jpeg from 'jpeg-js'; 4 | import config from '../../config.cjs'; 5 | 6 | const readqr = async (m, gss) => { 7 | try { 8 | const prefix = config.PREFIX; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | const text = m.body.slice(prefix.length + cmd.length).trim(); 11 | 12 | const validCommands = ['readqr']; 13 | 14 | if (!validCommands.includes(cmd)) return; 15 | 16 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 17 | return m.reply('Please quote an image containing a QR code with a caption.'); 18 | } 19 | 20 | const buffer = await m.quoted.download(); 21 | const image = await Jimp.read(buffer); 22 | const { data, width, height } = image.bitmap; 23 | 24 | const code = jsQR(data, width, height); 25 | 26 | if (!code) { 27 | return m.reply('QR code not found or could not be decoded.'); 28 | } 29 | 30 | m.reply(`Decoded QR code: ${code.data}`); 31 | } catch (error) { 32 | console.error('Error:', error); 33 | m.reply('An error occurred while processing the command.'); 34 | } 35 | }; 36 | 37 | export default readqr; 38 | -------------------------------------------------------------------------------- /src/plugin/waifu.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import config from '../../config.cjs'; 3 | 4 | const stickerCommandHandler = async (m, gss) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const stickerCommands = ['cry', 'kiss', 'kill', 'kick', 'hug', 'pat', 'lick', 'bite', 'yeet', 'bully', 'bonk', 'wink', 'poke', 'nom', 'slap', 'smile', 'wave', 'awoo', 'blush', 'smug', 'dance', 'happy', 'sad', 'cringe', 'cuddle', 'shinobu', 'handhold', 'glomp', 'highfive']; 10 | 11 | if (stickerCommands.includes(cmd)) { 12 | const packname = `𝐑𝐎𝐌𝐄𝐊 𝐗𝐃`; 13 | const author = ''; 14 | 15 | try { 16 | const { data } = await axios.get(`https://api.waifu.pics/sfw/${cmd}`); 17 | if (data && data.url) { 18 | gss.sendImageAsSticker(m.from, data.url, m, { packname, author }); 19 | } else { 20 | m.reply('Error fetching sticker.'); 21 | } 22 | } catch (error) { 23 | console.error('Error fetching sticker:', error); 24 | m.reply('Error fetching sticker.'); 25 | } 26 | } 27 | }; 28 | 29 | export default stickerCommandHandler; 30 | -------------------------------------------------------------------------------- /src/plugin/del.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const deleteMessage = async (m, gss) => { 4 | try { 5 | const botNumber = await gss.decodeJid(gss.user.id); 6 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | const validCommands = ['del', 'delete']; 12 | 13 | if (validCommands.includes(cmd)) { 14 | if (!isCreator) { 15 | return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 16 | } 17 | 18 | if (!m.quoted) { 19 | return m.reply('✳️ Reply to the message you want to delete'); 20 | } 21 | 22 | const key = { 23 | remoteJid: m.from, 24 | id: m.quoted.key.id, 25 | participant: m.quoted.key.participant || m.quoted.key.remoteJid 26 | }; 27 | 28 | await gss.sendMessage(m.from, { delete: key }); 29 | } 30 | } catch (error) { 31 | console.error('Error deleting message:', error); 32 | m.reply('An error occurred while trying to delete the message.'); 33 | } 34 | }; 35 | 36 | export default deleteMessage; 37 | -------------------------------------------------------------------------------- /src/plugin/linkgc.js: -------------------------------------------------------------------------------- 1 | import config from '../config.cjs'; 2 | 3 | const linkgc = async (m, gss) => { 4 | try { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const validCommands = ['linkgc', 'grouplink']; 10 | 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | if (!m.isGroup) { 14 | return m.reply('*📛 THIS COMMAND CAN ONLY BE USED IN GROUPS.*'); 15 | } 16 | const groupMetadata = await gss.groupMetadata(m.from); 17 | const botNumber = await gss.decodeJid(gss.user.id); 18 | const isBotAdmins = groupMetadata.participants.find(p => p.id === botNumber)?.admin; 19 | 20 | if (!isBotAdmins) { 21 | return m.reply('*📛 BOT MUST BE AN ADMIN TO USE THIS COMMAND.*'); 22 | } 23 | 24 | const response = await gss.groupInviteCode(m.from); 25 | await gss.sendMessage(m.from, { 26 | text: `https://chat.whatsapp.com/${response}\n\nGroup Link: ${groupMetadata.subject}`, 27 | detectLink: true 28 | }); 29 | 30 | } catch (error) { 31 | console.error('Error:', error); 32 | m.reply('An error occurred while processing the command.'); 33 | } 34 | }; 35 | 36 | export default linkgc; 37 | -------------------------------------------------------------------------------- /src/plugin/statusmsg.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | // Main command function 4 | const anticallCommand = async (m, Matrix) => { 5 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 6 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | // Only valid command is 'setstatusmsg' 12 | if (cmd === 'setstatusmsg') { 13 | if (!isCreator) return m.reply("*📛 THIS IS AN OWNER COMMAND*"); 14 | 15 | let responseMessage; 16 | 17 | if (text) { 18 | config.STATUS_READ_MSG = text; // Set custom reply message 19 | responseMessage = `Custom reply message has been set to: "${text}"`; 20 | } else { 21 | responseMessage = `Usage: *${prefix}setstatusmsg * to set a custom reply message.`; 22 | } 23 | 24 | try { 25 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 26 | } catch (error) { 27 | console.error("Error processing your request:", error); 28 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 29 | } 30 | } 31 | }; 32 | 33 | export default anticallCommand; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2024, Watsonxdboy 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /src/plugin/autoread.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const autoreadCommand = async (m, Matrix) => { 4 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 5 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | if (cmd === 'autoread') { 11 | if (!isCreator) return m.reply("*💓 THIS IS AN OWNER COMMAND*"); 12 | let responseMessage; 13 | 14 | if (text === 'on') { 15 | config.AUTO_READ = true; 16 | responseMessage = "Auto-Read has been enabled."; 17 | } else if (text === 'off') { 18 | config.AUTO_READ = false; 19 | responseMessage = "Auto-Read has been disabled."; 20 | } else { 21 | responseMessage = "Usage:\n- `autoread on`: Enable Auto-Read\n- `autoread off`: Disable Auto-Read"; 22 | } 23 | 24 | try { 25 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 26 | } catch (error) { 27 | console.error("Error processing your request:", error); 28 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 29 | } 30 | } 31 | }; 32 | 33 | export default autoreadCommand; 34 | -------------------------------------------------------------------------------- /src/plugin/autoblock.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const autoblockCommand = async (m, Matrix) => { 4 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 5 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | if (cmd === 'autoblock') { 11 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 12 | let responseMessage; 13 | 14 | if (text === 'on') { 15 | config.AUTO_BLOCK = true; 16 | responseMessage = "Auto-Block has been enabled."; 17 | } else if (text === 'off') { 18 | config.AUTO_BLOCK = false; 19 | responseMessage = "Auto-Block has been disabled."; 20 | } else { 21 | responseMessage = "Usage:\n- `autoblock on`: Enable Auto-Block\n- `autoblock off`: Disable Auto-Block"; 22 | } 23 | try { 24 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 25 | } catch (error) { 26 | console.error("Error processing your request:", error); 27 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 28 | } 29 | } 30 | }; 31 | 32 | export default autoblockCommand; 33 | -------------------------------------------------------------------------------- /src/plugin/autoreact.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const autoreadCommand = async (m, Matrix) => { 4 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 5 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | if (cmd === 'autoreact') { 11 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 12 | let responseMessage; 13 | 14 | if (text === 'on') { 15 | config.AUTO_REACT = true; 16 | responseMessage = "AUTO_REACT has been enabled."; 17 | } else if (text === 'off') { 18 | config.AUTO_REACT = false; 19 | responseMessage = "AUTO_REACT has been disabled."; 20 | } else { 21 | responseMessage = "Usage:\n- `autoreact on`: Enable Auto-React\n- `autoreact off`: Disable Auto-React"; 22 | } 23 | 24 | try { 25 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 26 | } catch (error) { 27 | console.error("Error processing your request:", error); 28 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 29 | } 30 | } 31 | }; 32 | 33 | export default autoreadCommand; 34 | -------------------------------------------------------------------------------- /src/plugin/take.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs-extra'; 2 | import config from '../../config.cjs'; 3 | 4 | const handleTakeCommand = async (m, gss) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | if (cmd !== 'take') return; 10 | 11 | // Split text into packname and author 12 | const args = text.split('|'); 13 | const [providedPackname, providedAuthor] = args; 14 | 15 | if (!providedPackname || !providedAuthor) { 16 | return m.reply('Usage: /take pkgname|author'); 17 | } 18 | 19 | global.packname = providedPackname; 20 | global.author = providedAuthor; 21 | 22 | const quoted = m.quoted || {}; 23 | 24 | if (!['imageMessage', 'videoMessage', 'stickerMessage'].includes(quoted.mtype)) { 25 | return m.reply(`Send/Reply with an image or video to use ${prefix + cmd}`); 26 | } 27 | 28 | try { 29 | const mediaBuffer = await quoted.download(); 30 | if (!mediaBuffer) throw new Error('Failed to download media.'); 31 | 32 | await gss.sendImageAsSticker(m.from, mediaBuffer, m, { packname: global.packname, author: global.author }); 33 | m.reply('Sticker created successfully!'); 34 | } catch (error) { 35 | m.reply(`Error: ${error.message}`); 36 | } 37 | }; 38 | 39 | export default handleTakeCommand; 40 | -------------------------------------------------------------------------------- /src/plugin/autotyping.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const autotypingCommand = async (m, Matrix) => { 4 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 5 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | if (cmd === 'autotyping') { 11 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 12 | let responseMessage; 13 | 14 | if (text === 'on') { 15 | config.AUTO_TYPING = true; 16 | responseMessage = "Auto-Typing has been enabled."; 17 | } else if (text === 'off') { 18 | config.AUTO_TYPING = false; 19 | responseMessage = "Auto-Typing has been disabled."; 20 | } else { 21 | responseMessage = "Usage:\n- `autotyping on`: Enable Auto-Typing\n- `autotyping off`: Disable Auto-Typing"; 22 | } 23 | 24 | try { 25 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 26 | } catch (error) { 27 | console.error("Error processing your request:", error); 28 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 29 | } 30 | } 31 | }; 32 | 33 | export default autotypingCommand; 34 | -------------------------------------------------------------------------------- /src/plugin/enhancer.js: -------------------------------------------------------------------------------- 1 | import { createRequire } from 'module'; 2 | import path from 'path'; 3 | 4 | const require = createRequire(import.meta.url); 5 | const __filename = new URL(import.meta.url).pathname; 6 | const __dirname = path.dirname(__filename); 7 | const reminiPath = path.resolve(__dirname, '../remini.cjs'); 8 | const { remini } = require(reminiPath); 9 | 10 | const tohd = async (m, gss) => { 11 | const prefixMatch = m.body.match(/^[\\/!#.]/); 12 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 13 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 14 | const validCommands = ['hdr2', 'hd2', 'remini2', 'enhance2', 'upscale2']; 15 | 16 | if (validCommands.includes(cmd)) { 17 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 18 | return m.reply(`*Send/Reply with an Image to Enhance Your Picture Quality ${prefix + cmd}*`); 19 | } 20 | 21 | const media = await m.quoted.download(); 22 | 23 | try { 24 | let proses = await remini(media, "enhance"); 25 | gss.sendMessage(m.from, { image: proses, caption: `> *Hey ${m.pushName} Here Is Your Enhanced Image*\n*ᴘᴏᴡᴇʀᴇᴅ ʙʏ ᴋʜᴀɴ-ᴍᴅ*` }, { quoted: m }); 26 | 27 | } catch (error) { 28 | console.error('Error processing media:', error); 29 | m.reply('Error processing media.'); 30 | } 31 | } 32 | }; 33 | 34 | export default tohd; 35 | -------------------------------------------------------------------------------- /src/plugin/Anticall.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | // Main command function 4 | const anticallcommand = async (m, Matrix) => { 5 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 6 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | if (cmd === 'anticall') { 12 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 13 | let responseMessage; 14 | 15 | if (text === 'on') { 16 | config.REJECT_CALL = true; 17 | responseMessage = "Anti-Call has been enabled."; 18 | } else if (text === 'off') { 19 | config.REJECT_CALL = false; 20 | responseMessage = "Anti-Call has been disabled."; 21 | } else { 22 | responseMessage = "Usage:\n- `anticall on`: Enable Anti-Call\n- `anticall off`: Disable Anti-Call"; 23 | } 24 | 25 | try { 26 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 27 | } catch (error) { 28 | console.error("Error processing your request:", error); 29 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 30 | } 31 | } 32 | }; 33 | 34 | export default anticallcommand; 35 | -------------------------------------------------------------------------------- /src/plugin/mode.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const modeCommand = async (m, Matrix) => { 4 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 5 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | 11 | if (cmd === 'mode') { 12 | if (!isCreator) { 13 | await Matrix.sendMessage(m.from, { text: "*❌ THIS IS AN OWNER COMMAND*" }, { quoted: m }); 14 | return; 15 | } 16 | 17 | if (['public', 'private'].includes(text)) { 18 | if (text === 'public') { 19 | Matrix.public = true; 20 | config.MODE = "public"; 21 | m.reply('Mode has been changed to public.'); 22 | } else if (text === 'private') { 23 | Matrix.public = false; 24 | config.MODE = "private"; 25 | m.reply('Mode has been changed to private.'); 26 | } else { 27 | m.reply("Usage:\n.Mode public/private"); 28 | } 29 | } else { 30 | m.reply("Invalid mode. Please use 'public' or 'private'."); 31 | } 32 | } 33 | }; 34 | 35 | export default modeCommand; 36 | -------------------------------------------------------------------------------- /src/plugin/alwaysonline.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const alwaysonlineCommand = async (m, Matrix) => { 4 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 5 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | if (cmd === 'alwaysonline') { 11 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 12 | let responseMessage; 13 | 14 | if (text === 'on') { 15 | config.ALWAYS_ONLINE = true; 16 | responseMessage = "Always Online has been enabled."; 17 | } else if (text === 'off') { 18 | config.ALWAYS_ONLINE = false; 19 | responseMessage = "Always Online has been disabled."; 20 | } else { 21 | responseMessage = "Usage:\n- `alwaysonline on`: Enable Always Online\n- `alwaysonline off`: Disable Always Online"; 22 | } 23 | 24 | try { 25 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 26 | } catch (error) { 27 | console.error("Error processing your request:", error); 28 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 29 | } 30 | } 31 | }; 32 | 33 | export default alwaysonlineCommand; 34 | -------------------------------------------------------------------------------- /src/plugin/setgroupname.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const setGroupName = async (m, gss) => { 4 | try { 5 | const botNumber = await gss.decodeJid(gss.user.id); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['setgroupname', 'setname']; 11 | 12 | if (!validCommands.includes(cmd)) return; 13 | 14 | if (!m.isGroup) return m.reply("*❌ THIS COMMAND CAN ONLY BE USED IN GROUPS*"); 15 | const groupMetadata = await gss.groupMetadata(m.from); 16 | const participants = groupMetadata.participants; 17 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 18 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 19 | 20 | if (!botAdmin) return m.reply("*❌ BOT MUST BE AN ADMIN TO USE THIS COMMAND*"); 21 | if (!senderAdmin) return m.reply("*❌ YOU MUST BE AN ADMIN TO USE THIS COMMAND*"); 22 | 23 | if (!text) return m.reply("*❌ PLEASE PROVIDE A NAME TO SET*"); 24 | 25 | await gss.groupUpdateSubject(m.from, text); 26 | m.reply(`Group Name Has Been Set To: ${text}`); 27 | } catch (error) { 28 | console.error('Error:', error); 29 | m.reply('An error occurred while processing the command.'); 30 | } 31 | }; 32 | 33 | export default setGroupName; 34 | -------------------------------------------------------------------------------- /src/plugin/autorecording.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const autorecordingCommand = async (m, Matrix) => { 4 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 5 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | if (cmd === 'autorecording') { 11 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 12 | let responseMessage; 13 | 14 | if (text === 'on') { 15 | config.AUTO_RECORDING = true; 16 | responseMessage = "Auto-Recording has been enabled."; 17 | } else if (text === 'off') { 18 | config.AUTO_RECORDING = false; 19 | responseMessage = "Auto-Recording has been disabled."; 20 | } else { 21 | responseMessage = "Usage:\n- `autorecording on`: Enable Auto-Recording\n- `autorecording off`: Disable Auto-Recording"; 22 | } 23 | 24 | try { 25 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 26 | } catch (error) { 27 | console.error("Error processing your request:", error); 28 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 29 | } 30 | } 31 | }; 32 | 33 | export default autorecordingCommand; 34 | -------------------------------------------------------------------------------- /src/plugin/setdesc.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const setDescription = async (m, gss) => { 4 | try { 5 | const botNumber = await gss.decodeJid(gss.user.id); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['setdescription', 'setdesc', 'setgroupbio']; 11 | 12 | if (!validCommands.includes(cmd)) return; 13 | 14 | if (!m.isGroup) return m.reply("*❌ THIS COMMAND CAN ONLY BE USED IN GROUPS*"); 15 | const groupMetadata = await gss.groupMetadata(m.from); 16 | const participants = groupMetadata.participants; 17 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 18 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 19 | 20 | if (!botAdmin) return m.reply("*❌ BOT MUST BE AN ADMIN TO USE THIS COMMAND*"); 21 | if (!senderAdmin) return m.reply("*❌ YOU MUST BE AN ADMIN TO USE THIS COMMAND*"); 22 | 23 | if (!text) return m.reply("*❌ PLEASE PROVIDE A DESCRIPTION TO SET*"); 24 | 25 | await gss.groupUpdateDescription(m.from, text); 26 | m.reply(`Group Description Has Been Set To: ${text}`); 27 | } catch (error) { 28 | console.error('Error:', error); 29 | m.reply('An error occurred while processing the command.'); 30 | } 31 | }; 32 | 33 | export default setDescription; 34 | -------------------------------------------------------------------------------- /src/plugin/statusreply.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | // Main command function 4 | const anticallCommand = async (m, Matrix) => { 5 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 6 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | const validCommands = ['autostatusreply']; 12 | 13 | if (validCommands.includes(cmd)){ 14 | if (!isCreator) return m.reply("*📛 THIS IS AN OWNER COMMAND*"); 15 | let responseMessage; 16 | 17 | if (text === 'on') { 18 | config.AUTO_STATUS_REPLY = true; 19 | responseMessage = "AUTO STATUS REPLY has been enabled."; 20 | } else if (text === 'off') { 21 | config.AUTO_STATUS_REPLY = false; 22 | responseMessage = "AUTO STATUS REPLY has been disabled."; 23 | } else { 24 | responseMessage = `Usage:\n- *${prefix + cmd} ON:* Enable AUTO STATUS REPLY\n- *${prefix + cmd} off:* Disable AUTO STATUS REPLY`; 25 | } 26 | 27 | try { 28 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 29 | } catch (error) { 30 | console.error("Error processing your request:", error); 31 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 32 | } 33 | } 34 | }; 35 | 36 | export default anticallCommand; 37 | -------------------------------------------------------------------------------- /src/plugin/autos.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | // Main command function 4 | const anticallCommand = async (m, Matrix) => { 5 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 6 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | const validCommands = ['autostatus', 'autosview', 'autostatusview']; 12 | 13 | if (validCommands.includes(cmd)){ 14 | if (!isCreator) return m.reply("*❌ THIS IS AN OWNER COMMAND*"); 15 | let responseMessage; 16 | 17 | if (text === 'on') { 18 | config.AUTO_STATUS_SEEN = true; 19 | responseMessage = "AUTO STATUS SEEN has been enabled."; 20 | } else if (text === 'off') { 21 | config.AUTO_STATUS_SEEN = false; 22 | responseMessage = "AUTO STATUS SEEN has been disabled."; 23 | } else { 24 | responseMessage = `Usage:\n- *${prefix + cmd} ON:* Enable AUTO STATUS VIEW\n- *${prefix + cmd} off:* Disable AUTO STATUS SEEN`; 25 | } 26 | 27 | try { 28 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 29 | } catch (error) { 30 | console.error("Error processing your request:", error); 31 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 32 | } 33 | } 34 | }; 35 | 36 | export default anticallCommand; 37 | -------------------------------------------------------------------------------- /src/plugin/report.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const report = async (m, gss) => { 4 | const reportedMessages = {}; 5 | const devlopernumber = '919341378016'; 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['bug', 'report', 'request']; 11 | 12 | if (validCommands.includes(cmd)) { 13 | 14 | if (!text) return m.reply(`Example: ${prefix + cmd} hi dev play command is not working`); 15 | 16 | const messageId = m.key.id; 17 | 18 | if (reportedMessages[messageId]) { 19 | return m.reply("This report has already been forwarded to the owner. Please wait for a response."); 20 | } 21 | 22 | reportedMessages[messageId] = true; 23 | 24 | const textt = `*| REQUEST/BUG |*`; 25 | const teks1 = `\n\n*User*: @${m.sender.split("@")[0]}\n*Request/Bug*: ${text}`; 26 | const teks2 = `\n\n*Hi ${m.pushName}, your request has been forwarded to my Owners.*\n*Please wait...*`; 27 | 28 | // Send the message to the first owner in the `owner` array 29 | gss.sendMessage(devlopernumber + "@s.whatsapp.net", { 30 | text: textt + teks1, 31 | mentions: [m.sender], 32 | }, { 33 | quoted: m, 34 | }); 35 | 36 | // Send a reply to the user 37 | m.reply("Tʜᴀɴᴋ ʏᴏᴜ ꜰᴏʀ ʏᴏᴜʀ ʀᴇᴘᴏʀᴛ. Iᴛ ʜᴀs ʙᴇᴇɴ ꜰᴏʀᴡᴀʀᴅᴇᴅ ᴛᴏ ᴛʜᴇ ᴏᴡɴᴇʀ. Pʟᴇᴀsᴇ ᴡᴀɪᴛ ꜰᴏʀ ᴀ ʀᴇsᴘᴏɴsᴇ."); 38 | } 39 | }; 40 | 41 | export default report; -------------------------------------------------------------------------------- /src/plugin/emojimix.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | import fs from 'fs'; 3 | import config from '../../config.cjs'; 4 | 5 | const emojimix = async (m, Matrix) => { 6 | try { 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | const validCommands = ['emojimix', 'emix']; 12 | if (!validCommands.includes(cmd)) return; 13 | 14 | let [emoji1, emoji2] = text.split('+'); 15 | if (!emoji1 || !emoji2) { 16 | return m.reply(`Example: ${prefix + cmd} 😅+🤔`); 17 | } 18 | 19 | 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)}`; 20 | const response = await fetch(url); 21 | const anu = await response.json(); 22 | 23 | if (!anu.results || anu.results.length === 0) { 24 | return m.reply('No emoji mix found for the provided emojis.'); 25 | } 26 | 27 | for (let res of anu.results) { 28 | const encmedia = await Matrix.sendImageAsSticker(m.from, res.url, m, { packname: "", author: "ROMEK-XD", categories: res.tags }); 29 | await fs.unlinkSync(encmedia); 30 | } 31 | } catch (error) { 32 | console.error('Error:', error); 33 | m.reply('An error occurred while processing the command.'); 34 | } 35 | }; 36 | 37 | export default emojimix; 38 | -------------------------------------------------------------------------------- /src/plugin/gdrive.js: -------------------------------------------------------------------------------- 1 | import pkg from "nayan-media-downloader"; 2 | const { GDLink } = pkg; 3 | import config from '../../config.cjs'; 4 | 5 | const gdriveDownload = async (m, Matrix) => { 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['gdrive', 'gd', 'gddownload']; 11 | 12 | if (validCommands.includes(cmd)) { 13 | if (!text) return m.reply('Please provide a Google Drive URL.'); 14 | 15 | try { 16 | await m.React('🔜'); 17 | 18 | const gdriveUrl = text; 19 | const gdriveInfo = await GDLink(gdriveUrl); 20 | 21 | if (gdriveInfo && gdriveInfo.status && gdriveInfo.data) { 22 | const mediaUrl = gdriveInfo.data; 23 | const caption = `©𝐏𝐎𝐖𝐄𝐑𝐄𝐃 𝐁𝐘 𝐑𝐎𝐌𝐄𝐊 𝐗𝐃`; 24 | 25 | // Inferring the file type based on the file extension 26 | const extension = mediaUrl.split('.').pop().toLowerCase(); 27 | 28 | // Send the media using Matrix.sendMedia 29 | await Matrix.sendMedia(m.from, mediaUrl, extension, caption, m); 30 | 31 | await m.React('✅'); 32 | } else { 33 | throw new Error('Invalid response from Google Drive.'); 34 | } 35 | } catch (error) { 36 | console.error('Error downloading Google Drive file:', error.message); 37 | m.reply('Error downloading Google Drive file.'); 38 | await m.React('❌'); 39 | } 40 | } 41 | }; 42 | 43 | export default gdriveDownload; 44 | -------------------------------------------------------------------------------- /src/plugin/pinterestdl.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import config from '../../config.cjs'; 3 | 4 | const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); 5 | 6 | const imageCommand = async (m, sock) => { 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const arg = m.body.slice(prefix.length + cmd.length).trim(); 10 | const query = args; 11 | 12 | const validCommands = ['pintrest', 'pintrestdl']; 13 | 14 | if (validCommands.includes(cmd)) { 15 | if (!query) { 16 | return sock.sendMessage(m.from, { text: `Usage: ${prefix + cmd} naruto` }); 17 | } 18 | 19 | try { 20 | await m.React("📥"); 21 | const response = await axios.get(`https://pinteresimage.nepcoderdevs.workers.dev/?query=${encodeURIComponent(query)}&limit=5`); 22 | const results = response.data.results; 23 | 24 | if (results.length === 0) { 25 | return sock.sendMessage(m.from, { text: 'No images found for your search query.' }); 26 | } 27 | 28 | for (const result of results) { 29 | await sleep(500); 30 | const imageUrl = result.imageUrl; 31 | const response = await axios.get(imageUrl, { responseType: 'arraybuffer' }); 32 | const imageBuffer = Buffer.from(response.data, 'binary'); 33 | 34 | await sock.sendMessage(m.from, { image: imageBuffer, caption: result.title }, { quoted: m }); 35 | await m.React("✅"); 36 | } 37 | } catch (error) { 38 | console.error("Error fetching images:", error); 39 | await sock.sendMessage(m.from, { text: 'Error fetching images.' }); 40 | } 41 | } 42 | }; 43 | 44 | export default imageCommand; 45 | -------------------------------------------------------------------------------- /src/plugin/tagall.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const tagAll = async (m, gss) => { 4 | try { 5 | // Ensure the function is async 6 | const botNumber = await gss.decodeJid(gss.user.id); 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | // Check for the valid command 12 | const validCommands = ['tagall']; 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | 16 | const groupMetadata = await gss.groupMetadata(m.from); 17 | const participants = groupMetadata.participants; 18 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 19 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 20 | 21 | if (!m.isGroup) return m.reply("*❌ THIS COMMAND CAN ONLY BE USED IN GROUPS*"); 22 | 23 | if (!botAdmin) return m.reply("❌ BOT MUST BE AN ADMIN TO USE THIS COMMAND*"); 24 | if (!senderAdmin) return m.reply("*❌ YOU MUST BE AN ADMIN TO USE THIS COMMAND*"); 25 | // Extract the message to be sent 26 | let message = `乂 *Attention Everyone* 乂\n\n*Message:* ${m.body.slice(prefix.length + cmd.length).trim() || 'no message'}\n\n`; 27 | 28 | 29 | 30 | for (let participant of participants) { 31 | message += `❒ @${participant.id.split('@')[0]}\n`; 32 | } 33 | 34 | await gss.sendMessage(m.from, { text: message, mentions: participants.map(a => a.id) }, { quoted: m }); 35 | } catch (error) { 36 | console.error('Error:', error); 37 | await m.reply('An error occurred while processing the command.'); 38 | } 39 | }; 40 | 41 | export default tagAll; 42 | -------------------------------------------------------------------------------- /src/plugin/cal.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const report = async (m, gss) => { 4 | try { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const validCommands = ['cal', 'calculater', 'calc']; 10 | 11 | if (validCommands.includes(cmd)) { 12 | let id = m.from; 13 | gss.math = gss.math ? gss.math : {}; 14 | 15 | if (id in gss.math) { 16 | clearTimeout(gss.math[id][3]); 17 | delete gss.math[id]; 18 | return m.reply('...'); 19 | } 20 | 21 | let val = text 22 | .replace(/[^0-9\-\/+*×÷πEe()piPI.]/g, '') // Allow decimal point '.' 23 | .replace(/×/g, '*') 24 | .replace(/÷/g, '/') 25 | .replace(/π|pi/gi, 'Math.PI') 26 | .replace(/e/gi, 'Math.E') 27 | .replace(/\/+/g, '/') 28 | .replace(/\++/g, '+') 29 | .replace(/-+/g, '-'); 30 | 31 | let format = val 32 | .replace(/Math\.PI/g, 'π') 33 | .replace(/Math\.E/g, 'e') 34 | .replace(/\//g, '÷') 35 | .replace(/\*/g, '×'); 36 | 37 | let result = (new Function('return ' + val))(); 38 | 39 | if (isNaN(result)) throw new Error('example: 17+19'); 40 | 41 | m.reply(`*${format}* = _${result}_`); 42 | } 43 | } catch (error) { 44 | // Handle specific error messages 45 | if (error instanceof SyntaxError) { 46 | return m.reply('Invalid syntax. Please check your expression.'); 47 | } else if (error instanceof Error) { 48 | return m.reply(error.message); 49 | } else { 50 | } 51 | } 52 | }; 53 | 54 | export default report; 55 | -------------------------------------------------------------------------------- /src/plugin/join.js: -------------------------------------------------------------------------------- 1 | import config from '../config.cjs'; 2 | 3 | const joinGroup = async (m, gss) => { 4 | try { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) 7 | ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() 8 | : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | const args = text.split(' '); 11 | 12 | const validCommands = ['join']; 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | const botNumber = await gss.decodeJid(gss.user.id); 16 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 17 | 18 | if (!isCreator) { 19 | return m.reply("🚫 *Only the bot owner can use this command.*"); 20 | } 21 | 22 | if (!text) return m.reply("📛 *Please provide a valid WhatsApp group invite link.*"); 23 | if (!isValidUrl(args[0]) || !args[0].includes('whatsapp.com')) { 24 | return m.reply("❌ *Invalid group link. Please check and try again.*"); 25 | } 26 | 27 | await m.reply("⏳ *Joining the group, please wait...*"); 28 | 29 | const inviteCode = args[0].split("https://chat.whatsapp.com/")[1]; 30 | 31 | await gss.groupAcceptInvite(inviteCode) 32 | .then(res => m.reply(`✅ *Successfully joined the group!*\n\n_ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ_`)) 33 | .catch(err => m.reply(`❌ *Failed to join the group.*\nError: ${err.message || err}`)); 34 | 35 | } catch (error) { 36 | console.error("Join Group Error:", error); 37 | m.reply("❌ *An error occurred while processing the command.*"); 38 | } 39 | }; 40 | 41 | const isValidUrl = (url) => { 42 | try { 43 | new URL(url); 44 | return true; 45 | } catch (e) { 46 | return false; 47 | } 48 | }; 49 | 50 | export default joinGroup; -------------------------------------------------------------------------------- /src/plugin/welcome.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const gcEvent = async (m, Matrix) => { 4 | const prefix = config.PREFIX; 5 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 6 | const text = m.body.slice(prefix.length + cmd.length).trim(); 7 | 8 | if (cmd === 'welcome') { 9 | if (!m.isGroup) return m.reply("*❌ THIS COMMAND CAN ONLY BE USED IN GROUPS*"); 10 | const groupMetadata = await Matrix.groupMetadata(m.from); 11 | const participants = groupMetadata.participants; 12 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 13 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 14 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 15 | 16 | if (!botAdmin) return m.reply("*❌ BOT MUST BE AN ADMIN TO USE THIS COMMAND*"); 17 | if (!senderAdmin) return m.reply("*❌ YOU MUST BE AN ADMIN TO USE THIS COMMAND*"); 18 | let responseMessage; 19 | 20 | if (text === 'on') { 21 | config.WELCOME = true; 22 | responseMessage = "WELCOME & LEFT message has been enabled."; 23 | } else if (text === 'off') { 24 | config.WELCOME = false; 25 | responseMessage = "WELCOME & LEFT message has been disabled."; 26 | } else { 27 | responseMessage = "Usage:\n- `WELCOME on`: Enable WELCOME & LEFT message\n- `WELCOME off`: Disable WELCOME & LEFT message"; 28 | } 29 | 30 | try { 31 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 32 | } catch (error) { 33 | console.error("Error processing your request:", error); 34 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 35 | } 36 | } 37 | }; 38 | 39 | export default gcEvent; 40 | -------------------------------------------------------------------------------- /src/plugin/fetch.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | import config from '../config.cjs'; 3 | 4 | const fetchData = async (m, Matrix) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const validCommands = ['fetch', 'get', 'api']; 10 | 11 | if (validCommands.includes(cmd)) { 12 | if (!/^https?:\/\//.test(text)) return m.reply('Start the *URL* with http:// or https://'); 13 | 14 | try { 15 | const _url = new URL(text); 16 | const url = `${_url.origin}${_url.pathname}?${_url.searchParams.toString()}`; 17 | const res = await fetch(url); 18 | 19 | const contentLength = res.headers.get('content-length'); 20 | if (contentLength && contentLength > 100 * 1024 * 1024 * 1024) { 21 | return m.reply(`Content-Length exceeds the limit: ${contentLength}`); 22 | } 23 | 24 | const contentType = res.headers.get('content-type'); 25 | if (!/text|json/.test(contentType)) { 26 | await Matrix.sendMedia(m.from, url, 'file', '> Api Fetched From ROMEK-XD', m); 27 | return; 28 | } 29 | 30 | let content = Buffer.from(await res.arrayBuffer()); 31 | 32 | try { 33 | console.log('Parsed JSON:', JSON.parse(content)); 34 | content = JSON.stringify(JSON.parse(content)); 35 | } catch (e) { 36 | console.error('Error parsing JSON:', e); 37 | content = content.toString(); 38 | } finally { 39 | m.reply(content.slice(0, 65536)); 40 | } 41 | } catch (error) { 42 | console.error('Error fetching data:', error.message); 43 | m.reply('Error fetching data.'); 44 | } 45 | } 46 | }; 47 | 48 | export default fetchData; 49 | -------------------------------------------------------------------------------- /src/plugin/gemini.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { GoogleGenerativeAI } from '@google/generative-ai'; 3 | import config from '../config.cjs'; 4 | 5 | const geminiResponse = async (m, Matrix) => { 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const apiKey = config.GEMINI_KEY; 11 | const genAI = new GoogleGenerativeAI(apiKey); 12 | const validCommands = ['gemini', 'vision']; 13 | 14 | if (validCommands.includes(cmd)) { 15 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 16 | return m.reply(`⚠️ *Send/Reply with an Image to use* \`${prefix + cmd}\``); 17 | } 18 | 19 | await m.reply("⏳ *Processing with Gemini Vision AI...*"); 20 | 21 | try { 22 | const prompt = text; 23 | const media = await m.quoted.download(); 24 | 25 | const imagePart = { 26 | inlineData: { 27 | data: Buffer.from(media).toString("base64"), 28 | mimeType: "image/png", 29 | }, 30 | }; 31 | 32 | const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash-latest" }); 33 | const result = await model.generateContent([prompt, imagePart]); 34 | const response = result.response; 35 | 36 | const textResponse = await response.text(); 37 | 38 | return m.reply( 39 | `┌─〔 *GEMINI VISION RESULT* 〕─◉\n\n${textResponse.trim()}\n\n📥 ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ` 40 | ); 41 | 42 | } catch (error) { 43 | console.error('Error in Gemini Pro Vision:', error); 44 | await m.React("❌"); 45 | return m.reply(`❌ *An error occurred while generating response:*\n${error.message}`); 46 | } 47 | } 48 | }; 49 | 50 | export default geminiResponse; -------------------------------------------------------------------------------- /src/plugin/qrgenerater.js: -------------------------------------------------------------------------------- 1 | import qrcode from 'qrcode'; 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | import PDFDocument from 'pdfkit'; 5 | import config from '../../config.cjs'; 6 | 7 | const toqr = async (m, gss) => { 8 | try { 9 | const botNumber = await gss.decodeJid(gss.user.id); 10 | const prefix = config.PREFIX; 11 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 12 | const text = m.body.slice(prefix.length + cmd.length).trim(); 13 | 14 | const validCommands = ['toqr']; 15 | 16 | if (!validCommands.includes(cmd)) return; 17 | 18 | if (!text) { 19 | return m.reply('Please include link or text!'); 20 | } 21 | 22 | let qyuer = await qrcode.toDataURL(text, { scale: 8 }); 23 | let data = Buffer.from(qyuer.replace('data:image/png;base64,', ''), 'base64'); 24 | 25 | // Create a PDF document 26 | const pdfPath = path.join('./', `${Date.now()}.pdf`); 27 | const doc = new PDFDocument(); 28 | const writeStream = fs.createWriteStream(pdfPath); 29 | doc.pipe(writeStream); 30 | 31 | // Draw the QR code on the PDF 32 | doc.image(data, { 33 | fit: [500, 500], 34 | align: 'center', 35 | valign: 'center', 36 | }); 37 | 38 | doc.end(); 39 | 40 | writeStream.on('finish', async () => { 41 | const medi = fs.readFileSync(pdfPath); 42 | 43 | await gss.sendMessage(m.from, { 44 | document: medi, 45 | mimetype: 'application/pdf', 46 | fileName: 'QRCode.pdf', 47 | }, { 48 | quoted: m 49 | }); 50 | 51 | fs.unlinkSync(pdfPath); 52 | }); 53 | } catch (error) { 54 | console.error('Error:', error); 55 | m.reply('An error occurred while generating the QR code.'); 56 | } 57 | }; 58 | 59 | export default toqr; 60 | -------------------------------------------------------------------------------- /config.cjs: -------------------------------------------------------------------------------- 1 | // config.js 2 | const fs = require("fs"); 3 | require("dotenv").config(); 4 | 5 | const config = { 6 | SESSION_ID: process.env.SESSION_ID || "Your Session Id", 7 | PREFIX: process.env.PREFIX || '.', 8 | AUTO_STATUS_SEEN: process.env.AUTO_STATUS_SEEN !== undefined ? process.env.AUTO_STATUS_SEEN === 'true' : true, 9 | AUTO_STATUS_REPLY: process.env.AUTO_STATUS_REPLY !== undefined ? process.env.AUTO_STATUS_REPLY === 'true' : true, 10 | STATUS_READ_MSG: process.env.STATUS_READ_MSG || '', 11 | AUTO_DL: process.env.AUTO_DL !== undefined ? process.env.AUTO_DL === 'true' : false, 12 | AUTO_READ: process.env.AUTO_READ !== undefined ? process.env.AUTO_READ === 'true' : false, 13 | AUTO_TYPING: process.env.AUTO_TYPING !== undefined ? process.env.AUTO_TYPING === 'true' : false, 14 | AUTO_RECORDING: process.env.AUTO_RECORDING !== undefined ? process.env.AUTO_RECORDING === 'true' : false, 15 | ALWAYS_ONLINE: process.env.ALWAYS_ONLINE !== undefined ? process.env.ALWAYS_ONLINE === 'true' : false, 16 | AUTO_REACT: process.env.AUTO_REACT !== undefined ? process.env.AUTO_REACT === 'true' : false, 17 | /*auto block only for 212 */ 18 | AUTO_BLOCK: process.env.AUTO_BLOCK !== undefined ? process.env.AUTO_BLOCK === 'true' : true, 19 | 20 | 21 | REJECT_CALL: process.env.REJECT_CALL !== undefined ? process.env.REJECT_CALL === 'true' : false, 22 | NOT_ALLOW: process.env.NOT_ALLOW !== undefined ? process.env.NOT_ALLOW === 'true' : true, 23 | MODE: process.env.MODE || "public", 24 | OWNER_NAME: process.env.OWNER_NAME || "✪⏤͟͞★⃝ꪶ‎𝐑𝐎𝐌𝐄𝐊-𝐗𝐃𖥘✪͜͡➺", 25 | OWNER_NUMBER: process.env.OWNER_NUMBER || "919341378016", 26 | GEMINI_KEY: process.env.GEMINI_KEY || "AIzaSyCUPaxfIdZawsKZKqCqJcC-GWiQPCXKTDc", 27 | WELCOME: process.env.WELCOME !== undefined ? process.env.WELCOME === 'true' : false, 28 | }; 29 | 30 | 31 | module.exports = config; 32 | -------------------------------------------------------------------------------- /src/plugin/insta.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | import { igdl } from "ruhend-scraper"; 3 | 4 | const instagramDownloader = async (m, bot) => { 5 | const prefixMatch = m.body.match(/^[\\/!#.]/); 6 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const validCommands = ['instagram', 'igdl', 'ig', 'insta']; 9 | 10 | if (validCommands.includes(cmd)) { 11 | const args = m.body.split(' ').slice(1); 12 | const url = args[0]; 13 | 14 | // Validate URL 15 | if (!url || !url.includes('https://www.instagram.com/')) { 16 | return m.reply(`Please provide a valid public Instagram video link!`); 17 | } 18 | 19 | try { 20 | await bot.sendMessage(m.from, { text: "ROMEK-XD LOADING YOUR IG VIDEO..." }, { quoted: m }); 21 | 22 | // Fetch Instagram video data using igdl 23 | const downloadData = await igdl(url); 24 | 25 | if (downloadData && downloadData.data && downloadData.data.length > 0) { 26 | const videos = downloadData.data.slice(0, 20); // Limit to first 20 videos 27 | 28 | for (const video of videos) { 29 | if (video?.url) { 30 | const caption = `Instagram Video Downloaded by TOJI MD`; 31 | 32 | await bot.sendMessage(m.from, { 33 | video: { url: video.url }, 34 | caption, 35 | }, { quoted: m }); 36 | } 37 | } 38 | } else { 39 | throw new Error('No video found at the provided Instagram link.'); 40 | } 41 | } catch (error) { 42 | console.error("Error fetching Instagram video:", error); 43 | m.reply('TOJI SAYS: 💀 An error occurred while fetching the video. Please try again later.'); 44 | } 45 | } 46 | }; 47 | 48 | export default instagramDownloader; 49 | -------------------------------------------------------------------------------- /src/plugin/play.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import yts from "yt-search"; 3 | import config from '../config.cjs'; 4 | 5 | const play = async (m, gss) => { 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(" ")[0].toLowerCase() : ""; 8 | const args = m.body.slice(prefix.length + cmd.length).trim().split(" "); 9 | 10 | if (cmd === "play") { 11 | if (args.length === 0 || !args.join(" ")) { 12 | return m.reply("*Please provide a song name or keywords to search for.*"); 13 | } 14 | 15 | const searchQuery = args.join(" "); 16 | m.reply("*🎧 Searching for the song...*"); 17 | 18 | try { 19 | const searchResults = await yts(searchQuery); 20 | if (!searchResults.videos || searchResults.videos.length === 0) { 21 | return m.reply(`❌ No results found for "${searchQuery}".`); 22 | } 23 | 24 | const firstResult = searchResults.videos[0]; 25 | const videoUrl = firstResult.url; 26 | 27 | // First API endpoint 28 | const apiUrl = `https://api.davidcyriltech.my.id/download/ytmp3?url=${videoUrl}`; 29 | const response = await axios.get(apiUrl); 30 | 31 | if (!response.data.success) { 32 | return m.reply(`❌ Failed to fetch audio for "${searchQuery}".`); 33 | } 34 | 35 | const { title, download_url } = response.data.result; 36 | 37 | // Send the audio file 38 | await gss.sendMessage( 39 | m.from, 40 | { 41 | audio: { url: download_url }, 42 | mimetype: "audio/mp4", 43 | ptt: false, 44 | }, 45 | { quoted: m } 46 | ); 47 | 48 | m.reply(`✅ *${title}* has been downloaded successfully!`); 49 | } catch (error) { 50 | console.error(error); 51 | m.reply("❌ An error occurred while processing your request."); 52 | } 53 | } 54 | }; 55 | 56 | export default play; 57 | -------------------------------------------------------------------------------- /src/generateProfilePicture.js: -------------------------------------------------------------------------------- 1 | import Jimp from 'jimp'; 2 | import fs from 'fs/promises'; // Using promises for async/await compatibility 3 | import path from 'path'; // To handle file paths 4 | 5 | const __filename = new URL(import.meta.url).pathname; 6 | const __dirname = path.dirname(__filename); 7 | 8 | const generateProfilePictureWithWatermark = async (buffer) => { 9 | try { 10 | const jimp = await Jimp.read(buffer); 11 | const min = jimp.getWidth(); 12 | const max = jimp.getHeight(); 13 | const cropped = jimp.crop(0, 0, min, max); 14 | 15 | // Ensure the watermark path is correct 16 | const watermarkPath = path.resolve(__dirname, 'watermark.png'); 17 | 18 | // Check if watermark file exists 19 | try { 20 | await fs.access(watermarkPath); 21 | } catch (error) { 22 | throw new Error(`Watermark file not found at ${watermarkPath}`); 23 | } 24 | 25 | const watermarkBuffer = await fs.readFile(watermarkPath); 26 | const watermark = await Jimp.read(watermarkBuffer); 27 | 28 | // Resize the watermark to a larger size 29 | watermark.scaleToFit(200, 200); // Increase the size here 30 | 31 | // Calculate the position to place the watermark (bottom left corner) 32 | const x = 10; 33 | const y = cropped.bitmap.height - watermark.bitmap.height - 10; 34 | 35 | // Composite the watermark onto the profile picture 36 | cropped.composite(watermark, x, y); 37 | 38 | // Scale the profile picture to fit within 720x720 39 | const scaledImg = await cropped.scaleToFit(720, 720).getBufferAsync(Jimp.MIME_JPEG); 40 | 41 | return { 42 | img: scaledImg, 43 | preview: scaledImg, // Assuming the preview is the same as the profile picture 44 | }; 45 | } catch (error) { 46 | console.error('Error generating profile picture with watermark:', error); 47 | throw error; 48 | } 49 | }; 50 | 51 | export default generateProfilePictureWithWatermark; 52 | -------------------------------------------------------------------------------- /src/plugin/hd.js: -------------------------------------------------------------------------------- 1 | import { createRequire } from 'module'; 2 | import path from 'path'; 3 | 4 | // Setup for CommonJS require in ES modules 5 | const require = createRequire(import.meta.url); 6 | const __filename = new URL(import.meta.url).pathname; 7 | const __dirname = path.dirname(__filename); 8 | const reminiPath = path.resolve(__dirname, '../media/remini.cjs'); 9 | const { remini } = require(reminiPath); 10 | 11 | // Enhance Image Function 12 | const tohd = async (m, gss) => { 13 | // Prefix detection 14 | const prefixMatch = m.body.match(/^[\\/!#.]/); 15 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 16 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 17 | const validCommands = ['hdr2', 'hd2', 'remini2', 'enhance2', 'upscale2']; 18 | 19 | // Command validation 20 | if (validCommands.includes(cmd)) { 21 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 22 | return m.reply(`✨ *Send/Reply with an Image to Enhance Quality* ✨\nUsage: *${prefix + cmd}*`); 23 | } 24 | 25 | // Download the quoted image 26 | const media = await m.quoted.download(); 27 | 28 | try { 29 | // Process the image with Remini 30 | const enhancedImage = await remini(media, 'enhance'); 31 | 32 | // Send the enhanced image with a stylish caption 33 | await gss.sendMessage( 34 | m.from, 35 | { 36 | image: enhancedImage, 37 | caption: `🌟 *Hey ${m.pushName}, Here’s Your Enhanced Image!* 🌟\n*ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ*`, 38 | }, 39 | { quoted: m } 40 | ); 41 | } catch (error) { 42 | console.error('✖ Error processing media:', error); 43 | await m.reply('❌ *Oops! Error enhancing the image.*'); 44 | } 45 | } 46 | }; 47 | 48 | export default tohd; -------------------------------------------------------------------------------- /src/plugin/status.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import config from '../../config.cjs'; 3 | 4 | const handleGreeting = async (m, gss) => { 5 | try { 6 | const textLower = m.body.toLowerCase(); 7 | 8 | const triggerWords = [ 9 | 'send', 'statusdown', 'take', 'sent', 'giv', 'gib', 'upload', 10 | 'send me', 'sent me', 'znt', 'snt', 'ayak', 'do', 'mee' 11 | ]; 12 | 13 | if (triggerWords.includes(textLower)) { 14 | if (m.message && m.message.extendedTextMessage && m.message.extendedTextMessage.contextInfo) { 15 | const quotedMessage = m.message.extendedTextMessage.contextInfo.quotedMessage; 16 | 17 | if (quotedMessage) { 18 | // Check if it's an image 19 | if (quotedMessage.imageMessage) { 20 | const imageCaption = quotedMessage.imageMessage.caption; 21 | const imageUrl = await gss.downloadAndSaveMediaMessage(quotedMessage.imageMessage); 22 | await gss.sendMessage(m.from, { 23 | image: { url: imageUrl }, 24 | caption: imageCaption, 25 | contextInfo: { 26 | mentionedJid: [m.sender], 27 | forwardingScore: 9999, 28 | isForwarded: true, 29 | }, 30 | }); 31 | } 32 | 33 | // Check if it's a video 34 | if (quotedMessage.videoMessage) { 35 | const videoCaption = quotedMessage.videoMessage.caption; 36 | const videoUrl = await gss.downloadAndSaveMediaMessage(quotedMessage.videoMessage); 37 | await gss.sendMessage(m.from, { 38 | video: { url: videoUrl }, 39 | caption: videoCaption, 40 | contextInfo: { 41 | mentionedJid: [m.sender], 42 | forwardingScore: 9999, 43 | isForwarded: true, 44 | }, 45 | }); 46 | } 47 | } 48 | } 49 | } 50 | } catch (error) { 51 | console.error('Error:', error); 52 | } 53 | }; 54 | 55 | export default handleGreeting; 56 | -------------------------------------------------------------------------------- /src/plugin/invite.js: -------------------------------------------------------------------------------- 1 | import config from '../config.cjs'; 2 | 3 | const invite = async (m, gss) => { 4 | try { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) 7 | ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() 8 | : ''; 9 | const text = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | const validCommands = ['invite', 'add']; 12 | if (!validCommands.includes(cmd)) return; 13 | 14 | if (!m.isGroup) { 15 | return m.reply("🚫 *This command can only be used in group chats!*"); 16 | } 17 | 18 | const botNumber = await gss.decodeJid(gss.user.id); 19 | const groupMetadata = await gss.groupMetadata(m.from); 20 | const isBotAdmin = groupMetadata.participants.find(p => p.id === botNumber)?.admin; 21 | 22 | if (!isBotAdmin) { 23 | return m.reply("📛 *Bot must be an admin to send invites.*"); 24 | } 25 | 26 | if (!text) { 27 | return m.reply(`📛 *Please provide a number to invite.*\n\nExample:\n\`${prefix + cmd} 919341***\``); 28 | } 29 | 30 | if (text.includes('+')) { 31 | return m.reply("📛 *Please do not use '+' sign in the number.*"); 32 | } 33 | 34 | if (isNaN(text)) { 35 | return m.reply("📛 *Invalid number. Please enter only digits with country code.*"); 36 | } 37 | 38 | const groupLink = 'https://chat.whatsapp.com/' + await gss.groupInviteCode(m.from); 39 | const inviteMessage = `┌─〔 *GROUP INVITATION* 〕─◉ 40 | │ 41 | │ 📌 *Group:* ${groupMetadata.subject} 42 | │ 🔗 *Link:* ${groupLink} 43 | │ 👤 *Invited By:* @${m.sender.split('@')[0]} 44 | │ 45 | └─➤ *ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ*`; 46 | 47 | await gss.sendMessage(`${text}@s.whatsapp.net`, { 48 | text: inviteMessage, 49 | mentions: [m.sender] 50 | }); 51 | 52 | m.reply("✅ *Invite link sent successfully to the user!*"); 53 | 54 | } catch (error) { 55 | console.error("Invite Command Error:", error); 56 | m.reply("❌ *An error occurred while processing the invite. Please try again.*"); 57 | } 58 | }; 59 | 60 | export default invite; -------------------------------------------------------------------------------- /src/plugin/dl-ringtone.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import config from '../config.cjs'; 3 | 4 | const ringtone = async (m, Matrix) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const args = m.body.slice(prefix.length + cmd.length).trim().split(/\s+/).filter(Boolean); 8 | const query = args.join(" "); 9 | 10 | if (!['ringtone', 'ringtones', 'ring'].includes(cmd)) return; 11 | 12 | if (!query) { 13 | return Matrix.sendMessage(m.from, { text: "❌ Please provide a search query!\nExample: *.ringtone Suna*" }, { quoted: m }); 14 | } 15 | 16 | await m.React('🎵'); 17 | await Matrix.sendMessage(m.from, { text: `🎵 Searching ringtone for: *${query}*...` }, { quoted: m }); 18 | 19 | try { 20 | const { data } = await axios.get(`https://www.dark-yasiya-api.site/download/ringtone?text=${encodeURIComponent(query)}`); 21 | 22 | if (!data.status || !data.result || data.result.length === 0) { 23 | return Matrix.sendMessage(m.from, { text: "❌ No ringtones found for your query. Please try a different keyword." }, { quoted: m }); 24 | } 25 | 26 | const randomRingtone = data.result[Math.floor(Math.random() * data.result.length)]; 27 | 28 | await Matrix.sendMessage(m.from, { 29 | audio: { url: randomRingtone.dl_link }, 30 | mimetype: "audio/mpeg", 31 | fileName: `${randomRingtone.title}.mp3`, 32 | contextInfo: { 33 | mentionedJid: [m.sender], 34 | forwardingScore: 999, 35 | isForwarded: true, 36 | forwardedNewsletterMessageInfo: { 37 | newsletterJid: '120363321472746562@newsletter', 38 | newsletterName: "𓆩•𝐑𝐎𝐌𝐄𝐊 𝐓𝐑𝐈𝐂𝐊𝐒•𓆪‌", 39 | serverMessageId: 143 40 | } 41 | } 42 | }, { quoted: m }); 43 | 44 | } catch (error) { 45 | console.error("Error in ringtone command:", error); 46 | Matrix.sendMessage(m.from, { text: "❌ Something went wrong while fetching the ringtone. Please try again later." }, { quoted: m }); 47 | } 48 | }; 49 | 50 | export default ringtone; 51 | -------------------------------------------------------------------------------- /src/plugin/remove.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const kick = async (m, gss) => { 4 | try { 5 | const botNumber = await gss.decodeJid(gss.user.id); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['kick', 'remove']; 11 | 12 | if (!validCommands.includes(cmd)) return; 13 | 14 | if (!m.isGroup) return m.reply("*❌ THIS COMMAND CAN ONLY BE USED IN GROUPS*"); 15 | const groupMetadata = await gss.groupMetadata(m.from); 16 | const participants = groupMetadata.participants; 17 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 18 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 19 | 20 | if (!botAdmin) return m.reply("*❌ BOT MUST BE AN ADMIN TO USE THIS COMMAND*"); 21 | if (!senderAdmin) return m.reply("*❌ YOU MUST BE AN ADMIN TO USE THIS COMMAND*"); 22 | 23 | if (!m.mentionedJid) m.mentionedJid = []; 24 | 25 | if (m.quoted?.participant) m.mentionedJid.push(m.quoted.participant); 26 | 27 | const users = m.mentionedJid.length > 0 28 | ? m.mentionedJid 29 | : text.replace(/[^0-9]/g, '').length > 0 30 | ? [text.replace(/[^0-9]/g, '') + '@s.whatsapp.net'] 31 | : []; 32 | 33 | if (users.length === 0) { 34 | return m.reply("*❌ PLEASE MENTION OR QUOTE A USER TO KICK*"); 35 | } 36 | 37 | const validUsers = users.filter(Boolean); 38 | 39 | await gss.groupParticipantsUpdate(m.from, validUsers, 'remove') 40 | .then(() => { 41 | const kickedNames = validUsers.map(user => `@${user.split("@")[0]}`); 42 | m.reply(`*USERS ${kickedNames} KICKED SUCCESSFULLY FROM THE GROUP ${groupMetadata.subject}*`); 43 | }) 44 | .catch(() => m.reply('Failed to kick user(s) from the group.')); 45 | } catch (error) { 46 | console.error('Error:', error); 47 | m.reply('An error occurred while processing the command.'); 48 | } 49 | }; 50 | 51 | export default kick; 52 | -------------------------------------------------------------------------------- /src/plugin/demote.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const demote = async (m, gss) => { 4 | try { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const validCommands = ['demote', 'unadmin']; 10 | 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | 14 | if (!m.isGroup) return m.reply("*❌ THIS COMMAND CAN ONLY BE USED IN GROUPS*"); 15 | const groupMetadata = await gss.groupMetadata(m.from); 16 | const participants = groupMetadata.participants; 17 | const botNumber = await gss.decodeJid(gss.user.id); 18 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 19 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 20 | 21 | if (!botAdmin) return m.reply("*❌ BOT MUST BE AN ADMIN TO USE THIS COMMAND*"); 22 | if (!senderAdmin) return m.reply("*❌ YOU MUST BE AN ADMIN TO USE THIS COMMAND*"); 23 | 24 | if (!m.mentionedJid) m.mentionedJid = []; 25 | 26 | if (m.quoted?.participant) m.mentionedJid.push(m.quoted.participant); 27 | 28 | const users = m.mentionedJid.length > 0 29 | ? m.mentionedJid 30 | : text.replace(/[^0-9]/g, '').length > 0 31 | ? [text.replace(/[^0-9]/g, '') + '@s.whatsapp.net'] 32 | : []; 33 | 34 | if (users.length === 0) { 35 | return m.reply("*❌ PLEASE MENTION OR QUOTE A USER TO DEMOTE*"); 36 | } 37 | 38 | const validUsers = users.filter(Boolean); 39 | 40 | await gss.groupParticipantsUpdate(m.from, validUsers, 'demote') 41 | .then(() => { 42 | const demotedNames = validUsers.map(user => `@${user.split("@")[0]}`); 43 | m.reply(`*USERS ${demotedNames} DEMOTED SUCCESSFULLY IN THE GROUP ${groupMetadata.subject}*`); 44 | }) 45 | .catch(() => m.reply('Failed to demote user(s) in the group.')); 46 | } catch (error) { 47 | console.error('Error:', error); 48 | m.reply('An error occurred while processing the command.'); 49 | } 50 | }; 51 | 52 | export default demote; 53 | -------------------------------------------------------------------------------- /src/plugin/hidetag.js: -------------------------------------------------------------------------------- 1 | import config from '../config.cjs'; 2 | 3 | // Stylish Tag-All Function 4 | const tagall = async (m, gss) => { 5 | try { 6 | // Bot and command setup 7 | const botNumber = await gss.decodeJid(gss.user.id); 8 | const prefix = config.PREFIX; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | const text = m.body.slice(prefix.length + cmd.length).trim(); 11 | 12 | // Valid command check 13 | const validCommands = ['hidetag']; 14 | if (!validCommands.includes(cmd)) return; 15 | 16 | // Group metadata and participant details 17 | const groupMetadata = await gss.groupMetadata(m.from); 18 | const participants = groupMetadata.participants; 19 | const botAdmin = participants.find((p) => p.id === botNumber)?.admin; 20 | const senderAdmin = participants.find((p) => p.id === m.sender)?.admin; 21 | 22 | // Validation checks with stylish responses 23 | if (!m.isGroup) return m.reply('🚫 *This command is exclusive to groups!*'); 24 | if (!botAdmin) return m.reply('⚠ *I need admin powers to tag everyone!*'); 25 | if (!senderAdmin) return m.reply('🔒 *Only admins can use this command!*'); 26 | 27 | // Craft the stylish message 28 | const customMessage = text || 'No message provided'; 29 | let message = `✨ *Attention Everyone!* ✨\n\n📢 *Message:* ${customMessage}\n\n`; 30 | participants.forEach((participant) => { 31 | message += `➤ @${participant.id.split('@')[0]}\n`; 32 | }); 33 | message += `\n*ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ*`; 34 | 35 | // Send the tagged message 36 | await gss.sendMessage( 37 | m.from, 38 | { 39 | text: message, 40 | mentions: participants.map((a) => a.id), 41 | }, 42 | { quoted: m } 43 | ); 44 | } catch (error) { 45 | console.error('✖ Error in tagall:', error); 46 | await m.reply('❌ *Oops! Something went wrong while tagging everyone.*'); 47 | } 48 | }; 49 | 50 | export default tagall; -------------------------------------------------------------------------------- /src/plugin/romovebg.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import fs from 'fs'; 3 | import { v4 as uuidv4 } from 'uuid'; 4 | import { removeBackgroundFromImageFile } from 'remove.bg'; 5 | import config from '../../config.cjs'; 6 | 7 | const tourl = async (m, gss) => { 8 | const prefix = config.PREFIX; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | const text = m.body.slice(prefix.length + cmd.length).trim(); 11 | 12 | const validCommands = ['removebg', 'nobg']; 13 | 14 | if (validCommands.includes(cmd)) { 15 | const apiKeys = [ 16 | 'q61faXzzR5zNU6cvcrwtUkRU', 'S258diZhcuFJooAtHTaPEn4T', 17 | '5LjfCVAp4vVNYiTjq9mXJWHF', 'aT7ibfUsGSwFyjaPZ9eoJc61', 18 | 'BY63t7Vx2tS68YZFY6AJ4HHF', '5Gdq1sSWSeyZzPMHqz7ENfi8', 19 | '86h6d6u4AXrst4BVMD9dzdGZ', 'xp8pSDavAgfE5XScqXo9UKHF', 20 | 'dWbCoCb3TacCP93imNEcPxcL' 21 | ]; 22 | const apiKey = apiKeys[Math.floor(Math.random() * apiKeys.length)]; 23 | 24 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 25 | return m.reply(`> Send/Reply with an image for remove you picture backgroud\n*Example ${prefix + cmd}*`); 26 | } 27 | 28 | const localFilePath = `./src/remobg-${uuidv4()}`; 29 | const outputFilePath = `./src/hremo-${uuidv4()}.png`; 30 | const media = await m.quoted.download(); 31 | 32 | fs.writeFileSync(localFilePath, media); 33 | 34 | m.reply('Processing...'); 35 | 36 | removeBackgroundFromImageFile({ 37 | path: localFilePath, 38 | apiKey, 39 | size: 'regular', 40 | type: 'auto', 41 | scale: '100%', 42 | outputFile: outputFilePath 43 | }).then(async () => { 44 | gss.sendMessage(m.from, { image: fs.readFileSync(outputFilePath), caption: `> Hey ${m.pushName} Your picture Background Romoved Sucessfully` }, { quoted: m }); 45 | fs.unlinkSync(localFilePath); 46 | fs.unlinkSync(outputFilePath); 47 | }).catch(error => { 48 | console.error('Error processing image:', error); 49 | m.reply('There was an error processing the image.'); 50 | fs.unlinkSync(localFilePath); 51 | }); 52 | } 53 | }; 54 | 55 | export default tourl; 56 | -------------------------------------------------------------------------------- /src/plugin/insta-dl.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import config from "../config.cjs"; 3 | 4 | const instagram = async (m, Matrix) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) 7 | ? m.body.slice(prefix.length).split(" ")[0].toLowerCase() 8 | : ""; 9 | const query = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | if (!["ig", "insta", "instagram"].includes(cmd)) return; 12 | 13 | if (!query || !query.startsWith("http")) { 14 | return Matrix.sendMessage(m.from, { 15 | text: "❌ *Usage:* `.ig `\n\nExample:\n`.ig https://www.instagram.com/reel/xyz123/`" 16 | }, { quoted: m }); 17 | } 18 | 19 | try { 20 | // React with hourglass while processing 21 | await Matrix.sendMessage(m.from, { 22 | react: { text: "⏳", key: m.key } 23 | }); 24 | 25 | const { data } = await axios.get(`https://api.davidcyriltech.my.id/instagram?url=${query}`); 26 | 27 | if (!data.success || !data.downloadUrl) { 28 | return Matrix.sendMessage(m.from, { 29 | text: "⚠️ *Failed to fetch Instagram video. Please check the URL and try again.*" 30 | }, { quoted: m }); 31 | } 32 | 33 | await Matrix.sendMessage(m.from, { 34 | video: { url: data.downloadUrl }, 35 | mimetype: "video/mp4", 36 | caption: "📥 Instagram Video\n\n_ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ_", 37 | contextInfo: { 38 | mentionedJid: [m.sender], 39 | forwardingScore: 999, 40 | isForwarded: true, 41 | forwardedNewsletterMessageInfo: { 42 | newsletterJid: "120363321472746562@newsletter", 43 | newsletterName: "ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ", 44 | serverMessageId: 143, 45 | }, 46 | }, 47 | }, { quoted: m }); 48 | 49 | // React with success tick 50 | await Matrix.sendMessage(m.from, { 51 | react: { text: "✅", key: m.key } 52 | }); 53 | 54 | } catch (error) { 55 | console.error("Instagram Downloader Error:", error); 56 | Matrix.sendMessage(m.from, { 57 | text: "❌ *An error occurred while processing your request.*\nPlease try again later." 58 | }, { quoted: m }); 59 | } 60 | }; 61 | 62 | export default instagram; -------------------------------------------------------------------------------- /src/plugin/imagetotext.js: -------------------------------------------------------------------------------- 1 | import Tesseract from 'tesseract.js'; 2 | import { writeFile, unlink } from 'fs/promises'; 3 | import config from '../config.cjs'; 4 | 5 | // Stylish Text Extraction Function 6 | const givetextCommand = async (m, Matrix) => { 7 | // Command setup 8 | const prefix = config.PREFIX; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | const arg = m.body.slice(prefix.length + cmd.length).trim(); 11 | 12 | // Valid commands 13 | const validCommands = ['givetext', 'extract']; 14 | if (!validCommands.includes(cmd)) return; 15 | 16 | // Image validation 17 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 18 | return m.reply(`✨ *Send/Reply with an image to extract text!* ✨\nUsage: *${prefix + cmd} [language]*`); 19 | } 20 | 21 | // Language setup (default to 'eng') 22 | const lang = arg || 'eng'; 23 | 24 | try { 25 | // Download the image 26 | const media = await m.quoted.download(); 27 | if (!media) throw new Error('Failed to download media.'); 28 | 29 | // Temporary file creation 30 | const filePath = `./${Date.now()}.png`; 31 | await writeFile(filePath, media); 32 | 33 | // Extract text using Tesseract 34 | await m.React('⏳'); // Processing reaction 35 | const { data: { text } } = await Tesseract.recognize(filePath, lang, { 36 | logger: (info) => console.log('🔍 Tesseract Progress:', info), 37 | }); 38 | 39 | // Craft the stylish response 40 | const responseMessage = `📝 *Extracted Text* 📝\n\n${text || 'No text found.'}\n\n*ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ*`; 41 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 42 | await m.React('✅'); // Success reaction 43 | 44 | // Cleanup 45 | await unlink(filePath); 46 | } catch (error) { 47 | console.error('✖ Error extracting text:', error); 48 | await Matrix.sendMessage(m.from, { text: '❌ *Oops! Failed to extract text from the image.*' }, { quoted: m }); 49 | await m.React('❌'); // Error reaction 50 | } 51 | }; 52 | 53 | export default givetextCommand; -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "whatsapp-bot (ROMEK-XD)", 3 | "description": " Whatsapp bot.", 4 | "keywords": [ 5 | "whatsapp bot" 6 | ], 7 | "repository": "https://github.com/ROMEKTRICKS/ROMEK-XD", 8 | "stack": "container", 9 | "env": { 10 | "SESSION_ID": { 11 | "description": "your session id", 12 | "required": true, 13 | "value": "" 14 | }, 15 | "MODE": { 16 | "description": "mode public or self", 17 | "required": true, 18 | "value": "public" 19 | }, 20 | "AUTO_STATUS_SEEN": { 21 | "description": "make it true if you want bot to view status", 22 | "required": false, 23 | "value": "" 24 | }, 25 | "AUTO_READ": { 26 | "description": "make it true if you want bot to read message", 27 | "required": false, 28 | "value": "" 29 | }, 30 | "AUTO_TYPING": { 31 | "description": "make it true if you want bot to show typing", 32 | "required": false, 33 | "value": "" 34 | }, 35 | "AUTO_RECORDING": { 36 | "description": "make it true if you want bot to show recording audio", 37 | "required": false, 38 | "value": "" 39 | }, 40 | "ALWAYS_ONLINE": { 41 | "description": "make it true if you want bot to show always online", 42 | "required": false, 43 | "value": "" 44 | }, 45 | "AUTO_BLOCK": { 46 | "description": "make it true if you want bot to auto block only 212 numbers", 47 | "required": false, 48 | "value": "" 49 | }, 50 | "REJECT_CALL": { 51 | "description": "make it true if you want to reject call", 52 | "required": false, 53 | "value": "" 54 | }, 55 | "PREFIX": { 56 | "description": "Your Bot Prefix default (.)", 57 | "required": false, 58 | "value": "" 59 | } 60 | }, 61 | "buildpacks": [ 62 | { 63 | "url": "heroku/nodejs" 64 | }, 65 | { 66 | "url": "https://github.com/DuckyTeam/heroku-buildpack-imagemagick.git" 67 | }, 68 | { 69 | "url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest" 70 | }, 71 | { 72 | "url": "https://github.com/clhuang/heroku-buildpack-webp-binaries.git" 73 | } 74 | ] 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/plugin/gimage.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import config from '../config.cjs'; 3 | 4 | const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); 5 | 6 | const imageCommand = async (m, sock) => { 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) 9 | ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() 10 | : ''; 11 | let query = m.body.slice(prefix.length + cmd.length).trim(); 12 | 13 | const validCommands = ['image', 'img', 'gimage']; 14 | const numberOfImages = 5; 15 | 16 | if (validCommands.includes(cmd)) { 17 | // Query validation 18 | if (!query && !(m.quoted && m.quoted.text)) { 19 | return sock.sendMessage(m.from, { 20 | text: `❌ *Please provide some text to search.*\n\n✏️ *Example:* \`${prefix + cmd} black cats\`` 21 | }); 22 | } 23 | 24 | if (!query && m.quoted?.text) { 25 | query = m.quoted.text; 26 | } 27 | 28 | try { 29 | await sock.sendMessage(m.from, { text: '⏳ *Fetching images, please wait...*' }); 30 | 31 | const images = []; 32 | 33 | for (let i = 0; i < numberOfImages; i++) { 34 | const url = `https://api.guruapi.tech/api/googleimage?text=${encodeURIComponent(query)}`; 35 | const response = await axios.get(url, { responseType: 'arraybuffer' }); 36 | 37 | if (response.status === 200) { 38 | const buffer = Buffer.from(response.data, 'binary'); 39 | images.push(buffer); 40 | } else { 41 | throw new Error('Image generation failed.'); 42 | } 43 | } 44 | 45 | for (let img of images) { 46 | await sleep(500); 47 | await sock.sendMessage( 48 | m.from, 49 | { 50 | image: img, 51 | caption: `🖼️ *Result for:* \`${query}\`\n\n📥 ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ` 52 | }, 53 | { quoted: m } 54 | ); 55 | } 56 | 57 | await m.React("✅"); 58 | 59 | } catch (error) { 60 | console.error("Image Command Error:", error); 61 | await m.React("❌"); 62 | return sock.sendMessage(m.from, { 63 | text: '❌ *Oops! Failed to fetch images.*\nPlease try again later.' 64 | }); 65 | } 66 | } 67 | }; 68 | 69 | export default imageCommand; -------------------------------------------------------------------------------- /src/plugin/imdb.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import config from '../config.cjs'; 3 | 4 | const imdb = async (m, gss) => { 5 | try { 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) 8 | ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() 9 | : ''; 10 | const text = m.body.slice(prefix.length + cmd.length).trim(); 11 | 12 | const validCommands = ['imdb']; 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | if (!text) return m.reply('🎬 Please provide a movie or series name.'); 16 | 17 | const res = await axios.get(`http://www.omdbapi.com/?apikey=742b2d09&t=${encodeURIComponent(text)}&plot=full`); 18 | 19 | if (res.data.Response === "False") { 20 | return m.reply('❌ Movie or series not found.'); 21 | } 22 | 23 | const data = res.data; 24 | 25 | let msg = "╭───〘 *IMDB SEARCH* 〙───╮\n"; 26 | msg += `│\n`; 27 | msg += `├ 🎬 *Title* : ${data.Title}\n`; 28 | msg += `├ 📅 *Year* : ${data.Year}\n`; 29 | msg += `├ ⭐ *Rated* : ${data.Rated}\n`; 30 | msg += `├ 📆 *Released* : ${data.Released}\n`; 31 | msg += `├ ⏳ *Runtime* : ${data.Runtime}\n`; 32 | msg += `├ 🌀 *Genre* : ${data.Genre}\n`; 33 | msg += `├ 🎥 *Director* : ${data.Director}\n`; 34 | msg += `├ ✍️ *Writer* : ${data.Writer}\n`; 35 | msg += `├ 👨 *Actors* : ${data.Actors}\n`; 36 | msg += `├ 📃 *Plot* : ${data.Plot}\n`; 37 | msg += `├ 🌐 *Language* : ${data.Language}\n`; 38 | msg += `├ 🌍 *Country* : ${data.Country}\n`; 39 | msg += `├ 🎖️ *Awards* : ${data.Awards}\n`; 40 | msg += `├ 📦 *BoxOffice* : ${data.BoxOffice}\n`; 41 | msg += `├ 🏙️ *Production* : ${data.Production}\n`; 42 | msg += `├ 🌟 *IMDB Rating* : ${data.imdbRating}\n`; 43 | msg += `├ ✅ *IMDB Votes* : ${data.imdbVotes}\n`; 44 | msg += `│\n`; 45 | msg += `╰─── ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ ───╯`; 46 | 47 | await gss.sendMessage(m.from, { 48 | image: { url: data.Poster }, 49 | caption: msg, 50 | }, { quoted: m }); 51 | 52 | } catch (error) { 53 | console.error('Error fetching IMDb data:', error); 54 | m.reply('❌ An error occurred while fetching the data.'); 55 | } 56 | }; 57 | 58 | export default imdb; -------------------------------------------------------------------------------- /lib/converter.cjs: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path; 4 | const { spawn } = require('child_process') 5 | 6 | function ffmpeg(buffer, args = [], ext = '', ext2 = '') { 7 | return new Promise(async (resolve, reject) => { 8 | try { 9 | let tmp = path.join(__dirname, '../src', + new Date + '.' + ext) 10 | let out = tmp + '.' + ext2 11 | await fs.promises.writeFile(tmp, buffer) 12 | spawn(ffmpegPath, [ 13 | '-y', 14 | '-i', tmp, 15 | ...args, 16 | out 17 | ]) 18 | .on('error', reject) 19 | .on('close', async (code) => { 20 | try { 21 | await fs.promises.unlink(tmp) 22 | if (code !== 0) return reject(code) 23 | resolve(await fs.promises.readFile(out)) 24 | await fs.promises.unlink(out) 25 | } catch (e) { 26 | reject(e) 27 | } 28 | }) 29 | } catch (e) { 30 | reject(e) 31 | } 32 | }) 33 | } 34 | 35 | /** 36 | * Convert Audio to Playable WhatsApp Audio 37 | * @param {Buffer} buffer Audio Buffer 38 | * @param {String} ext File Extension 39 | */ 40 | function toAudio(buffer, ext) { 41 | return ffmpeg(buffer, [ 42 | '-vn', 43 | '-ac', '2', 44 | '-b:a', '128k', 45 | '-ar', '44100', 46 | '-f', 'mp3' 47 | ], ext, 'mp3') 48 | } 49 | 50 | /** 51 | * Convert Audio to Playable WhatsApp PTT 52 | * @param {Buffer} buffer Audio Buffer 53 | * @param {String} ext File Extension 54 | */ 55 | function toPTT(buffer, ext) { 56 | return ffmpeg(buffer, [ 57 | '-vn', 58 | '-c:a', 'libopus', 59 | '-b:a', '128k', 60 | '-vbr', 'on', 61 | '-compression_level', '10' 62 | ], ext, 'opus') 63 | } 64 | 65 | /** 66 | * Convert Audio to Playable WhatsApp Video 67 | * @param {Buffer} buffer Video Buffer 68 | * @param {String} ext File Extension 69 | */ 70 | function toVideo(buffer, ext) { 71 | return ffmpeg(buffer, [ 72 | '-c:v', 'libx264', 73 | '-c:a', 'aac', 74 | '-ab', '128k', 75 | '-ar', '44100', 76 | '-crf', '32', 77 | '-preset', 'slow' 78 | ], ext, 'mp4') 79 | } 80 | 81 | module.exports = { 82 | toAudio, 83 | toPTT, 84 | toVideo, 85 | ffmpeg, 86 | } 87 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ROMEK-XD", 3 | "version": "10.8.1", 4 | "description": "ROMEK-XD latest multi device whatsapp bot", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "pm2 start index.js --deep-monitoring --attach --name JAWAD-XMD", 9 | "stop": "pm2 stop ROMEK-XD", 10 | "restart": "pm2 restart ROMEK-XD" 11 | }, 12 | "keywords": ["ROMEKTRICKS", "whatsapp-bot", "whatsapp md bot"], 13 | "author": "ROMEK-XD", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@ffmpeg-installer/ffmpeg": "^1.1.0", 17 | "@google/generative-ai": "^0.9.0", 18 | "@hapi/boom": "^10.0.1", 19 | "@whiskeysockets/baileys": "github:kiuur/bails", 20 | "@xaviabot/fb-downloader": "^1.0.14", 21 | "acrcloud": "^1.4.0", 22 | "api-dylux": "^1.8.3", 23 | "aptoide-scraper": "^1.0.1", 24 | "awesome-phonenumber": "^6.8.0", 25 | "axios": "^1.6.8", 26 | "chalk": "^5.3.0", 27 | "child_process": "^1.0.2", 28 | "crypto": "^1.0.1", 29 | "dotenv": "^16.4.5", 30 | "express": "^4.19.2", 31 | "ffmpeg": "^0.0.4", 32 | "file-type": "^19.0.0", 33 | "fluent-ffmpeg": "^2.1.3", 34 | "megajs": "^1.1.0", 35 | "fs": "^0.0.1-security", 36 | "fs-extra": "^11.2.0", 37 | "gifted-dls": "^1.3.0", 38 | "google-it": "^1.6.4", 39 | "human-readable": "^0.2.1", 40 | "jimp": "^0.16.13", 41 | "jpeg-js": "^0.4.4", 42 | "jsqr": "^1.4.0", 43 | "libphonenumber": "^0.0.10", 44 | "moment-timezone": "^0.5.45", 45 | "node-cache": "^5.1.2", 46 | "node-cron": "^3.0.3", 47 | "node-fetch": "^3.3.2", 48 | "node-os-utils": "^1.3.7", 49 | "node-webpmux": "^3.2.0", 50 | "os": "^0.1.2", 51 | "pdfkit": "^0.15.0", 52 | "pino": "^8.20.0", 53 | "pm2": "^6.0.5", 54 | "sequelize": "^6.37.5", 55 | "sqlite3": "^5.1.7", 56 | "proto": "^1.0.19", 57 | "qrcode": "^1.5.3", 58 | "qrcode-terminal": "^0.12.0", 59 | "readline": "^1.3.0", 60 | "remove.bg": "^1.3.0", 61 | "adm-zip": "^0.5.16", 62 | "stream": "^0.0.3", 63 | "tesseract.js": "^5.1.0", 64 | "translate-google-api": "^1.0.4", 65 | "url": "^0.11.4", 66 | "uuid": "^9.0.1", 67 | "wasitech": "npm:@distube/ytdl-core", 68 | "yt-search": "^2.11.0", 69 | "gif-encoder": "^0.7.2" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/plugin/rvo.js: -------------------------------------------------------------------------------- 1 | import { downloadContentFromMessage } from '@whiskeysockets/baileys'; 2 | import fs from 'fs'; 3 | import config from '../../config.cjs'; 4 | 5 | const rvo = async (m, sock) => { 6 | try { 7 | console.log('Quoted message:', m.quoted); 8 | 9 | const prefix = config.PREFIX; 10 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 11 | const text = m.body.slice(prefix.length + cmd.length).trim(); 12 | 13 | const validCommands = ['v', 'vv', 'readviewonce']; 14 | if (!validCommands.includes(cmd)) return; 15 | 16 | // Check if the quoted message is a view-once message 17 | if (!m.quoted || m.quoted.type !== 'view_once' || (m.quoted.mtype !== 'imageMessage' && m.quoted.mtype !== 'videoMessage')) { 18 | return m.reply('This is not a view once message'); 19 | } 20 | 21 | // Extract the message and its type 22 | const msg = m.quoted.message; 23 | const type = Object.keys(msg)[0]; 24 | 25 | const originalCaption = msg[type].caption || ''; 26 | const newCaption = `${originalCaption}\n\n> ©𝐏𝐎𝐖𝐄𝐑𝐄𝐃 𝐁𝐘 🧿𝗥𝗢𝗠𝗘𝗞-𝗫𝗗🪀`; 27 | 28 | 29 | // Download the media content 30 | const mediaStream = await downloadContentFromMessage(msg[type], type === 'imageMessage' ? 'image' : 'video'); 31 | let buffer = Buffer.from([]); 32 | for await (const chunk of mediaStream) { 33 | buffer = Buffer.concat([buffer, chunk]); 34 | } 35 | 36 | // Send the media back to the chat 37 | if (/video/.test(type)) { 38 | await sock.sendMessage(m.from, { 39 | video: buffer, 40 | caption: newCaption, 41 | contextInfo: { 42 | mentionedJid: [m.sender], 43 | forwardingScore: 9999, 44 | isForwarded: true, 45 | } 46 | }, { quoted: m }); 47 | } else if (/image/.test(type)) { 48 | await sock.sendMessage(m.from, { 49 | image: buffer, 50 | caption: newCaption, 51 | contextInfo: { 52 | mentionedJid: [m.sender], 53 | forwardingScore: 9999, 54 | isForwarded: true, 55 | } 56 | }, { quoted: m }); 57 | } 58 | } catch (e) { 59 | console.error('Error:', e); 60 | m.reply('An error occurred while processing the command.'); 61 | } 62 | }; 63 | 64 | export default rvo; 65 | -------------------------------------------------------------------------------- /src/plugin/whatmusic.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import acrcloud from 'acrcloud'; 3 | import config from '../../config.cjs'; 4 | 5 | 6 | const acr = new acrcloud({ 7 | host: 'identify-eu-west-1.acrcloud.com', 8 | access_key: '716b4ddfa557144ce0a459344fe0c2c9', 9 | access_secret: 'Lz75UbI8g6AzkLRQgTgHyBlaQq9YT5wonr3xhFkf' 10 | }); 11 | 12 | const shazam = async (m, gss) => { 13 | try { 14 | const prefix = config.PREFIX; 15 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 16 | const text = m.body.slice(prefix.length + cmd.length).trim(); 17 | 18 | const validCommands = ['shazam', 'find', 'whatmusic']; 19 | if (!validCommands.includes(cmd)) return; 20 | 21 | const quoted = m.quoted || {}; 22 | 23 | if (!quoted || (quoted.mtype !== 'audioMessage' && quoted.mtype !== 'videoMessage')) { 24 | return m.reply('You asked about music. Please provide a quoted audio or video message for identification.'); 25 | } 26 | 27 | const mime = m.quoted.mimetype; 28 | try { 29 | const media = await m.quoted.download(); 30 | const filePath = `./${Date.now()}.mp3`; 31 | fs.writeFileSync(filePath, media); 32 | 33 | m.reply('Identifying the music, please wait...'); 34 | 35 | const res = await acr.identify(fs.readFileSync(filePath)); 36 | const { code, msg } = res.status; 37 | 38 | if (code !== 0) { 39 | throw new Error(msg); 40 | } 41 | 42 | const { title, artists, album, genres, release_date } = res.metadata.music[0]; 43 | const txt = `𝚁𝙴𝚂𝚄𝙻𝚃 44 | • 📌 *TITLE*: ${title} 45 | • 👨‍🎤 𝙰𝚁𝚃𝙸𝚂𝚃: ${artists ? artists.map(v => v.name).join(', ') : 'NOT FOUND'} 46 | • 💾 𝙰𝙻𝙱𝚄𝙼: ${album ? album.name : 'NOT FOUND'} 47 | • 🌐 𝙶𝙴𝙽𝚁𝙴: ${genres ? genres.map(v => v.name).join(', ') : 'NOT FOUND'} 48 | • 📆 RELEASE DATE: ${release_date || 'NOT FOUND'} 49 | `.trim(); 50 | 51 | fs.unlinkSync(filePath); 52 | m.reply(txt); 53 | } catch (error) { 54 | console.error(error); 55 | m.reply('An error occurred during music identification.'); 56 | } 57 | } catch (error) { 58 | console.error('Error:', error); 59 | m.reply('An Error Occurred While Processing The Command.'); 60 | } 61 | }; 62 | 63 | export default shazam; 64 | -------------------------------------------------------------------------------- /src/plugin/qc.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import config from '../../config.cjs'; 3 | 4 | const quotedChat = async (m, gss) => { 5 | try { 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['qc']; 11 | 12 | if (!validCommands.includes(cmd)) return; 13 | 14 | if (!text) { 15 | return m.reply('Please provide text for the quote.'); 16 | } 17 | 18 | if (text.length > 30) { 19 | return m.reply('Please provide text with a maximum of 30 characters.'); 20 | } 21 | 22 | let profilePicture; 23 | 24 | try { 25 | profilePicture = await gss.profilePictureUrl(m.quoted ? m.quoted.sender : m.sender, 'image'); 26 | } catch { 27 | profilePicture = 'https://srv.neoxr.tk/files/z8hI5T.jpg'; 28 | } 29 | 30 | const quoteObject = { 31 | type: "quote", 32 | format: "png", 33 | backgroundColor: "#FFFFFF", 34 | width: 512, 35 | height: 768, 36 | scale: 2, 37 | messages: [{ 38 | entities: [], 39 | avatar: true, 40 | from: { 41 | id: 1, 42 | name: m.quoted ? (await gss.getContact(m.quoted.sender)).notify || m.quoted.sender.split('@')[0] : m.pushName, 43 | photo: { 44 | url: profilePicture 45 | } 46 | }, 47 | text: text, 48 | replyMessage: {} 49 | }] 50 | }; 51 | 52 | try { 53 | const response = await axios.post('https://bot.lyo.su/quote/generate', quoteObject, { 54 | headers: { 55 | 'Content-Type': 'application/json' 56 | } 57 | }); 58 | 59 | const buffer = Buffer.from(response.data.result.image, 'base64'); 60 | 61 | await gss.sendImageAsSticker(m.from, buffer, m, { 62 | packname: "", 63 | author: ">🧿𝗥𝗢𝗠𝗘𝗞-𝗫𝗗🪀" 64 | }); 65 | } catch (error) { 66 | console.error('Error during HTTP request:', error); 67 | return m.reply('Error generating sticker. Please try again later.'); 68 | } 69 | } catch (error) { 70 | console.error('Unexpected error in sticker case:', error); 71 | m.reply('An unexpected error occurred.'); 72 | } 73 | }; 74 | 75 | export default quotedChat; 76 | 77 | -------------------------------------------------------------------------------- /src/plugin/fb-dl.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import config from "../config.cjs"; 3 | 4 | const facebook = async (m, Matrix) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(" ")[0].toLowerCase() : ""; 7 | const query = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | if (!["fb", "facebook"].includes(cmd)) return; 10 | 11 | if (!query || !query.startsWith("http")) { 12 | return Matrix.sendMessage(m.from, { text: "❌ *Usage:* `.fb `" }, { quoted: m }); 13 | } 14 | 15 | try { 16 | await Matrix.sendMessage(m.from, { react: { text: "⏳", key: m.key } }); 17 | 18 | const { data } = await axios.get(`https://api.davidcyriltech.my.id/facebook2?url=${query}`); 19 | 20 | if (!data.status || !data.video || !data.video.downloads) { 21 | return Matrix.sendMessage(m.from, { text: "⚠️ *Failed to fetch Facebook video. Please try again.*" }, { quoted: m }); 22 | } 23 | 24 | const { title, downloads } = data.video; 25 | const bestQuality = downloads.find(v => v.quality === "HD") || downloads.find(v => v.quality === "SD"); 26 | 27 | if (!bestQuality) { 28 | return Matrix.sendMessage(m.from, { text: "⚠️ *No downloadable video found.*" }, { quoted: m }); 29 | } 30 | 31 | const caption = ` 32 | ┌─〔 *FACEBOOK VIDEO* 〕─◉ 33 | │ 34 | │ 🎬 *Title:* ${title} 35 | │ 📥 *Quality:* ${bestQuality.quality} 36 | │ 37 | └─➤ *ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ✅* 38 | `.trim(); 39 | 40 | await Matrix.sendMessage(m.from, { 41 | video: { url: bestQuality.downloadUrl }, 42 | mimetype: "video/mp4", 43 | caption, 44 | contextInfo: { 45 | mentionedJid: [m.sender], 46 | forwardingScore: 999, 47 | isForwarded: true, 48 | forwardedNewsletterMessageInfo: { 49 | newsletterJid: "120363354023106228@newsletter", 50 | newsletterName: "JawadTechX", 51 | serverMessageId: 144, 52 | }, 53 | }, 54 | }, { quoted: m }); 55 | 56 | await Matrix.sendMessage(m.from, { react: { text: "✅", key: m.key } }); 57 | 58 | } catch (error) { 59 | console.error("Facebook Downloader Error:", error); 60 | Matrix.sendMessage(m.from, { text: "❌ *An error occurred while processing your request. Please try again later.*" }, { quoted: m }); 61 | } 62 | }; 63 | 64 | export default facebook; 65 | -------------------------------------------------------------------------------- /src/plugin/gcfullpp.js: -------------------------------------------------------------------------------- 1 | import { downloadMediaMessage } from '@whiskeysockets/baileys'; 2 | import Jimp from 'jimp'; 3 | import config from '../config.cjs'; 4 | 5 | const gcfullpp = async (m, sock) => { 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | 9 | if (cmd !== "gcfullpp") return; 10 | 11 | if (!m.isGroup) { 12 | return m.reply("❌ *This command can only be used in group chats.*"); 13 | } 14 | 15 | const groupMetadata = await sock.groupMetadata(m.from); 16 | const participant = groupMetadata.participants.find(p => p.id === m.sender); 17 | 18 | if (!participant?.admin) { 19 | return m.reply("❌ *Only group admins are allowed to use this command.*"); 20 | } 21 | 22 | if (!m.quoted?.message?.imageMessage) { 23 | return m.reply("⚠️ *Please reply to an image to set it as group profile picture.*"); 24 | } 25 | 26 | await m.React("⏳"); 27 | 28 | try { 29 | const media = await downloadMediaMessage(m.quoted, "buffer", {}); 30 | if (!media) { 31 | await m.React("❌"); 32 | return m.reply("❌ *Failed to download image. Try again.*"); 33 | } 34 | 35 | const image = await Jimp.read(media); 36 | if (!image) throw new Error("Invalid image format"); 37 | 38 | const size = Math.max(image.bitmap.width, image.bitmap.height); 39 | const squareImage = new Jimp(size, size, 0x000000FF); 40 | 41 | const x = (size - image.bitmap.width) / 2; 42 | const y = (size - image.bitmap.height) / 2; 43 | squareImage.composite(image, x, y); 44 | 45 | squareImage.resize(640, 640); 46 | const buffer = await squareImage.getBufferAsync(Jimp.MIME_JPEG); 47 | 48 | await sock.updateProfilePicture(m.from, buffer); 49 | await m.React("✅"); 50 | 51 | return sock.sendMessage( 52 | m.from, 53 | { 54 | text: ` 55 | ┌─〔 *GROUP FULL PP UPDATED* 〕─◉ 56 | │ 57 | │ ✅ *Successfully updated group display picture!* 58 | │ 👑 *By:* @${m.sender.split("@")[0]} 59 | │ 60 | └─➤ *ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ* 61 | `.trim(), 62 | mentions: [m.sender] 63 | }, 64 | { quoted: m } 65 | ); 66 | 67 | } catch (error) { 68 | console.error("Group Full PP Error:", error); 69 | await m.React("❌"); 70 | return m.reply("❌ *Error occurred while setting group profile picture:* " + error.message); 71 | } 72 | }; 73 | 74 | export default gcfullpp; -------------------------------------------------------------------------------- /src/plugin/dl-tiktok.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import config from "../config.cjs"; 3 | 4 | const tiktok = async (m, Matrix) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(" ")[0].toLowerCase() : ""; 7 | const query = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | if (!["tiktok", "tt"].includes(cmd)) return; 10 | 11 | if (!query || !query.startsWith("http")) { 12 | return Matrix.sendMessage(m.from, { text: "❌ *Usage:* `.tiktok `" }, { quoted: m }); 13 | } 14 | 15 | try { 16 | await Matrix.sendMessage(m.from, { react: { text: "⏳", key: m.key } }); 17 | 18 | const { data } = await axios.get(`https://api.davidcyriltech.my.id/download/tiktok?url=${query}`); 19 | 20 | if (!data.success || !data.result || !data.result.video) { 21 | return Matrix.sendMessage(m.from, { 22 | text: "⚠️ *Failed to fetch TikTok video. Please try again.*" 23 | }, { quoted: m }); 24 | } 25 | 26 | const { desc, author, statistics, video, music } = data.result; 27 | 28 | const caption = ` 29 | ┌─〔 *TIKTOK VIDEO* 〕─◉ 30 | │ 31 | │ ✦ *Description:* ${desc} 32 | │ ✦ *Author:* ${author.nickname} 33 | │ ✦ *Likes:* ${statistics.likeCount} 34 | │ ✦ *Comments:* ${statistics.commentCount} 35 | │ ✦ *Shares:* ${statistics.shareCount} 36 | │ 37 | └─➤> *ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ* 38 | `; 39 | 40 | await Matrix.sendMessage(m.from, { 41 | video: { url: video }, 42 | mimetype: "video/mp4", 43 | caption, 44 | contextInfo: { 45 | mentionedJid: [m.sender], 46 | forwardingScore: 999, 47 | isForwarded: true, 48 | forwardedNewsletterMessageInfo: { 49 | newsletterJid: "120363321472746562@newsletter", 50 | newsletterName: "𓆩•𝐑𝐎𝐌𝐄𝐊 𝐓𝐑𝐈𝐂𝐊𝐒•𓆪‌", 51 | serverMessageId: 143, 52 | }, 53 | }, 54 | }, { quoted: m }); 55 | 56 | await Matrix.sendMessage(m.from, { react: { text: "✅", key: m.key } }); 57 | 58 | // Send the TikTok music separately 59 | await Matrix.sendMessage(m.from, { 60 | audio: { url: music }, 61 | mimetype: "audio/mpeg", 62 | fileName: "TikTok_Audio.mp3", 63 | caption: "🎶 *TikTok Audio Downloaded*", 64 | }, { quoted: m }); 65 | 66 | } catch (error) { 67 | console.error("TikTok Downloader Error:", error); 68 | Matrix.sendMessage(m.from, { text: "❌ *An error occurred while processing your request. Please try again later.*" }, { quoted: m }); 69 | } 70 | }; 71 | 72 | export default tiktok; 73 | -------------------------------------------------------------------------------- /src/plugin/promote.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const promote = async (m, gss) => { 4 | try { 5 | const botNumber = await gss.decodeJid(gss.user.id); 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 8 | const text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['promote', 'admin', 'toadmin']; 11 | 12 | if (!validCommands.includes(cmd)) return; 13 | 14 | if (!m.isGroup) return m.reply("*❌ THIS COMMAND CAN ONLY BE USED IN GROUPS*"); 15 | const groupMetadata = await gss.groupMetadata(m.from); 16 | const participants = groupMetadata.participants; 17 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 18 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 19 | 20 | if (!botAdmin) return m.reply("*❌ BOT MUST BE AN ADMIN TO USE THIS COMMAND*"); 21 | if (!senderAdmin) return m.reply("*❌ YOU MUST BE AN ADMIN TO USE THIS COMMAND*"); 22 | 23 | if (!m.mentionedJid) m.mentionedJid = []; 24 | 25 | if (m.quoted?.participant) m.mentionedJid.push(m.quoted.participant); 26 | 27 | const users = m.mentionedJid.length > 0 28 | ? m.mentionedJid 29 | : text.replace(/[^0-9]/g, '').length > 0 30 | ? [text.replace(/[^0-9]/g, '') + '@s.whatsapp.net'] 31 | : []; 32 | 33 | if (users.length === 0) { 34 | return m.reply("*❌ PLEASE MENTION OR QUOTE A USER TO PROMOTE*"); 35 | } 36 | console.log('users: ', users) 37 | const validUsers = users.filter(Boolean); 38 | 39 | const usernames = await Promise.all( 40 | validUsers.map(async (user) => { 41 | console.log('user: ', user) 42 | try { 43 | const contact = await gss.getContact(user); 44 | console.log('contact: ', contact) 45 | return contact.notify || contact.pushname || user.split('@')[0]; 46 | } catch (error) { 47 | return user.split('@')[0]; 48 | } 49 | }) 50 | ); 51 | console.log('usernames: ', usernames) 52 | 53 | await gss.groupParticipantsUpdate(m.from, validUsers, 'promote') 54 | .then(() => { 55 | const promotedNames = usernames.map(username => `@${username}`).join(', '); 56 | m.reply(`*Users ${promotedNames} promoted successfully in the group ${groupMetadata.subject}.*`); 57 | }) 58 | .catch(() => m.reply('Failed to promote user(s) in the group.')); 59 | } catch (error) { 60 | console.error('Error:', error); 61 | m.reply('An error occurred while processing the command.'); 62 | } 63 | }; 64 | 65 | export default promote; -------------------------------------------------------------------------------- /src/plugin/vv2.js: -------------------------------------------------------------------------------- 1 | import { downloadContentFromMessage } from '@whiskeysockets/baileys'; 2 | import fs from 'fs'; 3 | 4 | const vv2 = async (m, Gifted) => { 5 | try { 6 | console.log('Quoted message:', m.quoted); // Logging statement to check the quoted message 7 | 8 | const prefixMatch = m.body.match(/^[\\/!#.]/); 9 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 10 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 11 | 12 | const validCommands = ['rvo2', 'vv2', 'reveal2', 'antiviewonce2', 'viewonce2']; 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | // Check if the quoted message is a view-once message 16 | if (!m.quoted || m.quoted.type !== 'view_once' || (m.quoted.mtype !== 'imageMessage' && m.quoted.mtype !== 'videoMessage' && m.quoted.mtype !== 'audioMessage')) { 17 | return m.reply('This is not a view once message'); 18 | } 19 | 20 | // Extract the message and its type 21 | const msg = m.quoted.message; 22 | const type = Object.keys(msg)[0]; 23 | 24 | const originalCaption = msg[type].caption || ''; 25 | const newCaption = `${originalCaption}\n\n> ʀᴏᴍᴇᴋ-xᴅ © 2025*`; 26 | 27 | 28 | // Download the media content 29 | const mediaStream = await downloadContentFromMessage(msg[type], type === 'imageMessage' ? 'image' : 'video'); 30 | let buffer = Buffer.from([]); 31 | for await (const chunk of mediaStream) { 32 | buffer = Buffer.concat([buffer, chunk]); 33 | } 34 | 35 | // Send the media back to the chat 36 | if (/video/.test(type)) { 37 | await Gifted.sendMessage(m.from, { 38 | video: buffer, 39 | caption: newCaption, 40 | contextInfo: { 41 | mentionedJid: [m.sender], 42 | forwardingScore: 9999, 43 | isForwarded: false, 44 | } 45 | }, { quoted: m }); 46 | } else if (/image/.test(type)) { 47 | await Gifted.sendMessage(m.from, { 48 | image: buffer, 49 | caption: newCaption, 50 | contextInfo: { 51 | mentionedJid: [m.sender], 52 | forwardingScore: 9999, 53 | isForwarded: false, 54 | } 55 | }, { quoted: m }); 56 | } 57 | else if (/audio/.test(type)) { 58 | await Gifted.sendMessage(botUser, { 59 | audio: buffer, 60 | caption: newCaption, 61 | contextInfo: { 62 | mentionedJid: [m.sender], 63 | forwardingScore: 9999, 64 | isForwarded: false, 65 | } 66 | }, { quoted: m }); 67 | } 68 | } catch (e) { 69 | console.error('Error:', e); 70 | m.reply('An error occurred while processing the command.'); 71 | } 72 | }; 73 | 74 | export default vv2; 75 | -------------------------------------------------------------------------------- /src/plugin/fullpp.js: -------------------------------------------------------------------------------- 1 | import { downloadMediaMessage } from '@whiskeysockets/baileys'; 2 | import Jimp from 'jimp'; 3 | import config from '../config.cjs'; 4 | 5 | const setProfilePicture = async (m, sock) => { 6 | const botNumber = await sock.decodeJid(sock.user.id); 7 | const isBot = m.sender === botNumber; 8 | const prefix = config.PREFIX; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | 11 | if (cmd !== "fullpp") return; 12 | 13 | if (!isBot) { 14 | return m.reply("❌ *Only the bot itself can use this command.*"); 15 | } 16 | 17 | if (!m.quoted?.message?.imageMessage) { 18 | return m.reply("⚠️ *Please reply to an image to set as profile picture.*"); 19 | } 20 | 21 | await m.React('⏳'); 22 | 23 | try { 24 | let media; 25 | for (let i = 0; i < 3; i++) { 26 | try { 27 | media = await downloadMediaMessage(m.quoted, 'buffer'); 28 | if (media) break; 29 | } catch (err) { 30 | if (i === 2) { 31 | await m.React('❌'); 32 | return m.reply("❌ *Failed to download image. Please try again.*"); 33 | } 34 | } 35 | } 36 | 37 | const image = await Jimp.read(media); 38 | if (!image) throw new Error("Invalid image"); 39 | 40 | const size = Math.max(image.bitmap.width, image.bitmap.height); 41 | if (image.bitmap.width !== image.bitmap.height) { 42 | const squareImage = new Jimp(size, size, 0x000000FF); 43 | squareImage.composite(image, (size - image.bitmap.width) / 2, (size - image.bitmap.height) / 2); 44 | image.clone(squareImage); 45 | } 46 | 47 | image.resize(640, 640); 48 | const buffer = await image.getBufferAsync(Jimp.MIME_JPEG); 49 | 50 | await sock.updateProfilePicture(botNumber, buffer); 51 | await m.React('✅'); 52 | 53 | return sock.sendMessage( 54 | m.from, 55 | { 56 | text: ` 57 | ┌─〔 *PROFILE UPDATED* 〕─◉ 58 | │ 59 | │ ✅ *Profile Picture set successfully!* 60 | │ 🛡️ *Bot:* ${botNumber.split("@")[0]} 61 | │ 62 | └─➤ *ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ* 63 | `.trim(), 64 | contextInfo: { 65 | mentionedJid: [m.sender], 66 | forwardingScore: 999, 67 | isForwarded: true, 68 | forwardedNewsletterMessageInfo: { 69 | newsletterJid: '120363398040175935@newsletter', 70 | newsletterName: "Romek-XD", 71 | serverMessageId: 143 72 | } 73 | } 74 | }, 75 | { quoted: m } 76 | ); 77 | 78 | } catch (error) { 79 | console.error("Profile Picture Error:", error); 80 | await m.React('❌'); 81 | return m.reply("❌ *An error occurred while updating profile picture.*"); 82 | } 83 | }; 84 | 85 | export default setProfilePicture; -------------------------------------------------------------------------------- /src/plugin/sticker.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs-extra'; 2 | import config from '../../config.cjs'; 3 | 4 | const stickerCommand = async (m, gss) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const packname = global.packname || "🐼𝐑𝐎𝐌𝐄𝐊 𝐗𝐃🐠"; 10 | const author = global.author || "🥵💫👿"; 11 | 12 | const validCommands = ['sticker', 's', 'autosticker']; 13 | 14 | const arg = text.split(' ')[0]; 15 | 16 | if (cmd === 'autosticker') { 17 | if (arg === 'on') { 18 | config.AUTO_STICKER = true; 19 | await m.reply('Auto-sticker is now enabled.'); 20 | } else if (arg === 'off') { 21 | config.AUTO_STICKER = false; 22 | await m.reply('Auto-sticker is now disabled.'); 23 | } else { 24 | await m.reply('Usage: /autosticker on|off'); 25 | } 26 | return; 27 | } 28 | 29 | if (config.AUTO_STICKER && !m.key.fromMe) { 30 | if (m.type === 'imageMessage') { 31 | let media = await m.download(); 32 | if (media) { 33 | await gss.sendImageAsSticker(m.from, media, m, { packname, author }); 34 | console.log('Auto sticker sent'); 35 | } else { 36 | console.error('Failed to download media for auto-sticker.'); 37 | } 38 | return; 39 | } else if (m.type === 'videoMessage' && m.msg.seconds <= 11) { 40 | let media = await m.download(); 41 | if (media) { 42 | await gss.sendVideoAsSticker(m.from, media, m, { packname, author }); 43 | } else { 44 | console.error('Failed to download video for auto-sticker.'); 45 | } 46 | return; 47 | } 48 | } 49 | 50 | if (validCommands.includes(cmd)) { 51 | const quoted = m.quoted || {}; 52 | 53 | if (!quoted || (quoted.mtype !== 'imageMessage' && quoted.mtype !== 'videoMessage')) { 54 | return m.reply(`Send/Reply with an image or video to convert into a sticker using ${prefix + cmd}`); 55 | } 56 | 57 | try { 58 | const media = await quoted.download(); 59 | if (!media) throw new Error('Failed to download media.'); 60 | if (quoted.mtype === 'imageMessage') { 61 | await gss.sendImageAsSticker(m.from, media, m, { packname, author }); 62 | m.reply('Sticker created successfully!'); 63 | } 64 | else if (quoted.mtype === 'videoMessage' && quoted.msg.seconds <= 11) { 65 | await gss.sendVideoAsSticker(m.from, media, m, { packname, author }); 66 | m.reply('Sticker created successfully!'); 67 | } else { 68 | m.reply('Video too long. Please send a video that is less than 11 seconds.'); 69 | } 70 | } catch (error) { 71 | console.error(error); 72 | m.reply(`Error: ${error.message}`); 73 | } 74 | } 75 | }; 76 | 77 | export default stickerCommand; 78 | -------------------------------------------------------------------------------- /src/event/group-handler.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment-timezone'; 2 | import config from '../../config.cjs'; 3 | export default async function GroupParticipants(sock, { id, participants, action }) { 4 | try { 5 | const metadata = await sock.groupMetadata(id) 6 | 7 | // participants 8 | for (const jid of participants) { 9 | // get profile picture user 10 | let profile 11 | try { 12 | profile = await sock.profilePictureUrl(jid, "image") 13 | } catch { 14 | profile = "https://lh3.googleusercontent.com/proxy/esjjzRYoXlhgNYXqU8Gf_3lu6V-eONTnymkLzdwQ6F6z0MWAqIwIpqgq_lk4caRIZF_0Uqb5U8NWNrJcaeTuCjp7xZlpL48JDx-qzAXSTh00AVVqBoT7MJ0259pik9mnQ1LldFLfHZUGDGY=w1200-h630-p-k-no-nu" 15 | } 16 | 17 | // action 18 | if (action == "add" && config.WELCOME ) { 19 | const userName = jid.split("@")[0]; 20 | const joinTime = moment.tz('Asia/Kolkata').format('HH:mm:ss'); 21 | const joinDate = moment.tz('Asia/Kolkata').format('DD/MM/YYYY'); 22 | const membersCount = metadata.participants.length; 23 | sock.sendMessage(id, { 24 | text: `> Hello @${userName}! Welcome to *${metadata.subject}*.\n> You are the ${membersCount}th member.\n> Joined at: ${joinTime} on ${joinDate} 25 | "`, contextInfo: { 26 | mentionedJid: [jid], 27 | externalAdReply: { 28 | title: `Welcome`, 29 | mediaType: 1, 30 | previewType: 0, 31 | renderLargerThumbnail: true, 32 | thumbnailUrl: metadata.subject, 33 | sourceUrl: 'https://sid-bhai.vercel.app' 34 | } 35 | } 36 | }) 37 | } else if (action == "remove" && config.WELCOME ) { 38 | const userName = jid.split('@')[0]; 39 | const leaveTime = moment.tz('Asia/Kolkata').format('HH:mm:ss'); 40 | const leaveDate = moment.tz('Asia/Kolkata').format('DD/MM/YYYY'); 41 | const membersCount = metadata.participants.length; 42 | sock.sendMessage(id, { 43 | text: `> Goodbye @${userName} from ${metadata.subject}.\n> We are now ${membersCount} in the group.\n> Left at: ${leaveTime} on ${leaveDate}"`, contextInfo: { 44 | mentionedJid: [jid], 45 | externalAdReply: { 46 | title: `Leave`, 47 | mediaType: 1, 48 | previewType: 0, 49 | renderLargerThumbnail: true, 50 | thumbnailUrl: profile, 51 | sourceUrl: 'https://sid-bhai.vercel.app' 52 | } 53 | } 54 | }) 55 | } 56 | } 57 | } catch (e) { 58 | throw e 59 | } 60 | } -------------------------------------------------------------------------------- /src/plugin/audioeffect.js: -------------------------------------------------------------------------------- 1 | import { exec } from 'child_process'; 2 | import fs from 'fs'; 3 | import { getRandom } from '../../lib/myfunc.cjs'; 4 | import config from '../../config.cjs'; 5 | 6 | const audioEffects = async (m, gss) => { 7 | try { 8 | const prefix = config.PREFIX; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | const text = m.body.slice(prefix.length + cmd.length).trim(); 11 | 12 | const validCommands = ['bass', 'blown', 'deep', 'earrape', 'fast', 'fat', 'nightcore', 'reverse', 'robot', 'slow', 'smooth', 'tupai']; 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | let set; 16 | if (cmd === 'bass') { 17 | set = '-af equalizer=f=54:width_type=o:width=2:g=20'; 18 | } else if (cmd === 'blown') { 19 | set = '-af acrusher=.1:1:64:0:log'; 20 | } else if (cmd === 'deep') { 21 | set = '-af atempo=4/4,asetrate=44500*2/3'; 22 | } else if (cmd === 'earrape') { 23 | set = '-af volume=12'; 24 | } else if (cmd === 'fast') { 25 | set = '-filter:a "atempo=1.63,asetrate=44100"'; 26 | } else if (cmd === 'fat') { 27 | set = '-filter:a "atempo=1.6,asetrate=22100"'; 28 | } else if (cmd === 'nightcore') { 29 | set = '-filter:a atempo=1.06,asetrate=44100*1.25'; 30 | } else if (cmd === 'reverse') { 31 | set = '-filter_complex "areverse"'; 32 | } else if (cmd === 'robot') { 33 | set = '-filter_complex "afftfilt=real=\'hypot(re,im)*sin(0)\':imag=\'hypot(re,im)*cos(0)\':win_size=512:overlap=0.75"'; 34 | } else if (cmd === 'slow') { 35 | set = '-filter:a "atempo=0.7,asetrate=44100"'; 36 | } else if (cmd === 'smooth') { 37 | set = '-filter:v "minterpolate=\'mi_mode=mci:mc_mode=aobmc:vsbmc=1:fps=120\'"'; 38 | } else if (cmd === 'tupai') { 39 | set = '-filter:a "atempo=0.5,asetrate=65100"'; 40 | } 41 | 42 | if (!m.quoted || m.quoted.mtype !== 'audioMessage') { 43 | return m.reply(`Reply to the audio you want to change with a caption *${prefix + cmd}*`); 44 | } 45 | 46 | m.reply('Please wait...'); 47 | const media = await m.quoted.download(); 48 | const mediaPath = `./${getRandom('.webm')}`; 49 | fs.writeFileSync(mediaPath, media); 50 | const outputPath = `./${getRandom('.mp3')}`; 51 | 52 | exec(`ffmpeg -i ${mediaPath} ${set} ${outputPath}`, (err, stderr, stdout) => { 53 | fs.unlinkSync(mediaPath); 54 | if (err) { 55 | console.error('Error:', err); 56 | return m.reply('An error occurred while processing the audio.'); 57 | } 58 | const buff = fs.readFileSync(outputPath); 59 | gss.sendMessage(m.from, { audio: buff, mimetype: 'audio/mpeg' }, { quoted: m }); 60 | fs.unlinkSync(outputPath); 61 | }); 62 | } catch (e) { 63 | console.error('Error:', e); 64 | m.reply('An error occurred while processing the command.'); 65 | } 66 | }; 67 | 68 | export default audioEffects; 69 | -------------------------------------------------------------------------------- /src/plugin/trt.js: -------------------------------------------------------------------------------- 1 | import Tesseract from 'tesseract.js'; 2 | import translate from 'translate-google-api'; 3 | import { writeFile } from 'fs/promises'; 4 | import config from '../../config.cjs'; 5 | 6 | const translateCommand = async (m, sock) => { 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 9 | const args = m.body.slice(prefix.length + cmd.length).trim(); 10 | 11 | 12 | const validCommands = ['translate', 'trt']; 13 | 14 | if (validCommands.includes(cmd)) { 15 | const targetLang = args[0]; 16 | const text = args.slice(1).join(' '); 17 | 18 | if (m.quoted) { 19 | if (m.quoted.mtype === 'imageMessage') { 20 | try { 21 | const media = await m.quoted.download(); 22 | if (!media) throw new Error('Failed to download media.'); 23 | 24 | const filePath = `./${Date.now()}.png`; 25 | await writeFile(filePath, media); 26 | const { data: { text: extractedText } } = await Tesseract.recognize(filePath, 'eng', { 27 | logger: m => console.log(m) 28 | }); 29 | 30 | const result = await translate(extractedText, { to: targetLang }); 31 | const translatedText = result[0]; 32 | 33 | const responseMessage = `${targetLang}:\n\n${translatedText}`; 34 | await sock.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 35 | } catch (error) { 36 | console.error("Error extracting and translating text from image:", error); 37 | await sock.sendMessage(m.from, { text: 'Error extracting and translating text from image.' }, { quoted: m }); 38 | } 39 | } else if (m.quoted.text) { 40 | try { 41 | const quotedText = m.quoted.text; 42 | const result = await translate(quotedText, { to: targetLang }); 43 | const translatedText = result[0]; 44 | 45 | const responseMessage = `${targetLang}:\n\n${translatedText}`; 46 | await sock.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 47 | } catch (error) { 48 | console.error("Error translating quoted text:", error); 49 | await sock.sendMessage(m.from, { text: 'Error translating quoted text.' }, { quoted: m }); 50 | } 51 | } 52 | } else if (text && targetLang) { 53 | try { 54 | const result = await translate(text, { to: targetLang }); 55 | const translatedText = result[0]; 56 | 57 | const responseMessage = `${targetLang}:\n\n${translatedText}`; 58 | await sock.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 59 | } catch (error) { 60 | console.error("Error translating text:", error); 61 | await sock.sendMessage(m.from, { text: 'Error translating text.' }, { quoted: m }); 62 | } 63 | } else { 64 | const responseMessage = "Usage: /translate \nExample: /translate en कैसे हो भाई\nOr reply to an image/text message with /translate "; 65 | await sock.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 66 | } 67 | } 68 | }; 69 | 70 | export default translateCommand; 71 | -------------------------------------------------------------------------------- /src/remini.cjs: -------------------------------------------------------------------------------- 1 | //Ethix-MD-V2 2 | 3 | const FormData = require("form-data"); 4 | async function remini(_0x33b965, _0x34eff3) { 5 | return new Promise(async (_0x14db15, _0x267c15) => { 6 | let _0x45d85b = ['enhance', "recolor", "dehaze"]; 7 | if (_0x45d85b.includes(_0x34eff3)) { 8 | _0x34eff3 = _0x34eff3; 9 | } else { 10 | _0x34eff3 = _0x45d85b[0x0]; 11 | } 12 | let _0x370778 = new FormData(); 13 | let _0x5c019f = "https://inferenceengine.vyro.ai/" + _0x34eff3; 14 | _0x370778.append("model_version", 0x1, { 15 | 'Content-Transfer-Encoding': "binary", 16 | 'contentType': "multipart/form-data; charset=uttf-8" 17 | }); 18 | _0x370778.append('image', Buffer.from(_0x33b965), { 19 | 'filename': "enhance_image_body.jpg", 20 | 'contentType': "image/jpeg" 21 | }); 22 | _0x370778.submit({ 23 | 'url': _0x5c019f, 24 | 'host': "inferenceengine.vyro.ai", 25 | 'path': '/' + _0x34eff3, 26 | 'protocol': "https:", 27 | 'headers': { 28 | 'User-Agent': 'okhttp/4.9.3', 29 | 'Connection': "Keep-Alive", 30 | 'Accept-Encoding': "gzip" 31 | } 32 | }, function (_0x319120, _0x175e8d) { 33 | if (_0x319120) { 34 | _0x267c15(); 35 | } 36 | let _0x15e24d = []; 37 | _0x175e8d.on('data', function (_0x2918a5, _0x2d4e53) { 38 | _0x15e24d.push(_0x2918a5); 39 | }).on("end", () => { 40 | _0x14db15(Buffer.concat(_0x15e24d)); 41 | }); 42 | _0x175e8d.on("error", _0x90e19c => { 43 | _0x267c15(); 44 | }); 45 | }); 46 | }); 47 | } 48 | module.exports.remini = remini; 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/plugin/crick.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | import axios from 'axios'; 3 | 4 | const cricketScore = async (m, Matrix) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const text = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const validCommands = ['score', 'crick', 'crickterscore', 'cricket']; 10 | 11 | if (validCommands.includes(cmd)) { 12 | if (!text) { 13 | await m.React("❌"); 14 | return m.reply(`*Provide a match ID for cricket score.*\nExample: ${prefix}cricketscore 12345`); 15 | } 16 | 17 | const matchId = encodeURIComponent(text); 18 | 19 | try { 20 | const apiUrl = `https://iol.apinepdev.workers.dev/${matchId}`; 21 | const response = await axios.get(apiUrl); 22 | 23 | if (!response.status === 200) { 24 | await m.React("❌"); 25 | return m.reply(`Invalid response from the cricket score API. Status code: ${response.status}`); 26 | } 27 | 28 | const result = response.data; 29 | 30 | let formattedResult = `╭══════════════•∞•══╮\n`; 31 | formattedResult += `│⿻ *🐼𝐑𝐎𝐌𝐄𝐊 𝐗𝐃🐠*\n`; 32 | formattedResult += `│⿻ *LIVE MATCH INFO* ✨\n`; 33 | formattedResult += `│⿻\n`; 34 | 35 | if (result.code === 200) { 36 | formattedResult += `│⿻ *${result.data.title}*\n`; 37 | formattedResult += `│⿻ *${result.data.update}*\n`; 38 | formattedResult += `│⿻ \n`; 39 | } else { 40 | await m.reply(`*Update:* Data not found for the specified match ID.`); 41 | await m.React("❌"); 42 | return; 43 | } 44 | 45 | if (result.data.liveScore && result.data.liveScore.toLowerCase() !== "data not found") { 46 | formattedResult += `│⿻ *Live Score:* ${result.data.liveScore}\n`; 47 | formattedResult += `│⿻ *Run Rate:* ${result.data.runRate}\n`; 48 | formattedResult += `│⿻\n`; 49 | formattedResult += `│⿻ *Batter 1:* ${result.data.batsmanOne}\n`; 50 | formattedResult += `│⿻ *${result.data.batsmanOneRun} (${result.data.batsmanOneBall})* SR: ${result.data.batsmanOneSR}\n`; 51 | formattedResult += `│⿻\n`; 52 | formattedResult += `│⿻ *Batter 2:* ${result.data.batsmanTwo}\n`; 53 | formattedResult += `│⿻ *${result.data.batsmanTwoRun} (${result.data.batsmanTwoBall})* SR: ${result.data.batsmanTwoSR}\n`; 54 | formattedResult += `│⿻\n`; 55 | formattedResult += `│⿻ *Bowler 1:* ${result.data.bowlerOne}\n`; 56 | formattedResult += `│⿻ *${result.data.bowlerOneOver} overs, ${result.data.bowlerOneRun}/${result.data.bowlerOneWickets}, Econ:* ${result.data.bowlerOneEconomy}\n`; 57 | formattedResult += `│⿻\n`; 58 | formattedResult += `│⿻ *Bowler 2:* ${result.data.bowlerTwo}\n`; 59 | formattedResult += `│⿻ *${result.data.bowlerTwoOver} overs, ${result.data.bowlerTwoRun}/${result.data.bowlerTwoWicket}, Econ:* ${result.data.bowlerTwoEconomy}\n`; 60 | } 61 | 62 | formattedResult += `╰══•∞•═══════════════╯ `; 63 | 64 | await m.reply(formattedResult); 65 | await m.React("✅"); 66 | } catch (error) { 67 | console.error(error); 68 | await m.React("❌"); 69 | return m.reply(`An error occurred while processing the cricket score request. ${error.message}`); 70 | } 71 | } 72 | }; 73 | 74 | export default cricketScore; 75 | -------------------------------------------------------------------------------- /src/plugin/fetch-vv.js: -------------------------------------------------------------------------------- 1 | import pkg from '@whiskeysockets/baileys'; 2 | const { downloadMediaMessage } = pkg; 3 | import config from '../config.cjs'; 4 | 5 | const OwnerCmd = async (m, Matrix) => { 6 | const botNumber = Matrix.user.id.split(':')[0] + '@s.whatsapp.net'; 7 | const ownerNumber = config.OWNER_NUMBER + '@s.whatsapp.net'; 8 | const prefix = config.PREFIX; 9 | 10 | // Check if sender is Owner or Bot 11 | const isOwner = m.sender === ownerNumber; 12 | const isBot = m.sender === botNumber; 13 | const isAuthorized = isOwner || isBot; 14 | 15 | // Extract command if prefixed 16 | const cmd = m.body.startsWith(prefix) 17 | ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() 18 | : ''; 19 | 20 | // Detect reaction on View Once message 21 | const isReaction = m.message?.reactionMessage; 22 | const reactedToViewOnce = isReaction && m.quoted && (m.quoted.message.viewOnceMessage || m.quoted.message.viewOnceMessageV2); 23 | 24 | // Detect emoji reply (alone or with text) only on View Once media 25 | const isEmojiReply = m.body && /^[\p{Emoji}](\s|\S)*$/u.test(m.body.trim()) && 26 | m.quoted && (m.quoted.message.viewOnceMessage || m.quoted.message.viewOnceMessageV2); 27 | 28 | // Secret Mode = Emoji Reply or Reaction (For Bot/Owner Only) on View Once media 29 | const secretMode = (isEmojiReply || reactedToViewOnce) && isAuthorized; 30 | 31 | // Allow only `.vv`, `.vv2`, `.vv3` 32 | if (cmd && !['vv', 'vv2', 'vv3'].includes(cmd)) return; 33 | 34 | // Restrict VV commands properly 35 | if (cmd && !isAuthorized) return m.reply('*Only the owner or bot can use this command!*'); 36 | 37 | // If not command & not secret mode, exit 38 | if (!cmd && !secretMode) return; 39 | 40 | // Ensure the message is a reply to a View Once message 41 | const targetMessage = reactedToViewOnce ? m.quoted : m; 42 | if (!targetMessage.quoted) return; 43 | 44 | let msg = targetMessage.quoted.message; 45 | if (msg.viewOnceMessageV2) msg = msg.viewOnceMessageV2.message; 46 | else if (msg.viewOnceMessage) msg = msg.viewOnceMessage.message; 47 | 48 | // Additional check to ensure it's media (image, video, or audio) 49 | const messageType = msg ? Object.keys(msg)[0] : null; 50 | const isMedia = messageType && ['imageMessage', 'videoMessage', 'audioMessage'].includes(messageType); 51 | 52 | if (!msg || !isMedia) return; 53 | 54 | try { 55 | let buffer = await downloadMediaMessage(targetMessage.quoted, 'buffer'); 56 | if (!buffer) return; 57 | 58 | let mimetype = msg.audioMessage?.mimetype || 'audio/ogg'; 59 | let caption = `> *© ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ*`; 60 | 61 | // Set recipient 62 | let recipient = secretMode || cmd === 'vv2' 63 | ? botNumber 64 | : cmd === 'vv3' 65 | ? ownerNumber 66 | : m.from; 67 | 68 | if (messageType === 'imageMessage') { 69 | await Matrix.sendMessage(recipient, { image: buffer, caption }); 70 | } else if (messageType === 'videoMessage') { 71 | await Matrix.sendMessage(recipient, { video: buffer, caption, mimetype: 'video/mp4' }); 72 | } else if (messageType === 'audioMessage') { 73 | await Matrix.sendMessage(recipient, { audio: buffer, mimetype, ptt: true }); 74 | } 75 | 76 | // Silent execution for secret mode 77 | if (!cmd) return; 78 | m.reply('*Media sent successfully!*'); 79 | 80 | } catch (error) { 81 | console.error(error); 82 | if (cmd) await m.reply('*Failed to process View Once message!*'); 83 | } 84 | }; 85 | 86 | export default OwnerCmd; 87 | -------------------------------------------------------------------------------- /src/uploader.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import FormData from 'form-data'; 3 | import fetch from 'node-fetch'; 4 | import fs from 'fs'; 5 | import * as cheerio from 'cheerio'; 6 | import mime from 'mime'; 7 | 8 | export const TelegraPh = async (path) => { 9 | return new Promise(async (resolve, reject) => { 10 | if (!fs.existsSync(path)) return reject(new Error("File not Found")); 11 | try { 12 | const form = new FormData(); 13 | form.append("file", fs.createReadStream(path)); 14 | const { data } = await axios({ 15 | url: "https://telegra.ph/upload", 16 | method: "POST", 17 | headers: { 18 | ...form.getHeaders() 19 | }, 20 | data: form 21 | }); 22 | resolve("https://telegra.ph" + data[0].src); 23 | } catch (err) { 24 | reject(new Error(String(err))); 25 | } 26 | }); 27 | }; 28 | 29 | export const UploadFileUgu = async (input) => { 30 | return new Promise(async (resolve, reject) => { 31 | try { 32 | const form = new FormData(); 33 | form.append("files[]", fs.createReadStream(input)); 34 | const { data } = await axios({ 35 | url: "https://uguu.se/upload.php", 36 | method: "POST", 37 | headers: { 38 | "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", 39 | ...form.getHeaders() 40 | }, 41 | data: form 42 | }); 43 | resolve(data.files[0]); 44 | } catch (err) { 45 | reject(err); 46 | } 47 | }); 48 | }; 49 | 50 | export const webp2mp4File = async (path) => { 51 | return new Promise(async (resolve, reject) => { 52 | try { 53 | const form = new FormData(); 54 | form.append('new-image-url', ''); 55 | form.append('new-image', fs.createReadStream(path)); 56 | const { data: step1Data } = await axios({ 57 | method: 'post', 58 | url: 'https://s6.ezgif.com/webp-to-mp4', 59 | data: form, 60 | headers: { 61 | 'Content-Type': `multipart/form-data; boundary=${form._boundary}` 62 | } 63 | }); 64 | const $ = cheerio.load(step1Data); 65 | const file = $('input[name="file"]').attr('value'); 66 | const formThen = new FormData(); 67 | formThen.append('file', file); 68 | formThen.append('convert', "Convert WebP to MP4!"); 69 | const { data: step2Data } = await axios({ 70 | method: 'post', 71 | url: `https://ezgif.com/webp-to-mp4/${file}`, 72 | data: formThen, 73 | headers: { 74 | 'Content-Type': `multipart/form-data; boundary=${formThen._boundary}` 75 | } 76 | }); 77 | const $2 = cheerio.load(step2Data); 78 | const result = 'https:' + $2('div#output > p.outfile > video > source').attr('src'); 79 | resolve({ 80 | status: true, 81 | message: "Created By 𝐑𝐎𝐌𝐄𝐊 𝐗𝐃", 82 | result: result 83 | }); 84 | } catch (err) { 85 | reject(err); 86 | } 87 | }); 88 | }; 89 | 90 | export const floNime = async (path, options = {}) => { 91 | const ext = mime.getType(path); 92 | if (!ext) throw new Error('Unknown file type'); 93 | 94 | const form = new FormData(); 95 | form.append('file', fs.createReadStream(path), `tmp.${ext}`); 96 | const response = await fetch('https://flonime.my.id/upload', { 97 | method: 'POST', 98 | body: form 99 | }); 100 | const json = await response.json(); 101 | return json; 102 | }; 103 | 104 | export default { TelegraPh, UploadFileUgu, webp2mp4File, floNime }; 105 | -------------------------------------------------------------------------------- /src/plugin/githubstalk.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import config from '../config.cjs'; 3 | 4 | const githubStalk = async (m, gss) => { 5 | try { 6 | const prefix = config.PREFIX; 7 | const cmd = m.body.startsWith(prefix) 8 | ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() 9 | : ''; 10 | const text = m.body.slice(prefix.length + cmd.length).trim(); 11 | const args = text.split(' '); 12 | 13 | const validCommands = ['githubstalk', 'ghstalk']; 14 | 15 | if (validCommands.includes(cmd)) { 16 | if (!args[0]) return m.reply('❌ Please provide a GitHub username to stalk.'); 17 | 18 | const username = args[0]; 19 | await m.React('⏳'); 20 | 21 | try { 22 | const { data: userData, status } = await axios.get(`https://api.github.com/users/${username}`); 23 | if (status !== 200) return m.reply(`❌ GitHub user not found.`); 24 | 25 | let response = `👨‍💻 *GitHub Profile: @${userData.login}*\n\n`; 26 | response += ` ◦ *Name*: ${userData.name || 'N/A'}\n`; 27 | response += ` ◦ *Username*: @${userData.login}\n`; 28 | response += ` ◦ *Bio*: ${userData.bio || 'N/A'}\n`; 29 | response += ` ◦ *ID*: ${userData.id}\n`; 30 | response += ` ◦ *Node ID*: ${userData.node_id}\n`; 31 | response += ` ◦ *Avatar*: ${userData.avatar_url}\n`; 32 | response += ` ◦ *Profile Link*: ${userData.html_url}\n`; 33 | response += ` ◦ *Type*: ${userData.type}\n`; 34 | response += ` ◦ *Admin*: ${userData.site_admin ? 'Yes' : 'No'}\n`; 35 | response += ` ◦ *Company*: ${userData.company || 'N/A'}\n`; 36 | response += ` ◦ *Blog*: ${userData.blog || 'N/A'}\n`; 37 | response += ` ◦ *Location*: ${userData.location || 'N/A'}\n`; 38 | response += ` ◦ *Email*: ${userData.email || 'N/A'}\n`; 39 | response += ` ◦ *Public Repos*: ${userData.public_repos}\n`; 40 | response += ` ◦ *Public Gists*: ${userData.public_gists}\n`; 41 | response += ` ◦ *Followers*: ${userData.followers}\n`; 42 | response += ` ◦ *Following*: ${userData.following}\n`; 43 | response += ` ◦ *Created At*: ${userData.created_at}\n`; 44 | response += ` ◦ *Last Updated*: ${userData.updated_at}`; 45 | 46 | const { data: reposData } = await axios.get( 47 | `https://api.github.com/users/${username}/repos?per_page=5&sort=stargazers_count&direction=desc` 48 | ); 49 | 50 | if (reposData.length > 0) { 51 | const repos = reposData.map(repo => ( 52 | `\n\n🔹 *${repo.name}*\n` + 53 | ` ◦ 📄 Description: ${repo.description || 'N/A'}\n` + 54 | ` ◦ ⭐ Stars: ${repo.stargazers_count}\n` + 55 | ` ◦ 🍴 Forks: ${repo.forks}\n` + 56 | ` ◦ 🔗 [View Repo](${repo.html_url})` 57 | )); 58 | response += `\n\n📚 *Top Repositories*${repos.join('')}`; 59 | } else { 60 | response += `\n\n📂 No public repositories found.`; 61 | } 62 | 63 | response += `\n\n📡 ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ`; 64 | 65 | await gss.sendMessage( 66 | m.from, 67 | { image: { url: userData.avatar_url }, caption: response }, 68 | { quoted: m } 69 | ); 70 | 71 | await m.React('✅'); 72 | } catch (error) { 73 | console.error('GitHub API error:', error); 74 | await m.React('❌'); 75 | await gss.sendMessage(m.from, { text: '❌ Error fetching GitHub data.' }, { quoted: m }); 76 | } 77 | } 78 | } catch (err) { 79 | console.error('Command error:', err); 80 | m.reply('❌ Error processing command.'); 81 | } 82 | }; 83 | 84 | export default githubStalk; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Typing SVG](https://readme-typing-svg.demolab.com?font=Ribeye&size=50&pause=1000&color=3F00FF¢er=true&width=900&height=100&lines=𝐑𝐎𝐌𝐄𝐊%20-𝐗𝐃;%20𝗠𝗨𝗟𝗧𝗜-𝗗𝗘𝗩𝗜𝗖𝗘%20𝗪𝗛𝗔𝗧𝗦𝗔𝗣𝗣%20𝗕𝗢𝗧;%20𝗗𝗘𝗩𝗘𝗟𝗢𝗣𝗘𝗗%20𝗕𝗬%20𝐑𝐎𝐌𝐄𝐊%20𝐗𝐃..💖) 2 |

3 |

4 | ROMEK-XD Logo 5 |

6 | --- 7 |

8 | 9 | GitHub Forks 10 | 11 | 12 | GitHub Stars 13 | 14 |

15 | -- 16 | 🚀 DEPLOYMENT METHODS 17 | 18 | ✅ Fork This Repo 19 | > Click below to fork this repository and start deploying. 20 |

21 | 22 | 23 | 24 |

25 | --- 26 | 🔑 Get Session ID (WhatsApp Pair Code Login) 27 | 28 | > To deploy, generate your session ID from the link below: 29 |

30 | 31 | 32 | 33 |

34 | --- 35 | 🚀 Deploy to Koyeb 36 | 37 | > Deploy your bot on Koyeb by clicking the button below: 38 |

39 | 40 | 41 | 42 |

43 | --- 44 | 🌍 Deploy to Render 45 | 46 | > Click below to deploy your bot on Render 47 |

48 | 49 | 50 | 51 |

52 | --- 53 | ☁️ Deploy to Heroku 54 | 55 | > Click below to deploy on Heroku easily: 56 |

57 | 58 | 59 | 60 |

61 | --- 62 | 🚆 Deploy to Railway 63 | 64 | > Click below to deploy on Railway: 65 |

66 | 67 | 68 | 69 |

70 | --- 71 | 👑 𝐑𝐎𝐌𝐄𝐊-𝐗𝐃 𝐁𝐎𝐓 𝐎𝐖𝐍𝐄𝐑 👨 72 | 73 |

74 | 75 | 76 | 77 |

78 | --- 79 | 80 | 🎉 THANK YOU FOR USING ROMEK-XD BOT! 🎉 81 | 82 |

83 | 84 | 85 | 86 |

87 | --- 88 | 89 | ## ❌ COPYRIGHT NOTICE: 90 | 91 | ## ❌ This README.md file is uniquely designed. DO NOT COPY. 92 | -------------------------------------------------------------------------------- /src/event/handler.js: -------------------------------------------------------------------------------- 1 | import { serialize, decodeJid } from '../../lib/Serializer.js'; 2 | import path from 'path'; 3 | import fs from 'fs/promises'; 4 | import config from '../../config.cjs'; 5 | import { smsg } from '../../lib/myfunc.cjs'; 6 | import { handleAntilink } from './antilink.js'; 7 | import { fileURLToPath } from 'url'; 8 | 9 | const __filename = fileURLToPath(import.meta.url); 10 | const __dirname = path.dirname(__filename); 11 | 12 | // Function to get group admins 13 | export const getGroupAdmins = (participants) => { 14 | let admins = []; 15 | for (let i of participants) { 16 | if (i.admin === "superadmin" || i.admin === "admin") { 17 | admins.push(i.id); 18 | } 19 | } 20 | return admins || []; 21 | }; 22 | 23 | const Handler = async (chatUpdate, sock, logger) => { 24 | try { 25 | if (chatUpdate.type !== 'notify') return; 26 | 27 | const m = serialize(JSON.parse(JSON.stringify(chatUpdate.messages[0])), sock, logger); 28 | if (!m.message) return; 29 | 30 | const participants = m.isGroup ? await sock.groupMetadata(m.from).then(metadata => metadata.participants) : []; 31 | const groupAdmins = m.isGroup ? getGroupAdmins(participants) : []; 32 | const botId = sock.user.id.split(':')[0] + '@s.whatsapp.net'; 33 | const isBotAdmins = m.isGroup ? groupAdmins.includes(botId) : false; 34 | const isAdmins = m.isGroup ? groupAdmins.includes(m.sender) : false; 35 | 36 | const PREFIX = /^[\\/!#.]/; 37 | const isCOMMAND = (body) => PREFIX.test(body); 38 | const prefixMatch = isCOMMAND(m.body) ? m.body.match(PREFIX) : null; 39 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 40 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 41 | const text = m.body.slice(prefix.length + cmd.length).trim(); 42 | 43 | if (m.key && m.key.remoteJid === 'status@broadcast' && config.AUTO_STATUS_SEEN) { 44 | await sock.readMessages([m.key]); 45 | } 46 | 47 | const botNumber = await sock.decodeJid(sock.user.id); 48 | const ownerNumber = config.OWNER_NUMBER + '@s.whatsapp.net'; 49 | let isCreator = false; 50 | 51 | if (m.isGroup) { 52 | isCreator = m.sender === ownerNumber || m.sender === botNumber; 53 | } else { 54 | isCreator = m.sender === ownerNumber || m.sender === botNumber; 55 | } 56 | 57 | if (!sock.public) { 58 | if (!isCreator) { 59 | return; 60 | } 61 | } 62 | 63 | await handleAntilink(m, sock, logger, isBotAdmins, isAdmins, isCreator); 64 | 65 | const { isGroup, type, sender, from, body } = m; 66 | console.log(m); 67 | 68 | const pluginDir = path.join(__dirname, '..', 'plugin'); 69 | const pluginFiles = await fs.readdir(pluginDir); 70 | 71 | for (const file of pluginFiles) { 72 | if (file.endsWith('.js')) { 73 | const pluginPath = path.join(pluginDir, file); 74 | // console.log(`Attempting to load plugin: ${pluginPath}`); 75 | 76 | try { 77 | const pluginModule = await import(`file://${pluginPath}`); 78 | const loadPlugins = pluginModule.default; 79 | await loadPlugins(m, sock); 80 | // console.log(`Successfully loaded plugin: ${pluginPath}`); 81 | } catch (err) { 82 | console.error(`Failed to load plugin: ${pluginPath}`, err); 83 | } 84 | } 85 | } 86 | } catch (e) { 87 | console.log(e); 88 | } 89 | }; 90 | 91 | export default Handler; 92 | -------------------------------------------------------------------------------- /src/plugin/lyrics.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 3 | const { generateWAMessageFromContent, proto } = pkg; 4 | import config from '../config.cjs'; 5 | 6 | const Lyrics = async (m, Matrix) => { 7 | const prefix = config.PREFIX; 8 | const cmd = m.body.startsWith(prefix) 9 | ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() 10 | : ''; 11 | const text = m.body.slice(prefix.length + cmd.length).trim(); 12 | 13 | const validCommands = ['lyrics', 'lyric']; 14 | 15 | if (validCommands.includes(cmd)) { 16 | if (!text) { 17 | return m.reply(`*Hello, ${m.pushName}*\n\n> _Example Usage:_\n\`\`\`.lyrics Spectre|Alan Walker\`\`\``); 18 | } 19 | 20 | try { 21 | await m.React('🕘'); 22 | await m.reply('_Please wait, fetching your lyrics..._'); 23 | 24 | if (!text.includes('|')) { 25 | return m.reply('⚠️ *Use the correct format:*\n\n_Song Name|Artist Name_\nExample: `.lyrics Shape of You|Ed Sheeran`'); 26 | } 27 | 28 | const [title, artist] = text.split('|').map(part => part.trim()); 29 | 30 | if (!title || !artist) { 31 | return m.reply('❗ *Both song and artist name are required.*\nExample: `.lyrics Believer|Imagine Dragons`'); 32 | } 33 | 34 | const apiUrl = `https://api.lyrics.ovh/v1/${encodeURIComponent(artist)}/${encodeURIComponent(title)}`; 35 | const response = await axios.get(apiUrl); 36 | const result = response.data; 37 | 38 | if (result && result.lyrics) { 39 | const lyrics = result.lyrics; 40 | 41 | let buttons = [ 42 | { 43 | name: "cta_copy", 44 | buttonParamsJson: JSON.stringify({ 45 | display_text: "📋 Copy Lyrics", 46 | id: "copy_code", 47 | copy_code: lyrics 48 | }) 49 | }, 50 | { 51 | name: "cta_url", 52 | buttonParamsJson: JSON.stringify({ 53 | display_text: "Support Romek-XD", 54 | url: `https://whatsapp.com/channel/0029Vaj1hl1Lo4hksSXY0U2t` 55 | }) 56 | }, 57 | { 58 | name: "quick_reply", 59 | buttonParamsJson: JSON.stringify({ 60 | display_text: "Main Menu", 61 | id: ".menu" 62 | }) 63 | } 64 | ]; 65 | 66 | let msg = generateWAMessageFromContent(m.from, { 67 | viewOnceMessage: { 68 | message: { 69 | messageContextInfo: { 70 | deviceListMetadata: {}, 71 | deviceListMetadataVersion: 2 72 | }, 73 | interactiveMessage: proto.Message.InteractiveMessage.create({ 74 | body: proto.Message.InteractiveMessage.Body.create({ text: lyrics }), 75 | footer: proto.Message.InteractiveMessage.Footer.create({ text: "ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ" }), 76 | header: proto.Message.InteractiveMessage.Header.create({ 77 | title: "", 78 | subtitle: "", 79 | hasMediaAttachment: false 80 | }), 81 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 82 | buttons: buttons 83 | }) 84 | }) 85 | } 86 | } 87 | }, {}); 88 | 89 | await Matrix.relayMessage(msg.key.remoteJid, msg.message, { 90 | messageId: msg.key.id 91 | }); 92 | 93 | await m.React('✅'); 94 | } else { 95 | throw new Error('No lyrics found.'); 96 | } 97 | } catch (error) { 98 | console.error('Error getting lyrics:', error.message); 99 | m.reply('❌ *An error occurred while fetching lyrics.*'); 100 | await m.React('❌'); 101 | } 102 | } 103 | }; 104 | 105 | export default Lyrics; -------------------------------------------------------------------------------- /src/plugin/autogroup.js: -------------------------------------------------------------------------------- 1 | import cron from 'node-cron'; 2 | import moment from 'moment-timezone'; 3 | import config from '../../config.cjs'; 4 | 5 | let scheduledTasks = {}; 6 | 7 | const groupSetting = async (m, gss) => { 8 | try { 9 | const prefix = config.PREFIX; 10 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 11 | const text = m.body.slice(prefix.length + cmd.length).trim(); 12 | 13 | const validCommands = ['group']; 14 | if (!validCommands.includes(cmd)) return; 15 | 16 | if (!m.isGroup) return m.reply("*❌ THIS COMMAND CAN ONLY BE USED IN GROUPS*"); 17 | const groupMetadata = await gss.groupMetadata(m.from); 18 | const participants = groupMetadata.participants; 19 | const botNumber = await gss.decodeJid(gss.user.id); 20 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 21 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 22 | 23 | if (!botAdmin) return m.reply("*❌ BOT MUST BE AN ADMIN TO USE THIS COMMAND*"); 24 | if (!senderAdmin) return m.reply("*❌ YOU MUST BE AN ADMIN TO USE THIS COMMAND*"); 25 | 26 | const args = m.body.slice(prefix.length + cmd.length).trim().split(/\s+/); 27 | if (args.length < 1) return m.reply(`Please specify a setting (open/close) and optionally a time.\n\nExample:\n*${prefix + cmd} open* or *${prefix + cmd} open 04:00 PM*`); 28 | 29 | const groupSetting = args[0].toLowerCase(); 30 | const time = args.slice(1).join(' '); 31 | 32 | // Handle immediate setting if no time is provided 33 | if (!time) { 34 | if (groupSetting === 'close') { 35 | await gss.groupSettingUpdate(m.from, 'announcement'); 36 | return m.reply("Group successfully closed."); 37 | } else if (groupSetting === 'open') { 38 | await gss.groupSettingUpdate(m.from, 'not_announcement'); 39 | return m.reply("Group successfully opened."); 40 | } else { 41 | return m.reply(`Invalid setting. Use "open" to open the group and "close" to close the group.\n\nExample:\n*${prefix + cmd} open* or *${prefix + cmd} close*`); 42 | } 43 | } 44 | 45 | // Check if the provided time is valid 46 | if (!/^\d{1,2}:\d{2}\s*(?:AM|PM)$/i.test(time)) { 47 | return m.reply(`Invalid time format. Use HH:mm AM/PM format.\n\nExample:\n*${prefix + cmd} open 04:00 PM*`); 48 | } 49 | 50 | // Convert time to 24-hour format 51 | const [hour, minute] = moment(time, ['h:mm A', 'hh:mm A']).format('HH:mm').split(':').map(Number); 52 | const cronTime = `${minute} ${hour} * * *`; 53 | 54 | console.log(`Scheduling ${groupSetting} at ${cronTime} IST`); 55 | 56 | // Clear any existing scheduled task for this group 57 | if (scheduledTasks[m.from]) { 58 | scheduledTasks[m.from].stop(); 59 | delete scheduledTasks[m.from]; 60 | } 61 | 62 | scheduledTasks[m.from] = cron.schedule(cronTime, async () => { 63 | try { 64 | console.log(`Executing scheduled task for ${groupSetting} at ${moment().format('HH:mm')} IST`); 65 | if (groupSetting === 'close') { 66 | await gss.groupSettingUpdate(m.from, 'announcement'); 67 | await gss.sendMessage(m.from, { text: "Group successfully closed." }); 68 | } else if (groupSetting === 'open') { 69 | await gss.groupSettingUpdate(m.from, 'not_announcement'); 70 | await gss.sendMessage(m.from, { text: "Group successfully opened." }); 71 | } 72 | } catch (err) { 73 | console.error('Error during scheduled task execution:', err); 74 | await gss.sendMessage(m.from, { text: 'An error occurred while updating the group setting.' }); 75 | } 76 | }, { 77 | timezone: "Asia/Kolkata" 78 | }); 79 | 80 | m.reply(`Group will be set to "${groupSetting}" at ${time} IST.`); 81 | } catch (error) { 82 | console.error('Error:', error); 83 | m.reply('An error occurred while processing the command.'); 84 | } 85 | }; 86 | 87 | export default groupSetting; 88 | -------------------------------------------------------------------------------- /src/plugin/tourl.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | import FormData from 'form-data'; 3 | import { fileTypeFromBuffer } from 'file-type'; 4 | import { writeFile, unlink } from 'fs/promises'; 5 | 6 | const MAX_FILE_SIZE_MB = 200; 7 | async function uploadMedia(buffer) { 8 | try { 9 | const { ext } = await fileTypeFromBuffer(buffer); 10 | const bodyForm = new FormData(); 11 | bodyForm.append("fileToUpload", buffer, "file." + ext); 12 | bodyForm.append("reqtype", "fileupload"); 13 | 14 | const res = await fetch("https://catbox.moe/user/api.php", { 15 | method: "POST", 16 | body: bodyForm, 17 | }); 18 | 19 | if (!res.ok) { 20 | throw new Error(`Upload failed with status ${res.status}: ${res.statusText}`); 21 | } 22 | 23 | const data = await res.text(); 24 | return data; 25 | } catch (error) { 26 | console.error("Error during media upload:", error); 27 | throw new Error('Failed to upload media'); 28 | } 29 | } 30 | 31 | const tourl = async (m, bot) => { 32 | const prefixMatch = m.body.match(/^[\\/!#.]/); 33 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 34 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 35 | const validCommands = ['tourl', 'geturl', 'upload', 'url']; 36 | 37 | if (validCommands.includes(cmd)) { 38 | if (!m.quoted || !['imageMessage', 'videoMessage', 'audioMessage'].includes(m.quoted.mtype)) { 39 | return m.reply(`Send/Reply/Quote an image, video, or audio to upload \n*${prefix + cmd}*`); 40 | } 41 | 42 | try { 43 | const loadingMessages = [ 44 | "*「▰▰▰▱▱▱▱▱▱▱」*", 45 | "*「▰▰▰▰▱▱▱▱▱▱」*", 46 | "*「▰▰▰▰▰▱▱▱▱▱」*", 47 | "*「▰▰▰▰▰▰▱▱▱▱」*", 48 | "*「▰▰▰▰▰▰▰▱▱▱」*", 49 | "*「▰▰▰▰▰▰▰▰▱▱」*", 50 | "*「▰▰▰▰▰▰▰▰▰▱」*", 51 | "*「▰▰▰▰▰▰▰▰▰▰」*", 52 | ]; 53 | 54 | const loadingMessageCount = loadingMessages.length; 55 | let currentMessageIndex = 0; 56 | 57 | const { key } = await bot.sendMessage(m.from, { text: loadingMessages[currentMessageIndex] }, { quoted: m }); 58 | 59 | const loadingInterval = setInterval(() => { 60 | currentMessageIndex = (currentMessageIndex + 1) % loadingMessageCount; 61 | bot.sendMessage(m.from, { text: loadingMessages[currentMessageIndex] }, { quoted: m, messageId: key }); 62 | }, 500); 63 | 64 | const media = await m.quoted.download(); 65 | if (!media) throw new Error('Failed to download media.'); 66 | 67 | const fileSizeMB = media.length / (1024 * 1024); 68 | if (fileSizeMB > MAX_FILE_SIZE_MB) { 69 | clearInterval(loadingInterval); 70 | return m.reply(`File size exceeds the limit of ${MAX_FILE_SIZE_MB}MB.`); 71 | } 72 | const mediaUrl = await uploadMedia(media); 73 | 74 | clearInterval(loadingInterval); 75 | await bot.sendMessage(m.from, { text: '✅ Loading complete.' }, { quoted: m }); 76 | 77 | const mediaType = getMediaType(m.quoted.mtype); 78 | if (mediaType === 'audio') { 79 | const message = { 80 | text: `*Hey ${m.pushName} Here Is Your Audio URL*\n*Url:* ${mediaUrl}`, 81 | }; 82 | await bot.sendMessage(m.from, message, { quoted: m }); 83 | } else { 84 | const message = { 85 | [mediaType]: { url: mediaUrl }, 86 | caption: `*Hey ${m.pushName} Here Is Your Media*\n*Url:* ${mediaUrl}`, 87 | }; 88 | await bot.sendMessage(m.from, message, { quoted: m }); 89 | } 90 | 91 | } catch (error) { 92 | console.error('Error processing media:', error); 93 | m.reply('Error processing media.'); 94 | } 95 | } 96 | }; 97 | 98 | const getMediaType = (mtype) => { 99 | switch (mtype) { 100 | case 'imageMessage': 101 | return 'image'; 102 | case 'videoMessage': 103 | return 'video'; 104 | case 'audioMessage': 105 | return 'audio'; 106 | default: 107 | return null; 108 | } 109 | }; 110 | 111 | export default tourl; 112 | -------------------------------------------------------------------------------- /src/plugin/alive.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 3 | import Jimp from 'jimp'; 4 | const { generateWAMessageFromContent, proto } = pkg; 5 | 6 | const alive = async (m, Matrix) => { 7 | const uptimeSeconds = process.uptime(); 8 | const days = Math.floor(uptimeSeconds / (3600 * 24)); 9 | const hours = Math.floor((uptimeSeconds % (3600 * 24)) / 3600); 10 | const minutes = Math.floor((uptimeSeconds % 3600) / 60); 11 | const seconds = Math.floor(uptimeSeconds % 60); 12 | const timeString = `${String(days).padStart(2, '0')}-${String(hours).padStart(2, '0')}-${String(minutes).padStart(2, '0')}-${String(seconds).padStart(2, '0')}`; 13 | const prefix = config.PREFIX; 14 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 15 | const text = m.body.slice(prefix.length + cmd.length).trim(); 16 | 17 | if (['alive', 'uptime', 'runtime'].includes(cmd)) { 18 | const width = 800; 19 | const height = 500; 20 | const image = new Jimp(width, height, 'black'); 21 | const font = await Jimp.loadFont(Jimp.FONT_SANS_128_WHITE); 22 | const textMetrics = Jimp.measureText(font, timeString); 23 | const textHeight = Jimp.measureTextHeight(font, timeString, width); 24 | const x = (width / 2) - (textMetrics / 2); 25 | const y = (height / 2) - (textHeight / 2); 26 | image.print(font, x, y, timeString, width, Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_MIDDLE); 27 | const buffer = await image.getBufferAsync(Jimp.MIME_PNG); 28 | 29 | const uptimeMessage = `*🧿𝗥𝗢𝗠𝗘𝗞-𝗫𝗗🪀 Status Overview* 30 | _________________________________________ 31 | 32 | *🌅 ${days} Day(s)* 33 | *📟 ${hours} Hour(s)* 34 | *🔭 ${minutes} Minute(s)* 35 | *⏰ ${seconds} Second(s)* 36 | _________________________________________ 37 | `; 38 | 39 | const buttons = [ 40 | { 41 | "name": "quick_reply", 42 | "buttonParamsJson": JSON.stringify({ 43 | display_text: "MENU", 44 | id: `${prefix}menu` 45 | }) 46 | }, 47 | { 48 | "name": "quick_reply", 49 | "buttonParamsJson": JSON.stringify({ 50 | display_text: "PING", 51 | id: `${prefix}ping` 52 | }) 53 | } 54 | ]; 55 | 56 | const msg = generateWAMessageFromContent(m.from, { 57 | viewOnceMessage: { 58 | message: { 59 | messageContextInfo: { 60 | deviceListMetadata: {}, 61 | deviceListMetadataVersion: 2 62 | }, 63 | interactiveMessage: proto.Message.InteractiveMessage.create({ 64 | body: proto.Message.InteractiveMessage.Body.create({ 65 | text: uptimeMessage 66 | }), 67 | footer: proto.Message.InteractiveMessage.Footer.create({ 68 | text: "© ᴘᴏᴡᴇʀᴅ ʙʏ romek-xᴅ-ʙᴏᴛ" 69 | }), 70 | header: proto.Message.InteractiveMessage.Header.create({ 71 | ...(await prepareWAMessageMedia({ image: buffer }, { upload: Matrix.waUploadToServer })), 72 | title: ``, 73 | gifPlayback: false, 74 | subtitle: "", 75 | hasMediaAttachment: false 76 | }), 77 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 78 | buttons 79 | }), 80 | contextInfo: { 81 | quotedMessage: m.message, 82 | forwardingScore: 999, 83 | isForwarded: true, 84 | forwardedNewsletterMessageInfo: { 85 | newsletterJid: '120363321472746562@newsletter', 86 | newsletterName: "𝐑𝐎𝐌𝐄𝐊 𝐗𝐃", 87 | serverMessageId: 143 88 | } 89 | } 90 | }), 91 | }, 92 | }, 93 | }, {}); 94 | 95 | await Matrix.relayMessage(msg.key.remoteJid, msg.message, { 96 | messageId: msg.key.id 97 | }); 98 | } 99 | }; 100 | 101 | export default alive; 102 | -------------------------------------------------------------------------------- /src/plugin/repo.js: -------------------------------------------------------------------------------- 1 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 2 | const { generateWAMessageFromContent, proto } = pkg; 3 | import axios from 'axios'; // Import axios for HTTP requests 4 | 5 | const handleRepoCommand = async (m, Matrix) => { 6 | const repoUrl = 'https://api.github.com/repos/ROMEKTRICKS/ROMEK-XD-V2'; 7 | try { 8 | const response = await axios.get(repoUrl); 9 | const repoData = response.data; 10 | 11 | const { full_name, name, forks_count, stargazers_count, created_at, updated_at, owner } = repoData; 12 | 13 | const messageText = `Hello *_${m.pushName}_,*\nThis is *ROMEK-XD,* A Whatsapp Bot Built by *ROMEKTRICKS,* Enhanced with Amazing Features to Make Your Whatsapp Communication and Interaction Experience Amazing\n\n*❲❒❳ ɴᴀᴍᴇ:* ${name}\n*❲❒❳ sᴛᴀʀs:* ${stargazers_count}\n*❲❒❳ ғᴏʀᴋs:* ${forks_count}\n*❲❒❳ ᴄʀᴇᴀᴛᴇᴅ ᴏɴ:* ${new Date(created_at).toLocaleDateString()}\n*❲❒❳ ʟᴀsᴛ ᴜᴘᴅᴀᴛᴇᴅ:* ${new Date(updated_at).toLocaleDateString()}`; 14 | 15 | const repoMessage = generateWAMessageFromContent(m.from, { 16 | viewOnceMessage: { 17 | message: { 18 | messageContextInfo: { 19 | deviceListMetadata: {}, 20 | deviceListMetadataVersion: 2 21 | }, 22 | interactiveMessage: proto.Message.InteractiveMessage.create({ 23 | body: proto.Message.InteractiveMessage.Body.create({ 24 | text: messageText 25 | }), 26 | footer: proto.Message.InteractiveMessage.Footer.create({ 27 | text: "*© ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ*" 28 | }), 29 | header: proto.Message.InteractiveMessage.Header.create({ 30 | ...(await prepareWAMessageMedia({ image: { url: `https://telegra.ph/file/fbbe1744668b44637c21a.jpg` } }, { upload: Matrix.waUploadToServer })), 31 | title: "", 32 | gifPlayback: true, 33 | subtitle: "", 34 | hasMediaAttachment: false 35 | }), 36 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 37 | buttons: [ 38 | { 39 | name: "quick_reply", 40 | buttonParamsJson: JSON.stringify({ 41 | display_text: "OWNER", 42 | id: ".owner" 43 | }) 44 | }, 45 | { 46 | name: "cta_url", 47 | buttonParamsJson: JSON.stringify({ 48 | display_text: "FOLLOW WACHANNEL", 49 | url: `https://whatsapp.com/channel/0029VakaPzeD38CV78dbGf0e` 50 | }) 51 | }, 52 | { 53 | name: "cta_url", 54 | buttonParamsJson: JSON.stringify({ 55 | display_text: "CLOCK HERE TO FORK", 56 | url: `https://github.com/ROMEKTRICKS/ROMEK-XD/fork` 57 | }) 58 | } 59 | ], 60 | }), 61 | contextInfo: { 62 | mentionedJid: [m.sender], 63 | forwardingScore: 9999, 64 | isForwarded: false, 65 | } 66 | }), 67 | }, 68 | }, 69 | }, {}); 70 | 71 | await Matrix.relayMessage(repoMessage.key.remoteJid, repoMessage.message, { 72 | messageId: repoMessage.key.id 73 | }); 74 | await m.React("✅"); 75 | 76 | } catch (error) { 77 | console.error("Error processing your request:", error); 78 | m.reply('Error processing your request.'); 79 | await m.React("❌"); 80 | } 81 | }; 82 | 83 | const searchRepo = async (m, Matrix) => { 84 | // const prefixMatch = m.body.match(/^[\\/!#.]/); 85 | const prefixMatch = m.body.match(/^[+×÷=/_<>[\]!@#.£%^&*()\-"'1234567890?,°€£^:;?¿‽】〕」』【〔「『<>_${}\|`《○♡○¡☆《●●■◇¡¤▪︎•°~♡●♧₩$€○》☆¡Abcdefghijklmonpqrstuvwxyz]/i); 86 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 87 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 88 | 89 | const validCommands = ['repo', 'sc', 'script']; 90 | 91 | if (validCommands.includes(cmd)) { 92 | await handleRepoCommand(m, Matrix); 93 | } 94 | }; 95 | 96 | export default searchRepo; 97 | -------------------------------------------------------------------------------- /src/event/antilink.js: -------------------------------------------------------------------------------- 1 | import { serialize } from '../../lib/Serializer.js'; 2 | 3 | const antilinkSettings = {}; // In-memory database to store antilink settings for each chat 4 | 5 | export const handleAntilink = async (m, sock, logger, isBotAdmins, isAdmins, isCreator) => { 6 | const PREFIX = /^[\\/!#.]/; 7 | const isCOMMAND = (body) => PREFIX.test(body); 8 | const prefixMatch = isCOMMAND(m.body) ? m.body.match(PREFIX) : null; 9 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 10 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 11 | 12 | if (cmd === 'antilink') { 13 | const args = m.body.slice(prefix.length + cmd.length).trim().split(/\s+/); 14 | const action = args[0] ? args[0].toLowerCase() : ''; 15 | 16 | if (!m.isGroup) { 17 | await sock.sendMessage(m.from, { text: 'This command can only be used in groups.' }, { quoted: m }); 18 | return; 19 | } 20 | 21 | if (!isBotAdmins) { 22 | await sock.sendMessage(m.from, { text: 'The bot needs to be an admin to manage the antilink feature.' }, { quoted: m }); 23 | return; 24 | } 25 | 26 | if (action === 'on') { 27 | if (isAdmins) { 28 | antilinkSettings[m.from] = true; 29 | await sock.sendMessage(m.from, { text: 'Antilink feature has been enabled for this chat.' }, { quoted: m }); 30 | } else { 31 | await sock.sendMessage(m.from, { text: 'Only admins can enable the antilink feature.' }, { quoted: m }); 32 | } 33 | return; 34 | } 35 | 36 | if (action === 'off') { 37 | if (isAdmins) { 38 | antilinkSettings[m.from] = false; 39 | await sock.sendMessage(m.from, { text: 'Antilink feature has been disabled for this chat.' }, { quoted: m }); 40 | } else { 41 | await sock.sendMessage(m.from, { text: 'Only admins can disable the antilink feature.' }, { quoted: m }); 42 | } 43 | return; 44 | } 45 | 46 | await sock.sendMessage(m.from, { text: `Usage: ${prefix + cmd} on\n ${prefix + cmd} off` }, { quoted: m }); 47 | return; 48 | } 49 | 50 | if (antilinkSettings[m.from]) { 51 | if (m.body.match(/(chat.whatsapp.com\/)/gi)) { 52 | if (!isBotAdmins) { 53 | await sock.sendMessage(m.from, { text: `The bot needs to be an admin to remove links.` }); 54 | return; 55 | } 56 | let gclink = `https://chat.whatsapp.com/${await sock.groupInviteCode(m.from)}`; 57 | let isLinkThisGc = new RegExp(gclink, 'i'); 58 | let isgclink = isLinkThisGc.test(m.body); 59 | if (isgclink) { 60 | await sock.sendMessage(m.from, { text: `The link you shared is for this group, so you won't be removed.` }); 61 | return; 62 | } 63 | if (isAdmins) { 64 | await sock.sendMessage(m.from, { text: `Admins are allowed to share links.` }); 65 | return; 66 | } 67 | if (isCreator) { 68 | await sock.sendMessage(m.from, { text: `The owner is allowed to share links.` }); 69 | return; 70 | } 71 | 72 | // Send warning message first 73 | await sock.sendMessage(m.from, { 74 | text: `\`\`\`「 Group Link Detected 」\`\`\`\n\n@${m.sender.split("@")[0]}, please do not share group links in this group.`, 75 | contextInfo: { mentionedJid: [m.sender] } 76 | }, { quoted: m }); 77 | 78 | // Delete the link message 79 | await sock.sendMessage(m.from, { 80 | delete: { 81 | remoteJid: m.from, 82 | fromMe: false, 83 | id: m.key.id, 84 | participant: m.key.participant 85 | } 86 | }); 87 | 88 | // Wait for a short duration before kicking 89 | setTimeout(async () => { 90 | await sock.groupParticipantsUpdate(m.from, [m.sender], 'remove'); 91 | }, 5000); // 5 seconds delay before kick 92 | } 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /src/plugin/tohd2.js: -------------------------------------------------------------------------------- 1 | import { createRequire } from 'module'; 2 | import path from 'path'; 3 | import axios from 'axios'; 4 | import FormData from 'form-data'; 5 | import fs from 'fs-extra'; 6 | 7 | const require = createRequire(import.meta.url); 8 | const __filename = new URL(import.meta.url).pathname; 9 | const __dirname = path.dirname(__filename); 10 | 11 | class ImgLarger { 12 | constructor() { 13 | this.baseURL = 'https://get1.imglarger.com/api/Upscaler'; 14 | this.headers = { 15 | 'Accept': 'application/json, text/plain, */*', 16 | 'Origin': 'https://imgupscaler.com', 17 | 'Referer': 'https://imgupscaler.com/', 18 | 'User-Agent': 'Postify/1.0.0', 19 | 'X-Forwarded-For': Array(4).fill(0).map(() => Math.floor(Math.random() * 256)).join('.') 20 | }; 21 | this.retryLimit = 3; 22 | } 23 | 24 | async uploadImage(input, scaleRadio = 2, isLogin = 0) { 25 | const formData = new FormData(); 26 | if (Buffer.isBuffer(input)) { 27 | formData.append('myfile', input, { filename: 'uploaded_image.jpg' }); 28 | } else { 29 | throw new Error('Invalid input. Provide a buffer.'); 30 | } 31 | formData.append('scaleRadio', scaleRadio); 32 | formData.append('isLogin', isLogin); 33 | try { 34 | console.log('Uploading image, please wait...'); 35 | const response = await axios.post(`${this.baseURL}/Upload`, formData, { 36 | headers: { ...this.headers, ...formData.getHeaders() }, 37 | maxContentLength: Infinity, 38 | maxBodyLength: Infinity, 39 | onUploadProgress: progressEvent => { 40 | this.showProgress(progressEvent.loaded, progressEvent.total); 41 | } 42 | }); 43 | if (response.data.code === 999) { 44 | throw new Error('API limit exceeded.'); 45 | } 46 | return response.data; 47 | } catch (error) { 48 | throw new Error('Image upload failed.'); 49 | } 50 | } 51 | 52 | showProgress(loaded, total) { 53 | const percentage = Math.round((loaded / total) * 100); 54 | process.stdout.write(`\rUploading: ${percentage}%\n`); 55 | } 56 | 57 | async checkStatus(code, scaleRadio, isLogin) { 58 | const payload = { code, scaleRadio, isLogin }; 59 | try { 60 | const response = await axios.post(`${this.baseURL}/CheckStatus`, payload, { headers: this.headers }); 61 | return response.data; 62 | } catch (error) { 63 | throw new Error('Failed to check task status.'); 64 | } 65 | } 66 | 67 | async processImage(input, scaleRadio = 2, isLogin = 0, retries = 0) { 68 | try { 69 | const { data: { code } } = await this.uploadImage(input, scaleRadio, isLogin); 70 | let status; 71 | do { 72 | status = await this.checkStatus(code, scaleRadio, isLogin); 73 | if (status.data.status === 'waiting') { 74 | await this.delay(5000); 75 | } 76 | } while (status.data.status === 'waiting'); 77 | return status; 78 | } catch (error) { 79 | if (retries < this.retryLimit) { 80 | return await this.processImage(input, scaleRadio, isLogin, retries + 1); 81 | } else { 82 | throw new Error('Process failed after multiple attempts.'); 83 | } 84 | } 85 | } 86 | 87 | delay(ms) { 88 | return new Promise(resolve => setTimeout(resolve, ms)); 89 | } 90 | } 91 | 92 | const hd = async (m, gss) => { 93 | const prefixMatch = m.body.match(/^[\\/!#.]/); 94 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 95 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 96 | const validCommands = ['hdr', 'hd', 'remini', 'enhance', 'upscale']; 97 | 98 | if (validCommands.includes(cmd)) { 99 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 100 | return m.reply(`*Send/Reply with an Image to Enhance Your Picture Quality ${prefix + cmd}*`); 101 | } 102 | 103 | const media = await m.quoted.download(); 104 | const imgLarger = new ImgLarger(); 105 | 106 | try { 107 | const result = await imgLarger.processImage(media, 4); 108 | const enhancedImageUrl = result.data.downloadUrls[0]; 109 | 110 | gss.sendMessage(m.from, { image: { url: enhancedImageUrl }, caption: `> *Hey ${m.pushName}, here is your enhanced image*\n*©𝐏𝐎𝐖𝐄𝐑𝐄𝐃 𝐁𝐘 𝐑𝐎𝐌𝐄𝐊 𝐗𝐃*` }, { quoted: m }); 111 | 112 | } catch (error) { 113 | console.error('Error processing media:', error); 114 | m.reply('Error processing media.'); 115 | } 116 | } 117 | }; 118 | 119 | export default hd; 120 | -------------------------------------------------------------------------------- /src/plugin/gpinfo.js: -------------------------------------------------------------------------------- 1 | import { writeFile } from 'fs/promises'; 2 | import config from '../config.cjs'; 3 | 4 | const groupInfoCommand = async (m, sock) => { 5 | const prefix = config.PREFIX; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | const args = m.body.slice(prefix.length + cmd.length).trim(); 8 | 9 | const validCommands = ['ginfo', 'gpinfo', 'groupinfo', 'gcinfo']; 10 | 11 | if (validCommands.includes(cmd)) { 12 | try { 13 | // Function to format creation date 14 | const formatCreationDate = (timestamp) => { 15 | if (!timestamp) return 'Unknown'; 16 | const date = new Date(timestamp * 1000); 17 | return date.toLocaleString('en-US', { 18 | weekday: 'long', 19 | year: 'numeric', 20 | month: 'long', 21 | day: 'numeric', 22 | hour: '2-digit', 23 | minute: '2-digit', 24 | second: '2-digit', 25 | timeZoneName: 'short' 26 | }); 27 | }; 28 | 29 | // Function to fetch and format group info 30 | const getGroupInfo = async (groupId, sock) => { 31 | try { 32 | const groupMetadata = await sock.groupMetadata(groupId); 33 | const participants = groupMetadata.participants; 34 | 35 | // Get creator info 36 | const creator = groupMetadata.owner || 'Unknown'; 37 | 38 | // Get admins 39 | const admins = participants.filter(p => p.admin).map(p => p.id); 40 | 41 | // Prepare response 42 | let response = `*Group Info*\n\n`; 43 | response += `*Name:* ${groupMetadata.subject}\n`; 44 | response += `*Description:* ${groupMetadata.desc || 'No description'}\n`; 45 | response += `*Created:* ${formatCreationDate(groupMetadata.creation)}\n`; 46 | response += `*Creator:* ${creator}\n`; 47 | response += `*Total Members:* ${participants.length}\n`; 48 | response += `*Admins:* ${admins.length}\n`; 49 | 50 | // Try to get group picture 51 | try { 52 | const ppUrl = await sock.profilePictureUrl(groupId, 'image'); 53 | return { response, ppUrl }; 54 | } catch (e) { 55 | return { response }; 56 | } 57 | } catch (error) { 58 | throw error; 59 | } 60 | }; 61 | 62 | // Check if the command is used in a group 63 | const isGroup = m.isGroup; 64 | const groupLink = args.trim(); 65 | 66 | if (isGroup) { 67 | // Fetch info for the current group 68 | const { response, ppUrl } = await getGroupInfo(m.from, sock); 69 | 70 | if (ppUrl) { 71 | await sock.sendMessage(m.from, { 72 | image: { url: ppUrl }, 73 | caption: response 74 | }, { quoted: m }); 75 | } else { 76 | await sock.sendMessage(m.from, { text: response }, { quoted: m }); 77 | } 78 | } else if (groupLink) { 79 | // Handle group invite link 80 | if (!groupLink.includes('chat.whatsapp.com')) { 81 | await sock.sendMessage(m.from, { text: 'Please provide a valid WhatsApp group invite link.' }, { quoted: m }); 82 | return; 83 | } 84 | 85 | // Extract group ID from link 86 | const groupId = groupLink.split('/').pop(); 87 | 88 | try { 89 | // Verify the group exists and get basic info first 90 | const inviteInfo = await sock.groupGetInviteInfo(groupId); 91 | 92 | // Now fetch full metadata 93 | const { response, ppUrl } = await getGroupInfo(inviteInfo.id, sock); 94 | 95 | if (ppUrl) { 96 | await sock.sendMessage(m.from, { 97 | image: { url: ppUrl }, 98 | caption: response 99 | }, { quoted: m }); 100 | } else { 101 | await sock.sendMessage(m.from, { text: response }, { quoted: m }); 102 | } 103 | } catch (error) { 104 | console.error("Error fetching group info from link:", error); 105 | await sock.sendMessage(m.from, { 106 | text: 'Error fetching group info. Make sure:\n1. The link is valid\n2. You have permission to view this group\n3. The group exists' 107 | }, { quoted: m }); 108 | } 109 | } else { 110 | // Command used in private chat without link 111 | await sock.sendMessage(m.from, { 112 | text: 'Please use this command in a group or provide a group invite link.\n\nExample: .gcinfo https://chat.whatsapp.com/XXXXXXXXXXXX' 113 | }, { quoted: m }); 114 | } 115 | } catch (error) { 116 | console.error("Error in group info command:", error); 117 | await sock.sendMessage(m.from, { text: 'An error occurred while fetching group information.' }, { quoted: m }); 118 | } 119 | } 120 | }; 121 | 122 | export default groupInfoCommand; 123 | -------------------------------------------------------------------------------- /src/plugin/help.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment-timezone'; 2 | import fs from 'fs'; 3 | import os from 'os'; 4 | import pkg from '@whiskeysockets/baileys'; 5 | const { generateWAMessageFromContent, proto } = pkg; 6 | import config from '../config.cjs'; 7 | 8 | // Get total memory and free memory in bytes 9 | const totalMemoryBytes = os.totalmem(); 10 | const freeMemoryBytes = os.freemem(); 11 | 12 | // Define unit conversions 13 | const byteToKB = 1 / 1024; 14 | const byteToMB = byteToKB / 1024; 15 | const byteToGB = byteToMB / 1024; 16 | 17 | // Function to format bytes to a human-readable format 18 | function formatBytes(bytes) { 19 | if (bytes >= Math.pow(1024, 3)) { 20 | return (bytes * byteToGB).toFixed(2) + ' GB'; 21 | } else if (bytes >= Math.pow(1024, 2)) { 22 | return (bytes * byteToMB).toFixed(2) + ' MB'; 23 | } else if (bytes >= 1024) { 24 | return (bytes * byteToKB).toFixed(2) + ' KB'; 25 | } else { 26 | return bytes.toFixed(2) + ' bytes'; 27 | } 28 | } 29 | 30 | // Bot Process Time 31 | const uptime = process.uptime(); 32 | const day = Math.floor(uptime / (24 * 3600)); // Calculate days 33 | const hours = Math.floor((uptime % (24 * 3600)) / 3600); // Calculate hours 34 | const minutes = Math.floor((uptime % 3600) / 60); // Calculate minutes 35 | const seconds = Math.floor(uptime % 60); // Calculate seconds 36 | 37 | // Uptime 38 | const uptimeMessage = `*I am alive now since ${day}d ${hours}h ${minutes}m ${seconds}s*`; 39 | const runMessage = `*☀️ ${day} Day*\n*🕐 ${hours} Hour*\n*⏰ ${minutes} Minutes*\n*⏱️ ${seconds} Seconds*\n`; 40 | 41 | const xtime = moment.tz("Asia/Colombo").format("HH:mm:ss"); 42 | const xdate = moment.tz("Asia/Colombo").format("DD/MM/YYYY"); 43 | const time2 = moment().tz("Asia/Colombo").format("HH:mm:ss"); 44 | let pushwish = ""; 45 | 46 | if (time2 < "05:00:00") { 47 | pushwish = `Good Morning 🌄`; 48 | } else if (time2 < "11:00:00") { 49 | pushwish = `Good Morning 🌄`; 50 | } else if (time2 < "15:00:00") { 51 | pushwish = `Good Afternoon 🌅`; 52 | } else if (time2 < "18:00:00") { 53 | pushwish = `Good Evening 🌃`; 54 | } else if (time2 < "19:00:00") { 55 | pushwish = `Good Evening 🌃`; 56 | } else { 57 | pushwish = `Good Night 🌌`; 58 | } 59 | 60 | const test = async (m, Matrix) => { 61 | const prefix = config.PREFIX; 62 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 63 | const mode = config.MODE === 'public' ? 'public' : 'private'; 64 | const pref = config.PREFIX; 65 | 66 | const validCommands = ['list', 'help', 'menu']; 67 | 68 | if (validCommands.includes(cmd)) { 69 | const str = `╭╔════════════════════╗ 70 | 🌟 *ROMEK-XD BOT* 🌟 71 | ╚════════════════════╝ 72 | 73 | 👑 *Owner:* ROMEk-XD 74 | 👤 *User:* ${m.pushName} 75 | 🛠 *Baileys:* Multi Device 76 | ⚙ *Type:* NodeJs 77 | 🔄 *Mode:* ${mode} 78 | 📟 *Platform:* ${os.platform()} 79 | 🔎 *Prefix:* [${prefix}] 80 | 🔎 *Version:* 1.1.0 81 | 82 | 🎉 *Hello ${m.pushName}, ${pushwish}!* 🎉 83 | 84 | ━━━━━━━━━━━━━━━ 85 | 🌟 *CONVERTER* 🌟 86 | ━━━━━━━━━━━━━━━ 87 | 🔎 ${prefix}attp 88 | 🔎 ${prefix}attp2 89 | 🔎 ${prefix}attp3 90 | 🔎 ${prefix}ebinary 91 | 🔎 ${prefix}dbinary 92 | 🔎 ${prefix}emojimix 93 | 🔎 ${prefix}mp3 94 | 95 | ━━━━━━━━━━━━━━━ 96 | 🤖 *AI TOOLS* 🤖 97 | ━━━━━━━━━━━━━━━ 98 | 🔎 ${prefix}ai 99 | 🔎 ${prefix}bug 100 | 🔎 ${prefix}report 101 | 🔎 ${prefix}gpt 102 | 🔎 ${prefix}dalle 103 | 🔎 ${prefix}remini 104 | 🔎 ${prefix}gemini 105 | 106 | ━━━━━━━━━━━━━━━ 107 | 🛠 *TOOLS* 🛠 108 | ━━━━━━━━━━━━━━━ 109 | 🔎 ${prefix}calculator 110 | 🔎 ${prefix}tempmail 111 | 🔎 ${prefix}checkmail 112 | 🔎 ${prefix}trt 113 | 🔎 ${prefix}tts 114 | 115 | ━━━━━━━━━━━━━━━ 116 | 📢 *GROUP* 📢 117 | ━━━━━━━━━━━━━━━ 118 | 🔎 ${prefix}linkgroup 119 | 🔎 ${prefix}setppgc 120 | 🔎 ${prefix}setname 121 | 🔎 ${prefix}setdesc 122 | 🔎 ${prefix}group 123 | 🔎 ${prefix}add 124 | 🔎 ${prefix}kick 125 | 🔎 ${prefix}hidetag 126 | 127 | ━━━━━━━━━━━━━━━ 128 | ⬇ *DOWNLOAD* ⬇ 129 | ━━━━━━━━━━━━━━━ 130 | 🔎 ${prefix}apk 131 | 🔎 ${prefix}facebook 132 | 🔎 ${prefix}mediafire 133 | 🔎 ${prefix}pinterest 134 | 🔎 ${prefix}gitclone 135 | 🔎 ${prefix}ytmp3 136 | 🔎 ${prefix}ytmp4 137 | 🔎 ${prefix}tiktok 138 | 139 | ━━━━━━━━━━━━━━━ 140 | 🔎 *SEARCH* 🔎 141 | ━━━━━━━━━━━━━━━ 142 | 🔎 ${prefix}play 143 | 🔎 ${prefix}yts 144 | 🔎 ${prefix}imdb 145 | 🔎 ${prefix}google 146 | 🔎 ${prefix}gimage 147 | 🔎 ${prefix}pinterest 148 | 🔎 ${prefix}wallpaper 149 | 🔎 ${prefix}lyrics 150 | 151 | ━━━━━━━━━━━━━━━ 152 | 🏆 *OWNER* 🏆 153 | ━━━━━━━━━━━━━━━ 154 | 🔎 ${prefix}join 155 | 🔎 ${prefix}leave 156 | 🔎 ${prefix}block 157 | 🔎 ${prefix}unblock 158 | 🔎 ${prefix}setppbot 159 | 🔎 ${prefix}anticall 160 | 🔎 ${prefix}autotyping 161 | 162 | ━━━━━━━━━━━━━━━ 163 | 🕵‍♂ *STALKING* 🕵‍♂ 164 | ━━━━━━━━━━━━━━━ 165 | 🔎 ${prefix}truecaller 166 | 🔎 ${prefix}instastalk 167 | 🔎 ${prefix}githubstalk 168 | 169 | 🔥 *Powered by ROMEK-XD* 🔥`; 170 | 171 | await Matrix.sendMessage(m.from, { 172 | image: fs.readFileSync('./src/romek.jpg'), 173 | caption: str, 174 | contextInfo: { 175 | mentionedJid: [m.sender], 176 | forwardingScore: 999, 177 | isForwarded: true, 178 | forwardedNewsletterMessageInfo: { 179 | newsletterJid: '120363321472746562@newsletter', 180 | newsletterName: "ROMEKTRICKS", 181 | serverMessageId: 143 182 | } 183 | } 184 | }, { 185 | quoted: m 186 | }); 187 | 188 | // Send audio after sending the menu 189 | await Matrix.sendMessage(m.from, { 190 | audio: { url: 'https://github.com/JawadYTX/KHAN-DATA/raw/refs/heads/main/autovoice/menunew.m4a' }, 191 | mimetype: 'audio/mp4', 192 | ptt: true 193 | }, { quoted: m }); 194 | } 195 | }; 196 | 197 | export default test; 198 | -------------------------------------------------------------------------------- /src/plugin/gpt.js: -------------------------------------------------------------------------------- 1 | import { promises as fs } from 'fs'; 2 | import path from 'path'; 3 | import fetch from 'node-fetch'; 4 | import pkg from '@whiskeysockets/baileys'; 5 | const { generateWAMessageFromContent, proto } = pkg; 6 | import config from '../config.cjs'; 7 | 8 | // File path setup 9 | const __filename = new URL(import.meta.url).pathname; 10 | const __dirname = path.dirname(__filename); 11 | const chatHistoryFile = path.resolve(__dirname, '../mistral_history.json'); 12 | 13 | // System prompt for the AI 14 | const mistralSystemPrompt = "You are a good assistant."; 15 | 16 | // Utility Functions 17 | const readChatHistoryFromFile = async () => { 18 | try { 19 | const data = await fs.readFile(chatHistoryFile, 'utf-8'); 20 | return JSON.parse(data); 21 | } catch (err) { 22 | return {}; 23 | } 24 | }; 25 | 26 | const writeChatHistoryToFile = async (chatHistory) => { 27 | try { 28 | await fs.writeFile(chatHistoryFile, JSON.stringify(chatHistory, null, 2)); 29 | } catch (err) { 30 | console.error('✖ Error writing chat history:', err); 31 | } 32 | }; 33 | 34 | const updateChatHistory = async (chatHistory, sender, message) => { 35 | chatHistory[sender] = chatHistory[sender] || []; 36 | chatHistory[sender].push(message); 37 | if (chatHistory[sender].length > 20) chatHistory[sender].shift(); 38 | await writeChatHistoryToFile(chatHistory); 39 | }; 40 | 41 | const deleteChatHistory = async (chatHistory, userId) => { 42 | delete chatHistory[userId]; 43 | await writeChatHistoryToFile(chatHistory); 44 | }; 45 | 46 | // Main Mistral Function 47 | const mistral = async (m, Matrix) => { 48 | const chatHistory = await readChatHistoryFromFile(); 49 | const text = m.body.toLowerCase(); 50 | 51 | // Handle /forget command 52 | if (text === '/forget') { 53 | await deleteChatHistory(chatHistory, m.sender); 54 | await Matrix.sendMessage(m.from, { text: '✨ Conversation wiped successfully!' }, { quoted: m }); 55 | return; 56 | } 57 | 58 | // Command parsing 59 | const prefix = config.PREFIX; 60 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 61 | const prompt = m.body.slice(prefix.length + cmd.length).trim(); 62 | const validCommands = ['ai', 'gpt', 'mistral']; 63 | 64 | if (validCommands.includes(cmd)) { 65 | if (!prompt) { 66 | await Matrix.sendMessage(m.from, { text: '⚠ Please provide a prompt!' }, { quoted: m }); 67 | return; 68 | } 69 | 70 | try { 71 | const senderChatHistory = chatHistory[m.sender] || []; 72 | const messages = [ 73 | { role: 'system', content: mistralSystemPrompt }, 74 | ...senderChatHistory, 75 | { role: 'user', content: prompt }, 76 | ]; 77 | 78 | await m.React('⏳'); // Processing reaction 79 | 80 | // API call to MatrixCoder 81 | const response = await fetch('https://matrixcoder.tech/api/ai', { 82 | method: 'POST', 83 | headers: { 'Content-Type': 'application/json' }, 84 | body: JSON.stringify({ 85 | type: 'text-generation', 86 | model: 'hf/meta-llama/meta-llama-3-8b-instruct', 87 | messages, 88 | }), 89 | }); 90 | 91 | if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); 92 | const { result } = await response.json(); 93 | const answer = result.response; 94 | 95 | // Update chat history 96 | await updateChatHistory(chatHistory, m.sender, { role: 'user', content: prompt }); 97 | await updateChatHistory(chatHistory, m.sender, { role: 'assistant', content: answer }); 98 | 99 | // Handle code blocks in response 100 | const codeMatch = answer.match(/```([\s\S]*?)```/); 101 | if (codeMatch) { 102 | const code = codeMatch[1]; 103 | const msg = generateWAMessageFromContent(m.from, { 104 | viewOnceMessage: { 105 | message: { 106 | messageContextInfo: { deviceListMetadata: {}, deviceListMetadataVersion: 2 }, 107 | interactiveMessage: proto.Message.InteractiveMessage.create({ 108 | body: proto.Message.InteractiveMessage.Body.create({ text: answer }), 109 | footer: proto.Message.InteractiveMessage.Footer.create({ text: 'ᴘᴏᴡᴇʀᴇᴅ ʙʏ ʀᴏᴍᴇᴋ-xᴅ' }), 110 | header: proto.Message.InteractiveMessage.Header.create({ title: '', subtitle: '', hasMediaAttachment: false }), 111 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 112 | buttons: [{ 113 | name: 'cta_copy', 114 | buttonParamsJson: JSON.stringify({ 115 | display_text: '📋 Copy Code', 116 | id: 'copy_code', 117 | copy_code: code, 118 | }), 119 | }], 120 | }), 121 | }), 122 | }, 123 | }, 124 | }, {}); 125 | 126 | await Matrix.relayMessage(msg.key.remoteJid, msg.message, { messageId: msg.key.id }); 127 | } else { 128 | await Matrix.sendMessage(m.from, { text: answer }, { quoted: m }); 129 | } 130 | 131 | await m.React('✅'); // Success reaction 132 | } catch (err) { 133 | await Matrix.sendMessage(m.from, { text: '❌ Oops! Something went wrong.' }, { quoted: m }); 134 | console.error('✖ Error:', err); 135 | await m.React('❌'); // Error reaction 136 | } 137 | } 138 | }; 139 | 140 | export default mistral; -------------------------------------------------------------------------------- /src/plugin/fbdown.js: -------------------------------------------------------------------------------- 1 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 2 | const { generateWAMessageFromContent, proto } = pkg; 3 | import getFBInfo from '@xaviabot/fb-downloader'; 4 | import config from '../../config.cjs'; 5 | 6 | const fbSearchResultsMap = new Map(); 7 | let fbSearchIndex = 1; 8 | 9 | const facebookCommand = async (m, Matrix) => { 10 | let selectedListId; 11 | const selectedButtonId = m?.message?.templateButtonReplyMessage?.selectedId; 12 | const interactiveResponseMessage = m?.message?.interactiveResponseMessage; 13 | 14 | if (interactiveResponseMessage) { 15 | const paramsJson = interactiveResponseMessage.nativeFlowResponseMessage?.paramsJson; 16 | if (paramsJson) { 17 | const params = JSON.parse(paramsJson); 18 | selectedListId = params.id; 19 | } 20 | } 21 | 22 | const selectedId = selectedListId || selectedButtonId; 23 | 24 | const prefix = config.PREFIX; 25 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 26 | const text = m.body.slice(prefix.length + cmd.length).trim(); 27 | 28 | const validCommands = ['facebook', 'fb', 'fbdl']; 29 | 30 | if (validCommands.includes(cmd)) { 31 | if (!text) { 32 | return m.reply('Please provide a Facebook video URL.'); 33 | } 34 | 35 | try { 36 | await m.React("🔜"); 37 | 38 | const fbData = await getFBInfo(text); 39 | console.log("fbData:", fbData); // Log the data structure 40 | 41 | if (!fbData) { 42 | await m.reply('No results found.'); 43 | await m.React("❌"); 44 | return; 45 | } 46 | 47 | fbSearchResultsMap.set(fbSearchIndex, fbData); 48 | 49 | const videoQualities = []; 50 | if (fbData.sd) { 51 | videoQualities.push({ resolution: 'SD', url: fbData.sd }); 52 | } 53 | if (fbData.hd) { 54 | videoQualities.push({ resolution: 'HD', url: fbData.hd }); 55 | } 56 | 57 | const buttons = videoQualities.map((video, index) => ({ 58 | "name": "quick_reply", 59 | "buttonParamsJson": JSON.stringify({ 60 | display_text: `📥 Download ${video.resolution}`, 61 | id: `fbmedia_${index}_${fbSearchIndex}` 62 | }) 63 | })); 64 | 65 | const sections = videoQualities.map((video) => ({ 66 | title: 'Video Qualities', 67 | rows: [{ 68 | title: `📥 Download ${video.resolution}`, 69 | description: `Resolution: ${video.resolution}`, 70 | id: `fbmedia_${fbSearchIndex}_${video.resolution}` 71 | }] 72 | })); 73 | 74 | const msg = generateWAMessageFromContent(m.from, { 75 | viewOnceMessage: { 76 | message: { 77 | messageContextInfo: { 78 | deviceListMetadata: {}, 79 | deviceListMetadataVersion: 2 80 | }, 81 | interactiveMessage: proto.Message.InteractiveMessage.create({ 82 | body: proto.Message.InteractiveMessage.Body.create({ 83 | text: `*𝐑𝐎𝐌𝐄𝐊 𝐗𝐃 FACEBOOK POST DOWNLOADER*\n\n> *TITLE*: ${fbData.title}` 84 | }), 85 | footer: proto.Message.InteractiveMessage.Footer.create({ 86 | text: "©𝐏𝐎𝐖𝐄𝐑𝐄𝐃 𝐁𝐘 𝐑𝐎𝐌𝐄𝐊 𝐗𝐃" 87 | }), 88 | header: proto.Message.InteractiveMessage.Header.create({ 89 | ...(await prepareWAMessageMedia({ image: { url: fbData.thumbnail } }, { upload: Matrix.waUploadToServer })), 90 | title: "", 91 | gifPlayback: true, 92 | subtitle: "", 93 | hasMediaAttachment: false 94 | }), 95 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 96 | buttons 97 | }), 98 | contextInfo: { 99 | quotedMessage: m.message, 100 | mentionedJid: [m.sender], 101 | forwardingScore: 9999, 102 | isForwarded: true, 103 | } 104 | }), 105 | }, 106 | }, 107 | }, {}); 108 | 109 | await Matrix.relayMessage(msg.key.remoteJid, msg.message, { 110 | messageId: msg.key.id 111 | }); 112 | await m.React("✅"); 113 | 114 | fbSearchIndex += 1; 115 | } catch (error) { 116 | console.error("Error processing your request:", error); 117 | await m.reply('Error processing your request.'); 118 | await m.React("❌"); 119 | } 120 | } else if (selectedId) { 121 | if (selectedId.startsWith('fbmedia_')) { 122 | const parts = selectedId.split('_'); 123 | const qualityIndex = parseInt(parts[1]); 124 | const key = parseInt(parts[2]); 125 | const selectedMedia = fbSearchResultsMap.get(key); 126 | 127 | if (selectedMedia) { 128 | try { 129 | const videoQualities = []; 130 | if (selectedMedia.sd) { 131 | videoQualities.push({ resolution: 'SD', url: selectedMedia.sd }); 132 | } 133 | if (selectedMedia.hd) { 134 | videoQualities.push({ resolution: 'HD', url: selectedMedia.hd }); 135 | } 136 | 137 | const videoUrl = videoQualities[qualityIndex].url; 138 | let finalMediaBuffer, mimeType, content; 139 | 140 | finalMediaBuffer = await getStreamBuffer(videoUrl); 141 | mimeType = 'video/mp4'; 142 | 143 | const fileSizeInMB = finalMediaBuffer.length / (1024 * 1024); 144 | 145 | if (fileSizeInMB <= 300) { 146 | content = { 147 | video: finalMediaBuffer, 148 | mimetype: 'video/mp4', 149 | caption: '©𝐏𝐎𝐖𝐄𝐑𝐄𝐃 𝐁𝐘 𝐑𝐎𝐌𝐄𝐊 𝐗𝐃', 150 | }; 151 | await Matrix.sendMessage(m.from, content, { quoted: m }); 152 | } else { 153 | await m.reply('The video file size exceeds 300MB.'); 154 | } 155 | } catch (error) { 156 | console.error("Error processing your request:", error); 157 | await m.reply('Error processing your request.'); 158 | await m.React("❌"); 159 | } 160 | } 161 | } 162 | } 163 | }; 164 | 165 | const getStreamBuffer = async (url) => { 166 | const response = await fetch(url); 167 | const buffer = await response.arrayBuffer(); 168 | return Buffer.from(buffer); 169 | }; 170 | 171 | export default facebookCommand; 172 | -------------------------------------------------------------------------------- /lib/exif.cjs: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const { tmpdir } = require("os") 3 | const Crypto = require("crypto") 4 | const ff = require('fluent-ffmpeg') 5 | const webp = require("node-webpmux") 6 | const path = require("path") 7 | 8 | async function imageToWebp (media) { 9 | 10 | const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 11 | const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.jpg`) 12 | 13 | fs.writeFileSync(tmpFileIn, media) 14 | 15 | await new Promise((resolve, reject) => { 16 | ff(tmpFileIn) 17 | .on("error", reject) 18 | .on("end", () => resolve(true)) 19 | .addOutputOptions([ 20 | "-vcodec", 21 | "libwebp", 22 | "-vf", 23 | "scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease,fps=15, pad=320:320:-1:-1:color=white@0.0, split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse" 24 | ]) 25 | .toFormat("webp") 26 | .save(tmpFileOut) 27 | }) 28 | 29 | const buff = fs.readFileSync(tmpFileOut) 30 | fs.unlinkSync(tmpFileOut) 31 | fs.unlinkSync(tmpFileIn) 32 | return buff 33 | } 34 | 35 | async function videoToWebp (media) { 36 | 37 | const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 38 | const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.mp4`) 39 | 40 | fs.writeFileSync(tmpFileIn, media) 41 | 42 | await new Promise((resolve, reject) => { 43 | ff(tmpFileIn) 44 | .on("error", reject) 45 | .on("end", () => resolve(true)) 46 | .addOutputOptions([ 47 | "-vcodec", 48 | "libwebp", 49 | "-vf", 50 | "scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease,fps=15, pad=320:320:-1:-1:color=white@0.0, split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse", 51 | "-loop", 52 | "0", 53 | "-ss", 54 | "00:00:00", 55 | "-t", 56 | "00:00:05", 57 | "-preset", 58 | "default", 59 | "-an", 60 | "-vsync", 61 | "0" 62 | ]) 63 | .toFormat("webp") 64 | .save(tmpFileOut) 65 | }) 66 | 67 | const buff = fs.readFileSync(tmpFileOut) 68 | fs.unlinkSync(tmpFileOut) 69 | fs.unlinkSync(tmpFileIn) 70 | return buff 71 | } 72 | 73 | async function writeExifImg (media, metadata) { 74 | let wMedia = await imageToWebp(media) 75 | const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 76 | const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 77 | fs.writeFileSync(tmpFileIn, wMedia) 78 | 79 | if (metadata.packname || metadata.author) { 80 | const img = new webp.Image() 81 | const json = { "sticker-pack-id": `https://github.com/DikaArdnt/Hisoka-Morou`, "sticker-pack-name": metadata.packname, "sticker-pack-publisher": metadata.author, "emojis": metadata.categories ? metadata.categories : [""] } 82 | 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]) 83 | const jsonBuff = Buffer.from(JSON.stringify(json), "utf-8") 84 | const exif = Buffer.concat([exifAttr, jsonBuff]) 85 | exif.writeUIntLE(jsonBuff.length, 14, 4) 86 | await img.load(tmpFileIn) 87 | fs.unlinkSync(tmpFileIn) 88 | img.exif = exif 89 | await img.save(tmpFileOut) 90 | return tmpFileOut 91 | } 92 | } 93 | 94 | async function writeExifVid (media, metadata) { 95 | let wMedia = await videoToWebp(media) 96 | const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 97 | const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 98 | fs.writeFileSync(tmpFileIn, wMedia) 99 | 100 | if (metadata.packname || metadata.author) { 101 | const img = new webp.Image() 102 | const json = { "sticker-pack-id": `https://github.com/DikaArdnt/Hisoka-Morou`, "sticker-pack-name": metadata.packname, "sticker-pack-publisher": metadata.author, "emojis": metadata.categories ? metadata.categories : [""] } 103 | 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]) 104 | const jsonBuff = Buffer.from(JSON.stringify(json), "utf-8") 105 | const exif = Buffer.concat([exifAttr, jsonBuff]) 106 | exif.writeUIntLE(jsonBuff.length, 14, 4) 107 | await img.load(tmpFileIn) 108 | fs.unlinkSync(tmpFileIn) 109 | img.exif = exif 110 | await img.save(tmpFileOut) 111 | return tmpFileOut 112 | } 113 | } 114 | 115 | async function writeExif (media, metadata) { 116 | let wMedia = /webp/.test(media.mimetype) ? media.data : /image/.test(media.mimetype) ? await imageToWebp(media.data) : /video/.test(media.mimetype) ? await videoToWebp(media.data) : "" 117 | const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 118 | const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 119 | fs.writeFileSync(tmpFileIn, wMedia) 120 | 121 | if (metadata.packname || metadata.author) { 122 | const img = new webp.Image() 123 | const json = { "sticker-pack-id": `https://github.com/DikaArdnt/Hisoka-Morou`, "sticker-pack-name": metadata.packname, "sticker-pack-publisher": metadata.author, "emojis": metadata.categories ? metadata.categories : [""] } 124 | 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]) 125 | const jsonBuff = Buffer.from(JSON.stringify(json), "utf-8") 126 | const exif = Buffer.concat([exifAttr, jsonBuff]) 127 | exif.writeUIntLE(jsonBuff.length, 14, 4) 128 | await img.load(tmpFileIn) 129 | fs.unlinkSync(tmpFileIn) 130 | img.exif = exif 131 | await img.save(tmpFileOut) 132 | return tmpFileOut 133 | } 134 | } 135 | 136 | module.exports = { imageToWebp, videoToWebp, writeExifImg, writeExifVid, writeExif } 137 | --------------------------------------------------------------------------------