├── lib ├── README.md ├── binary.cjs ├── converter.cjs └── exif.cjs ├── src ├── README.md ├── event │ ├── README.md │ ├── index.js │ ├── call-handler.js │ ├── group-handler.js │ ├── handler.js │ └── antilink.js ├── plugin │ ├── README.md │ ├── fuck.js │ ├── ping.js │ ├── restart.js │ ├── dbinary.js │ ├── ebinary.js │ ├── autoaction.js │ ├── tquoted.js │ ├── exit.js │ ├── owner.js │ ├── flirt.js │ ├── tomp3.js │ ├── waifu.js │ ├── readqr.js │ ├── block.js │ ├── unblock.js │ ├── del.js │ ├── linkgc.js │ ├── lyrics.js │ ├── hd.js │ ├── autoread.js │ ├── mode.js │ ├── autoblock.js │ ├── autodown.js │ ├── autoreact.js │ ├── qrgenerater.js │ ├── autotyping.js │ ├── setgroupname.js │ ├── Anticall.js │ ├── alwaysonline.js │ ├── autorecording.js │ ├── setdesc.js │ ├── insta.js │ ├── report.js │ ├── emojimix.js │ ├── autodl.js │ ├── mediafiredl.js │ ├── gdrive.js │ ├── join.js │ ├── imagetotext.js │ ├── autos.js │ ├── gemini.js │ ├── pinterestdl.js │ ├── tagall.js │ ├── cal.js │ ├── hidetag.js │ ├── getpaircode.js │ ├── fetch.js │ ├── tboxdl.js │ ├── gimage.js │ ├── welcome.js │ ├── invite.js │ ├── romovebg.js │ ├── status.js │ ├── remove.js │ ├── demote.js │ ├── imdb.js │ ├── fullpp.js │ ├── rvo.js │ ├── whatmusic.js │ ├── qc.js │ ├── sticker.js │ ├── gcfullpp.js │ ├── promote.js │ ├── audioeffect.js │ ├── alive.js │ ├── crick.js │ ├── trt.js │ ├── repo.js │ ├── video.js │ ├── song.js │ ├── autogroup.js │ ├── sahan.js │ ├── githubstalk.js │ ├── tourl.js │ ├── gfgpt.js │ ├── apkdown.js │ ├── fbdown.js │ └── tiktokdl.js ├── auth_info_baileys │ └── MASTER-MD ├── master.jpg ├── watermark.png ├── generateProfilePicture.js ├── remini.cjs ├── uploader.js ├── setvar.js └── index.js ├── Procfile ├── heroku.yml ├── Dockerfile ├── .github ├── workflows │ └── deploy.yml └── README.md ├── config.cjs ├── app.json └── package.json /lib/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/event/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/plugin/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/auth_info_baileys/MASTER-MD: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node . --server 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/plugin/fuck.js: -------------------------------------------------------------------------------- 1 | /*😂_අනේ උබ හුකහන් පොන්නයා_😂*/ 2 | -------------------------------------------------------------------------------- /src/master.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrMasterOfc/MASTER-MD-V3/HEAD/src/master.jpg -------------------------------------------------------------------------------- /src/watermark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrMasterOfc/MASTER-MD-V3/HEAD/src/watermark.png -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | web: Dockerfile 4 | 5 | run: 6 | web: node . 7 | -------------------------------------------------------------------------------- /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 }; -------------------------------------------------------------------------------- /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 | WORKDIR /usr/src/app 12 | 13 | COPY package.json . 14 | 15 | RUN npm install && npm install -g qrcode-terminal pm2 16 | 17 | COPY . . 18 | 19 | EXPOSE 5000 20 | 21 | CMD ["npm", "start"] 22 | 23 | -------------------------------------------------------------------------------- /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 Sir_*`, 8 | mentions: [id.from], 9 | }); 10 | await sock.rejectCall(id.id, id.from); 11 | } 12 | } 13 | }; 14 | 15 | export default Callupdate; 16 | -------------------------------------------------------------------------------- /src/plugin/ping.js: -------------------------------------------------------------------------------- 1 | const ping = async (m, sock) => { 2 | const prefix = /^[\\/!#.]/gi.test(m.body) ? m.body.match(/^[\\/!#.]/gi)[0] : '/'; 3 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).toLowerCase() : ''; 4 | 5 | if (cmd === "ping") { 6 | const start = new Date().getTime(); 7 | await m.React('⚡'); 8 | const end = new Date().getTime(); 9 | const responseTime = (end - start) / 1000; 10 | 11 | const text = `*_ᴍᴀꜱᴛᴇʀ-ᴍᴅ ᴘɪɴɢ ꜱᴘᴇᴇᴅ: ${responseTime.toFixed(2)} ᴍꜱ_*`; 12 | sock.sendMessage(m.from, { text }, { quoted: m }); 13 | } 14 | } 15 | 16 | export default ping; 17 | -------------------------------------------------------------------------------- /src/plugin/restart.js: -------------------------------------------------------------------------------- 1 | const restartBot = async (m) => { 2 | const prefixMatch = m.body.match(/^[\\/!#.]/); 3 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 4 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 5 | 6 | if (cmd === 'restart') { 7 | try { 8 | m.reply('Proses....') 9 | process.exit() 10 | } catch (error) { 11 | console.error(error); 12 | await m.React("❌"); 13 | return m.reply(`An error occurred while restarting the bot: ${error.message}`); 14 | } 15 | } 16 | }; 17 | 18 | export default restartBot; 19 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [20.x] 19 | 20 | steps: 21 | - name: Checkout repository 22 | uses: actions/checkout@v3 23 | 24 | - name: Set up Node.js 25 | uses: actions/setup-node@v3 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | 29 | - name: Install dependencies 30 | run: npm install 31 | 32 | - name: Start application 33 | run: npm start 34 | -------------------------------------------------------------------------------- /src/plugin/dbinary.js: -------------------------------------------------------------------------------- 1 | import { dBinary } from '../../lib/binary.cjs'; 2 | 3 | const dbinary = async (m, gss) => { 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 | 3 | const ebinary = async (m, gss) => { 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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/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/tquoted.js: -------------------------------------------------------------------------------- 1 | const quotedMessage = async (m, gss) => { 2 | try { 3 | const prefixMatch = m.body.match(/^[/!#.]/); 4 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 5 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).trim().toLowerCase() : ''; 6 | const validCommands = ['q', 'quoted']; 7 | 8 | if (validCommands.includes(cmd)) { 9 | if (!m.quoted) return m.reply('Please reply to a message!'); 10 | if (!m.quoted || !m.quoted.quoted) return m.reply('The replied message does not contain a reply'); 11 | const quotedMsg = await m.getQuotedMsg(); 12 | if (!quotedMsg) return m.reply('The replied message does not contain a reply'); 13 | await quotedMsg.copyForward(m.from, true); 14 | } 15 | } catch (err) { 16 | console.error(err); 17 | } 18 | }; 19 | 20 | export default quotedMessage; -------------------------------------------------------------------------------- /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 prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | 11 | const validCommands = ['leave', 'exit', 'left']; 12 | 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 16 | 17 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 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/owner.js: -------------------------------------------------------------------------------- 1 | import setEnvCommand from '../setvar.js'; 2 | import config from '../../config.cjs'; 3 | const ownerContact = async (m, gss) => { 4 | const ownernumber = config.OWNER_NUMBER; 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 text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | if (cmd === 'owner') { 11 | try { 12 | await gss.sendContact(m.from, [ownernumber], m); 13 | await m.React("✅"); 14 | } catch (error) { 15 | console.error('Error sending owner contact:', error); 16 | m.reply('Error sending owner contact.'); 17 | await m.React("❌"); 18 | } 19 | } else if (cmd === 'setenv') { 20 | const args = text.split(' '); 21 | await setEnvCommand(m, args); 22 | } 23 | }; 24 | 25 | export default ownerContact; 26 | -------------------------------------------------------------------------------- /src/plugin/flirt.js: -------------------------------------------------------------------------------- 1 | import nodeFetch from 'node-fetch'; 2 | 3 | const flirting = async (m, Matrix) => { 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 6 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 7 | 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/tomp3.js: -------------------------------------------------------------------------------- 1 | import { toAudio } from '../../lib/converter.cjs'; // Import statement placed outside the try block 2 | 3 | const tomp3 = async (m, gss) => { 4 | try { 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 | 9 | const validCommands = ['tomp3', 'mp3']; 10 | 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | if (!m.quoted || m.quoted.mtype !== 'videoMessage') { 14 | return m.reply(`Send/Reply with Video to convert into MP3 with caption ${prefix + cmd}`); 15 | } 16 | 17 | m.reply('Converting to MP3, please wait...'); 18 | const media = await m.quoted.download(); 19 | const audio = await toAudio(media, 'mp4'); // Correctly importing toAudio function 20 | 21 | await gss.sendMessage(m.from, { document: audio, mimetype: 'audio/mpeg', fileName: `Converted By ${gss.user.name}.mp3` }, { quoted: m }); 22 | } catch (error) { 23 | console.error('Error:', error); 24 | m.reply('An error occurred while processing the command.'); 25 | } 26 | }; 27 | 28 | export default tomp3; 29 | -------------------------------------------------------------------------------- /src/plugin/waifu.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | 4 | const stickerCommandHandler = async (m, gss) => { 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 | 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 = `MASTER-MD`; 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/readqr.js: -------------------------------------------------------------------------------- 1 | import Jimp from 'jimp'; 2 | import jsQR from 'jsqr'; 3 | import jpeg from 'jpeg-js'; 4 | 5 | const readqr = async (m, gss) => { 6 | try { 7 | const prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | 11 | const validCommands = ['readqr']; 12 | 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 16 | return m.reply('Please quote an image containing a QR code with a caption.'); 17 | } 18 | 19 | const buffer = await m.quoted.download(); 20 | const image = await Jimp.read(buffer); 21 | const { data, width, height } = image.bitmap; 22 | 23 | const code = jsQR(data, width, height); 24 | 25 | if (!code) { 26 | return m.reply('QR code not found or could not be decoded.'); 27 | } 28 | 29 | m.reply(`Decoded QR code: ${code.data}`); 30 | } catch (error) { 31 | console.error('Error:', error); 32 | m.reply('An error occurred while processing the command.'); 33 | } 34 | }; 35 | 36 | export default readqr; 37 | -------------------------------------------------------------------------------- /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 prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['block']; 13 | 14 | if (!validCommands.includes(cmd)) return; 15 | 16 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 17 | 18 | let users = m.mentionedJid[0] ? m.mentionedJid[0] : m.quoted ? m.quoted.sender : text.replace(/[^0-9]/g, '') + '@s.whatsapp.net'; 19 | 20 | await gss.updateBlockStatus(users, 'block') 21 | .then((res) => m.reply(`Blocked ${users.split('@')[0]} successfully.`)) 22 | .catch((err) => m.reply(`Failed to block user: ${err}`)); 23 | } catch (error) { 24 | console.error('Error:', error); 25 | m.reply('An error occurred while processing the command.'); 26 | } 27 | }; 28 | 29 | export default block; 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 prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['unblock']; 13 | 14 | if (!validCommands.includes(cmd)) return; 15 | 16 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 17 | 18 | let users = m.mentionedJid[0] ? m.mentionedJid[0] : m.quoted ? m.quoted.sender : text.replace(/[^0-9]/g, '') + '@s.whatsapp.net'; 19 | 20 | await gss.updateBlockStatus(users, 'unblock') 21 | .then((res) => m.reply(`Unblocked ${users.split('@')[0]} successfully.`)) 22 | .catch((err) => m.reply(`Failed to unblock user: ${err}`)); 23 | } catch (error) { 24 | console.error('Error:', error); 25 | m.reply('An error occurred while processing the command.'); 26 | } 27 | }; 28 | 29 | export default unblock; 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 prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | 11 | const validCommands = ['del', 'delete']; 12 | 13 | if (validCommands.includes(cmd)) { 14 | if (!isCreator) { 15 | return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 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 | const linkgc = async (m, gss) => { 2 | try { 3 | const prefixMatch = m.body.match(/^[\\/!#.]/); 4 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 5 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 6 | 7 | const validCommands = ['linkgc', 'grouplink']; 8 | 9 | if (!validCommands.includes(cmd)) return; 10 | 11 | if (!m.isGroup) { 12 | return m.reply('*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*'); 13 | } 14 | const groupMetadata = await gss.groupMetadata(m.from); 15 | const botNumber = await gss.decodeJid(gss.user.id); 16 | const isBotAdmins = groupMetadata.participants.find(p => p.id === botNumber)?.admin; 17 | 18 | if (!isBotAdmins) { 19 | return m.reply('*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*'); 20 | } 21 | 22 | const response = await gss.groupInviteCode(m.from); 23 | await gss.sendMessage(m.from, { 24 | text: `https://chat.whatsapp.com/${response}\n\nGroup Link: ${groupMetadata.subject}`, 25 | detectLink: true 26 | }); 27 | 28 | } catch (error) { 29 | console.error('Error:', error); 30 | m.reply('An error occurred while processing the command.'); 31 | } 32 | }; 33 | 34 | export default linkgc; 35 | -------------------------------------------------------------------------------- /src/plugin/lyrics.js: -------------------------------------------------------------------------------- 1 | import { lyrics, lyricsv2 } from '@bochilteam/scraper'; 2 | 3 | const lyricsCommand = async (m, Matrix) => { 4 | try { 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 text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['lyrics']; 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | if (!text) { 14 | return m.reply('Please provide a song name to get the lyrics.'); 15 | } 16 | 17 | m.reply('*Searching for lyrics, please wait...*'); 18 | 19 | const result = await lyricsv2(text).catch(async () => await lyrics(text)); 20 | 21 | if (!result) { 22 | return m.reply('No lyrics found for the provided song.'); 23 | } 24 | 25 | const replyMessage = ` 26 | *✍️ Title:* ${result.title} 27 | *👨‍🎤 Author:* ${result.author} 28 | *🔗 Url:* ${result.link} 29 | 30 | *📝 Lyrics:*\n\n ${result.lyrics} 31 | `.trim(); 32 | 33 | m.reply(replyMessage); 34 | 35 | } catch (error) { 36 | console.error('Error:', error); 37 | m.reply('An error occurred while processing the command.'); 38 | } 39 | }; 40 | 41 | export default lyricsCommand; 42 | -------------------------------------------------------------------------------- /src/plugin/hd.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 tourl = 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 = ['hdr', 'hd', 'remini', 'enhance', 'upscale']; 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"); // Call remini directly 25 | gss.sendMessage(m.from, { image: proses, caption: `> *Hey ${m.pushName} Here Is Your Enhanced Image 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ*` }, { 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 tourl; 35 | -------------------------------------------------------------------------------- /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 prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 10 | 11 | if (cmd === 'autoread') { 12 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 13 | let responseMessage; 14 | 15 | if (text === 'on') { 16 | config.AUTO_READ = true; 17 | responseMessage = "Auto-Read has been enabled."; 18 | } else if (text === 'off') { 19 | config.AUTO_READ = false; 20 | responseMessage = "Auto-Read has been disabled."; 21 | } else { 22 | responseMessage = "Usage:\n- `autoread on`: Enable Auto-Read\n- `autoread off`: Disable Auto-Read"; 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 autoreadCommand; 35 | -------------------------------------------------------------------------------- /src/plugin/mode.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import config from '../../config.cjs'; 4 | 5 | const modeCommand = async (m, Matrix) => { 6 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 7 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 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 | const text = m.body.slice(prefix.length + cmd.length).trim().toLowerCase(); 12 | 13 | if (cmd === 'mode') { 14 | if (!isCreator) { 15 | await Matrix.sendMessage(m.from, { text: "*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*" }, { quoted: m }); 16 | return; 17 | } 18 | 19 | if (['public', 'private'].includes(text)) { 20 | if (text === 'public') { 21 | Matrix.public = true; 22 | m.reply('Mode has been changed to public.'); 23 | } else if (text === 'private') { 24 | Matrix.public = false; 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/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 prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 10 | 11 | if (cmd === 'autoblock') { 12 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 13 | let responseMessage; 14 | 15 | if (text === 'on') { 16 | config.AUTO_BLOCK = true; 17 | responseMessage = "Auto-Block has been enabled."; 18 | } else if (text === 'off') { 19 | config.AUTO_BLOCK = false; 20 | responseMessage = "*Auto-Block has been disabled.*"; 21 | } else { 22 | responseMessage = "Usage:\n- `autoblock on`: Enable Auto-Block\n- `autoblock off`: Disable Auto-Block"; 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 autoblockCommand; 34 | -------------------------------------------------------------------------------- /src/plugin/autodown.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const autodlCommand = 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 prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 10 | 11 | if (cmd === 'autodl') { 12 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 13 | let responseMessage; 14 | 15 | if (text === 'on') { 16 | config.AUTO_DL = true; 17 | responseMessage = "*AUTO-DOWNLOAD has been enabled.*"; 18 | } else if (text === 'off') { 19 | config.AUTO_DL = false; 20 | responseMessage = "*AUTO-DOWNLOAD has been disabled.*"; 21 | } else { 22 | responseMessage = "Usage:\n- `autodl on`: Enable Auto-Download\n- `autodl off`: Disable Auto-Download"; 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 autodlCommand; 35 | -------------------------------------------------------------------------------- /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 prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 10 | 11 | if (cmd === 'autoreact') { 12 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 13 | let responseMessage; 14 | 15 | if (text === 'on') { 16 | config.AUTO_REACT = true; 17 | responseMessage = "*AUTO_REACT has been enabled.*"; 18 | } else if (text === 'off') { 19 | config.AUTO_REACT = false; 20 | responseMessage = "*AUTO_REACT has been disabled.*"; 21 | } else { 22 | responseMessage = "Usage:\n- `autoreact on`: Enable Auto-React\n- `autoreact off`: Disable Auto-React"; 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 autoreadCommand; 35 | -------------------------------------------------------------------------------- /src/plugin/qrgenerater.js: -------------------------------------------------------------------------------- 1 | import qrcode from 'qrcode'; 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | 5 | const toqr = async (m, gss) => { 6 | try { 7 | const botNumber = await gss.decodeJid(gss.user.id); 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 | const text = m.body.slice(prefix.length + cmd.length).trim(); 12 | 13 | const validCommands = ['toqr']; 14 | 15 | if (!validCommands.includes(cmd)) return; 16 | 17 | if (!text) return m.reply('Please include link or text!'); 18 | 19 | let qyuer = await qrcode.toDataURL(text, { scale: 35 }); 20 | let data = Buffer.from(qyuer.replace('data:image/png;base64,', ''), 'base64'); 21 | let buff = `${Date.now()}.jpg`; 22 | 23 | await fs.writeFileSync(path.join('./', buff), data); 24 | let medi = fs.readFileSync(path.join('./', buff)); 25 | 26 | await gss.sendMessage(m.from, { 27 | image: medi, 28 | caption: 'QR code generated successfully!\n\n> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ' 29 | }, { 30 | quoted: m 31 | }); 32 | 33 | setTimeout(() => { 34 | fs.unlinkSync(path.join('./', buff)); 35 | }, 10000); 36 | } catch (error) { 37 | console.error('Error:', error); 38 | m.reply('An error occurred while generating the QR code.'); 39 | } 40 | }; 41 | 42 | export default toqr; 43 | -------------------------------------------------------------------------------- /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 prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 10 | 11 | if (cmd === 'autotyping') { 12 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 13 | let responseMessage; 14 | 15 | if (text === 'on') { 16 | config.AUTO_TYPING = true; 17 | responseMessage = "Auto-Typing has been enabled."; 18 | } else if (text === 'off') { 19 | config.AUTO_TYPING = false; 20 | responseMessage = "Auto-Typing has been disabled."; 21 | } else { 22 | responseMessage = "Usage:\n- `autotyping on`: Enable Auto-Typing\n- `autotyping off`: Disable Auto-Typing"; 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 autotypingCommand; 35 | -------------------------------------------------------------------------------- /src/plugin/setgroupname.js: -------------------------------------------------------------------------------- 1 | const setGroupName = async (m, gss) => { 2 | try { 3 | const botNumber = await gss.decodeJid(gss.user.id); 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['setgroupname', 'setname']; 10 | 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 14 | const groupMetadata = await gss.groupMetadata(m.from); 15 | const participants = groupMetadata.participants; 16 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 17 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 18 | 19 | if (!botAdmin) return m.reply("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 20 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 21 | 22 | if (!text) return m.reply("*📛 PLEASE PROVIDE A NAME TO SET*"); 23 | 24 | await gss.groupUpdateSubject(m.from, text); 25 | m.reply(`Group Name Has Been Set To: ${text}`); 26 | } catch (error) { 27 | console.error('Error:', error); 28 | m.reply('An error occurred while processing the command.'); 29 | } 30 | }; 31 | 32 | export default setGroupName; 33 | -------------------------------------------------------------------------------- /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 prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 11 | 12 | if (cmd === 'anticall') { 13 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 14 | let responseMessage; 15 | 16 | if (text === 'on') { 17 | config.REJECT_CALL = true; 18 | responseMessage = "*Anti-Call has been enabled.*"; 19 | } else if (text === 'off') { 20 | config.REJECT_CALL = false; 21 | responseMessage = "*Anti-Call has been disabled.*"; 22 | } else { 23 | responseMessage = "Usage:\n- `anticall on`: Enable Anti-Call\n- `anticall off`: Disable Anti-Call"; 24 | } 25 | 26 | try { 27 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 28 | } catch (error) { 29 | console.error("Error processing your request:", error); 30 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 31 | } 32 | } 33 | }; 34 | 35 | export default anticallcommand; 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 prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 10 | 11 | if (cmd === 'alwaysonline') { 12 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 13 | let responseMessage; 14 | 15 | if (text === 'on') { 16 | config.ALWAYS_ONLINE = true; 17 | responseMessage = "Always Online has been enabled."; 18 | } else if (text === 'off') { 19 | config.ALWAYS_ONLINE = false; 20 | responseMessage = "*Always Online has been disabled.*"; 21 | } else { 22 | responseMessage = "Usage:\n- `alwaysonline on`: Enable Always Online\n- `alwaysonline off`: Disable Always Online"; 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 alwaysonlineCommand; 35 | -------------------------------------------------------------------------------- /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 prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 10 | 11 | if (cmd === 'autorecording') { 12 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 13 | let responseMessage; 14 | 15 | if (text === 'on') { 16 | config.AUTO_RECORDING = true; 17 | responseMessage = "Auto-Recording has been enabled."; 18 | } else if (text === 'off') { 19 | config.AUTO_RECORDING = false; 20 | responseMessage = "Auto-Recording has been disabled."; 21 | } else { 22 | responseMessage = "Usage:\n- `autorecording on`: Enable Auto-Recording\n- `autorecording off`: Disable Auto-Recording"; 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 autorecordingCommand; 35 | -------------------------------------------------------------------------------- /src/plugin/setdesc.js: -------------------------------------------------------------------------------- 1 | const setDescription = async (m, gss) => { 2 | try { 3 | const botNumber = await gss.decodeJid(gss.user.id); 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['setdescription', 'setdesc', 'setgroupbio']; 10 | 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 14 | const groupMetadata = await gss.groupMetadata(m.from); 15 | const participants = groupMetadata.participants; 16 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 17 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 18 | 19 | if (!botAdmin) return m.reply("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 20 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 21 | 22 | if (!text) return m.reply("*📛 PLEASE PROVIDE A DESCRIPTION TO SET*"); 23 | 24 | await gss.groupUpdateDescription(m.from, text); 25 | m.reply(`Group Description Has Been Set To: ${text}`); 26 | } catch (error) { 27 | console.error('Error:', error); 28 | m.reply('An error occurred while processing the command.'); 29 | } 30 | }; 31 | 32 | export default setDescription; 33 | -------------------------------------------------------------------------------- /src/plugin/insta.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const apiBaseUrl = 'https://www.guruapi.tech/api/igdlv1?url='; 4 | 5 | const instaDownload = async (m, Matrix) => { 6 | const prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['insta', 'ig', 'igdl', 'instadl']; 12 | 13 | if (validCommands.includes(cmd)) { 14 | if (!text) return m.reply('Please provide an Instagram URL.'); 15 | 16 | try { 17 | await m.React('⬇️'); 18 | 19 | const apiUrl = `${apiBaseUrl}${encodeURIComponent(text)}`; 20 | const response = await axios.get(apiUrl); 21 | const result = response.data; 22 | 23 | if (result.success && result.data && result.data.length > 0) { 24 | const mediaUrl = result.data[0].url_download; // Use the first media URL from the array 25 | const caption = "© 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ"; 26 | 27 | await Matrix.sendMedia(m.from, mediaUrl, 'file', caption, m); 28 | await m.React('✅'); 29 | } else { 30 | throw new Error('Invalid response from the downloader.'); 31 | } 32 | } catch (error) { 33 | console.error('Error downloading Instagram media:', error.message); 34 | m.reply('Error downloading Instagram media.'); 35 | await m.React('❌'); 36 | } 37 | } 38 | }; 39 | 40 | export default instaDownload; 41 | -------------------------------------------------------------------------------- /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 || "Add your Session", 7 | AUTO_STATUS_SEEN: process.env.AUTO_STATUS_SEEN !== undefined ? process.env.AUTO_STATUS_SEEN === 'true' : true, 8 | AUTO_DL: process.env.AUTO_DL !== undefined ? process.env.AUTO_DL === 'true' : false, 9 | AUTO_READ: process.env.AUTO_READ !== undefined ? process.env.AUTO_READ === 'true' : false, 10 | AUTO_TYPING: process.env.AUTO_TYPING !== undefined ? process.env.AUTO_TYPING === 'true' : false, 11 | AUTO_RECORDING: process.env.AUTO_RECORDING !== undefined ? process.env.AUTO_RECORDING === 'true' : false, 12 | ALWAYS_ONLINE: process.env.ALWAYS_ONLINE !== undefined ? process.env.ALWAYS_ONLINE === 'true' : false, 13 | AUTO_REACT: process.env.AUTO_REACT !== undefined ? process.env.AUTO_REACT === 'true' : false, 14 | /*auto block only for 212 */ 15 | AUTO_BLOCK: process.env.AUTO_BLOCK !== undefined ? process.env.AUTO_BLOCK === 'true' : true, 16 | 17 | 18 | REJECT_CALL: process.env.REJECT_CALL !== undefined ? process.env.REJECT_CALL === 'true' : false, 19 | NOT_ALLOW: process.env.NOT_ALLOW !== undefined ? process.env.NOT_ALLOW === 'true' : true, 20 | MODE: process.env.MODE || "public", 21 | OWNER_NAME: process.env.OWNER_NAME || "MASTER_MIND", 22 | OWNER_NUMBER: process.env.OWNER_NUMBER || "94720797915", 23 | GEMINI_KEY: process.env.GEMINI_KEY || "", 24 | WELCOME: process.env.WELCOME !== undefined ? process.env.WELCOME === 'true' : false, 25 | }; 26 | 27 | 28 | module.exports = config; 29 | -------------------------------------------------------------------------------- /src/plugin/report.js: -------------------------------------------------------------------------------- 1 | const report = async (m, gss) => { 2 | const reportedMessages = {}; 3 | const devlopernumber = '94720797915'; 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['bug', 'report', 'request']; 10 | 11 | if (validCommands.includes(cmd)) { 12 | 13 | if (!text) return m.reply(`Example: ${prefix + cmd} hi Sahan play command is not working`); 14 | 15 | const messageId = m.key.id; 16 | 17 | if (reportedMessages[messageId]) { 18 | return m.reply("This report has already been forwarded to the owner. Please wait for a response."); 19 | } 20 | 21 | reportedMessages[messageId] = true; 22 | 23 | const textt = `*| REQUEST/BUG |*`; 24 | const teks1 = `\n\n*User*: @${m.sender.split("@")[0]}\n*Request/Bug*: ${text}`; 25 | const teks2 = `\n\n*Hi ${m.pushName}, your request has been forwarded to my Owners.*\n*Please wait...*`; 26 | 27 | // Send the message to the first owner in the `owner` array 28 | gss.sendMessage(devlopernumber + "@s.whatsapp.net", { 29 | text: textt + teks1, 30 | mentions: [m.sender], 31 | }, { 32 | quoted: m, 33 | }); 34 | 35 | // Send a reply to the user 36 | m.reply("Tʜᴀɴᴋ ʏᴏᴜ ꜰᴏʀ ʏᴏᴜʀ ʀᴇᴘᴏʀᴛ. Iᴛ ʜᴀs ʙᴇᴇɴ ꜰᴏʀᴡᴀʀᴅᴇᴅ ᴛᴏ ᴛʜᴇ ᴏᴡɴᴇʀ. Pʟᴇᴀsᴇ ᴡᴀɪᴛ ꜰᴏʀ ᴀ ʀᴇsᴘᴏɴsᴇ."); 37 | } 38 | }; 39 | 40 | export default report; 41 | -------------------------------------------------------------------------------- /src/plugin/emojimix.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | import fs from 'fs'; 3 | 4 | const emojimix = async (m, Matrix) => { 5 | try { 6 | const prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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: "MASTER-MD", 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/autodl.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | import config from '../../config.cjs'; 3 | 4 | const downloadAndSendMedia = async (m, Matrix) => { 5 | if (!config.AUTO_DL) return; // Exit early if AUTO_DL is false 6 | 7 | const text = m.body.trim(); 8 | 9 | if (!/^https?:\/\//.test(text)) { 10 | return; 11 | } 12 | 13 | try { 14 | const supportedDomains = ['youtube.com', 'youtu.be', 'instagram.com', 'facebook.com', 'tiktok.com', 'drive.google.com']; 15 | const urlObj = new URL(text); 16 | const domain = urlObj.hostname.replace('www.', ''); 17 | 18 | if (supportedDomains.some(d => domain.includes(d))) { 19 | const apiUrl = `https://ethixdl-003a39444563.herokuapp.com/download?url=${encodeURIComponent(text)}`; 20 | const res = await fetch(apiUrl); 21 | const result = await res.json(); 22 | 23 | if (result.status) { 24 | const mediaData = result.data; 25 | const caption = `> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ`; 26 | 27 | if (mediaData.low) { 28 | const mediaUrl = mediaData.low; 29 | const extension = mediaUrl.split('.').pop().toLowerCase(); 30 | 31 | await Matrix.sendMedia(m.from, mediaUrl, extension, caption, m); 32 | await m.React('✅'); 33 | } else { 34 | } 35 | } else { 36 | } 37 | } else { 38 | } 39 | } catch (error) { 40 | console.error('Error downloading and sending media:', error.message); 41 | m.reply('Error downloading and sending media.'); 42 | await m.React('❌'); 43 | } 44 | }; 45 | 46 | export default downloadAndSendMedia; 47 | -------------------------------------------------------------------------------- /src/plugin/mediafiredl.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { mediafireDl } from 'mfiredlcore-vihangayt'; 3 | 4 | const mediafireDownload = async (m, Matrix) => { 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 text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['mediafire', 'mf', 'mfdownload']; 11 | 12 | if (validCommands.includes(cmd)) { 13 | if (!text) return m.reply('Please provide a MediaFire URL.'); 14 | 15 | try { 16 | await m.React('⬇️'); 17 | 18 | const mediafireUrl = text; 19 | const mediafireInfo = await mediafireDl(mediafireUrl); 20 | 21 | if (mediafireInfo && mediafireInfo.link) { 22 | const mediaUrl = mediafireInfo.link; 23 | const caption = `> © Powered By mr Sahan Ofc\n> File: ${mediafireInfo.name}\n> Size: ${mediafireInfo.size}\n> Date: ${mediafireInfo.date}`; 24 | 25 | 26 | const extension = mediaUrl.split('.').pop().toLowerCase(); 27 | 28 | 29 | await Matrix.sendMedia(m.from, mediaUrl, extension, caption, m); 30 | 31 | await m.React('✅'); 32 | } else { 33 | throw new Error('Invalid response from MediaFire.'); 34 | } 35 | } catch (error) { 36 | console.error('Error downloading MediaFire file:', error.message); 37 | m.reply('Error downloading MediaFire file.'); 38 | await m.React('❌'); 39 | } 40 | } 41 | }; 42 | 43 | export default mediafireDownload; 44 | -------------------------------------------------------------------------------- /src/plugin/gdrive.js: -------------------------------------------------------------------------------- 1 | import pkg from "nayan-media-downloader"; 2 | const { GDLink } = pkg; 3 | 4 | const gdriveDownload = async (m, Matrix) => { 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 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/join.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const joinGroup = 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 prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 | const args = text.split(' '); 12 | 13 | const validCommands = ['join']; 14 | 15 | if (!validCommands.includes(cmd)) return; 16 | 17 | 18 | 19 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 20 | 21 | if (!text) throw '*Enter The Group Link!*'; 22 | if (!isUrl(args[0]) && !args[0].includes('whatsapp.com')) throw '*INVALID LINK!*'; 23 | 24 | m.reply('Please wait...'); 25 | const result = args[0].split('https://chat.whatsapp.com/')[1]; 26 | 27 | await gss.groupAcceptInvite(result) 28 | .then((res) => m.reply(`*📛 SUCCESSFULLY JOINED THE GROUP. ${JSON.stringify(res)}`)) 29 | .catch((err) => m.reply(`*🚫 FAILED TO JOIN THE GROUP. ${JSON.stringify(err)}`)); 30 | } catch (error) { 31 | console.error('Error:', error); 32 | m.reply('An error occurred while processing the command.'); 33 | } 34 | }; 35 | 36 | const isUrl = (string) => { 37 | try { 38 | new URL(string); 39 | return true; 40 | } catch (_) { 41 | return false; 42 | } 43 | }; 44 | 45 | export default joinGroup; 46 | -------------------------------------------------------------------------------- /src/plugin/imagetotext.js: -------------------------------------------------------------------------------- 1 | import Tesseract from 'tesseract.js'; 2 | import { writeFile, unlink } from 'fs/promises'; 3 | 4 | const givetextCommand = async (m, Matrix) => { 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 args = m.body.split(' ').slice(1); 9 | 10 | const validCommands = ['givetext', 'extract']; 11 | 12 | if (validCommands.includes(cmd)) { 13 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 14 | return m.reply(`Send/Reply with an image to extract text ${prefix + cmd}`); 15 | } 16 | 17 | let lang = 'eng'; 18 | if (args.length > 0) { 19 | lang = args[0]; 20 | } 21 | 22 | try { 23 | const media = await m.quoted.download(); 24 | if (!media) throw new Error('Failed to download media.'); 25 | 26 | const filePath = `./${Date.now()}.png`; 27 | await writeFile(filePath, media); 28 | 29 | const { data: { text } } = await Tesseract.recognize(filePath, lang, { 30 | logger: m => console.log(m) 31 | }); 32 | 33 | const responseMessage = `Extracted Text:\n\n${text}`; 34 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 35 | 36 | await unlink(filePath); 37 | } catch (error) { 38 | console.error("Error extracting text from image:", error); 39 | await Matrix.sendMessage(m.from, { text: 'Error extracting text from image.' }, { quoted: m }); 40 | } 41 | } 42 | }; 43 | 44 | export default givetextCommand; 45 | -------------------------------------------------------------------------------- /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 prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 11 | 12 | const validCommands = ['autostatus', 'autosview', 'autostatusview']; 13 | 14 | if (validCommands.includes(cmd)){ 15 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 16 | let responseMessage; 17 | 18 | if (text === 'on') { 19 | config.AUTO_STATUS_SEEN = true; 20 | responseMessage = "*AUTO STATUS SEEN has been enabled.*"; 21 | } else if (text === 'off') { 22 | config.AUTO_STATUS_SEEN = false; 23 | responseMessage = "*AUTO STATUS SEEN has been disabled.*"; 24 | } else { 25 | responseMessage = `Usage:\n- *${prefix + cmd} ON:* Enable AUTO STATUS VIEW\n- *${prefix + cmd} off:* Disable AUTO STATUS SEEN`; 26 | } 27 | 28 | try { 29 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 30 | } catch (error) { 31 | console.error("Error processing your request:", error); 32 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 33 | } 34 | } 35 | }; 36 | 37 | export default anticallCommand; 38 | -------------------------------------------------------------------------------- /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 prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 apiKey = config.GEMINI_KEY; 12 | const genAI = new GoogleGenerativeAI(apiKey); 13 | const validCommands = ['gemini', 'vision']; 14 | 15 | if (validCommands.includes(cmd)) { 16 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 17 | return m.reply(`*Send/Reply with an Image ${prefix + cmd}*`); 18 | } 19 | 20 | m.reply("Please wait..."); 21 | 22 | try { 23 | const prompt = text; 24 | const media = await m.quoted.download(); 25 | 26 | const imagePart = { 27 | inlineData: { 28 | data: Buffer.from(media).toString("base64"), 29 | mimeType: "image/png", 30 | }, 31 | }; 32 | 33 | const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash-latest" }); 34 | const result = await model.generateContent([prompt, imagePart]); 35 | const response = result.response; 36 | 37 | const textResponse = await response.text(); 38 | m.reply(`${textResponse}`); 39 | } catch (error) { 40 | console.error('Error in Gemini Pro Vision:', error); 41 | m.reply(`An error occurred: ${error.message}`); 42 | await m.React("❌"); 43 | } 44 | } 45 | }; 46 | 47 | export default geminiResponse; 48 | -------------------------------------------------------------------------------- /src/plugin/pinterestdl.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); 4 | 5 | const imageCommand = async (m, sock) => { 6 | const prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 | 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 | const tagAll = async (m, gss) => { 2 | try { 3 | // Ensure the function is async 4 | const botNumber = await gss.decodeJid(gss.user.id); 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 | 9 | // Check for the valid command 10 | const validCommands = ['tagall']; 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | 14 | const groupMetadata = await gss.groupMetadata(m.from); 15 | const participants = groupMetadata.participants; 16 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 17 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 18 | 19 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 20 | 21 | if (!botAdmin) return m.reply("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 22 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 23 | // Extract the message to be sent 24 | let message = `*👨‍💻MASTER-MD-V3👨‍💻*\n乂 *Attention Everyone* 乂\n\n*Message:* ${m.body.slice(prefix.length + cmd.length).trim() || 'no message'}\n\n`; 25 | 26 | 27 | 28 | for (let participant of participants) { 29 | message += `❒ @${participant.id.split('@')[0]}\n`; 30 | } 31 | 32 | await gss.sendMessage(m.from, { text: message, mentions: participants.map(a => a.id) }, { quoted: m }); 33 | } catch (error) { 34 | console.error('Error:', error); 35 | await m.reply('An error occurred while processing the command.'); 36 | } 37 | }; 38 | 39 | export default tagAll; 40 | -------------------------------------------------------------------------------- /src/plugin/cal.js: -------------------------------------------------------------------------------- 1 | const report = async (m, gss) => { 2 | try { 3 | const prefixMatch = m.body.match(/^[\\/!#.]/); 4 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 | const validCommands = ['cal', 'calculater', 'calc']; 9 | 10 | if (validCommands.includes(cmd)) { 11 | let id = m.from; 12 | gss.math = gss.math ? gss.math : {}; 13 | 14 | if (id in gss.math) { 15 | clearTimeout(gss.math[id][3]); 16 | delete gss.math[id]; 17 | return m.reply('...'); 18 | } 19 | 20 | let val = text 21 | .replace(/[^0-9\-\/+*×÷πEe()piPI.]/g, '') // Allow decimal point '.' 22 | .replace(/×/g, '*') 23 | .replace(/÷/g, '/') 24 | .replace(/π|pi/gi, 'Math.PI') 25 | .replace(/e/gi, 'Math.E') 26 | .replace(/\/+/g, '/') 27 | .replace(/\++/g, '+') 28 | .replace(/-+/g, '-'); 29 | 30 | let format = val 31 | .replace(/Math\.PI/g, 'π') 32 | .replace(/Math\.E/g, 'e') 33 | .replace(/\//g, '÷') 34 | .replace(/\*/g, '×'); 35 | 36 | let result = (new Function('return ' + val))(); 37 | 38 | if (isNaN(result)) throw new Error('example: 17+19'); 39 | 40 | m.reply(`*${format}* = _${result}_`); 41 | } 42 | } catch (error) { 43 | // Handle specific error messages 44 | if (error instanceof SyntaxError) { 45 | return m.reply('Invalid syntax. Please check your expression.'); 46 | } else if (error instanceof Error) { 47 | return m.reply(error.message); 48 | } else { 49 | } 50 | } 51 | }; 52 | 53 | export default report; 54 | -------------------------------------------------------------------------------- /src/plugin/hidetag.js: -------------------------------------------------------------------------------- 1 | const tagall = async (m, gss) => { 2 | try { 3 | // Ensure the function is async 4 | const botNumber = await gss.decodeJid(gss.user.id); 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 | 9 | // Check for the valid command 10 | const validCommands = ['hidetag']; 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | 14 | const groupMetadata = await gss.groupMetadata(m.from); 15 | const participants = groupMetadata.participants; 16 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 17 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 18 | 19 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 20 | 21 | if (!botAdmin) return m.reply("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 22 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 23 | // Extract the message to be sent 24 | let message = `乂 *Attention Everyone* 乂\n\n👨‍💻MASTER-MD-V3👨‍💻\n*Message:* ${m.body.slice(prefix.length + cmd.length).trim() || 'no message'}\n\n`; 25 | 26 | 27 | 28 | for (let participant of participants) { 29 | message += `❒ @${participant.id.split('@')[0]}\n`; 30 | } 31 | 32 | gss.sendMessage(m.from, { text: m.quoted.text ? m.quoted.text : '', mentions: participants.map(a => a.id) }, { quoted: m }); 33 | } catch (error) { 34 | console.error('Error:', error); 35 | await m.reply('An error occurred while processing the command.'); 36 | } 37 | }; 38 | 39 | export default tagall; 40 | -------------------------------------------------------------------------------- /src/plugin/getpaircode.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | const apiBaseUrl = 'https://semantic-delcina-gssbotwa-ecdfac1a.koyeb.app'; // Your API endpoint 3 | 4 | const getPairingCode = async (m, Matrix) => { 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 text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['pair', 'getsession', 'paircode', 'pairingcode']; 11 | 12 | if (validCommands.includes(cmd)) { 13 | if (!text) return m.reply('Please provide a phone number with country code.'); 14 | 15 | const phoneNumberMatch = text.match(/^(\+\d{1,3})(\d+)$/); 16 | if (!phoneNumberMatch) return m.reply('Please provide a valid phone number with country code.'); 17 | 18 | const countryCode = phoneNumberMatch[1]; 19 | const phoneNumber = phoneNumberMatch[2]; 20 | 21 | try { 22 | await m.React('🕘'); 23 | 24 | const response = await axios.post(apiBaseUrl, { 25 | phoneNumber: countryCode + phoneNumber 26 | }, { 27 | headers: { 28 | 'Content-Type': 'application/json' 29 | } 30 | }); 31 | 32 | const result = response.data; 33 | 34 | if (result.pairingCode) { 35 | const message = `Pairing Code: ${result.pairingCode}\nStatus: ${result.status}`; 36 | await m.reply(message); 37 | await m.React('✅'); 38 | } else { 39 | throw new Error('Invalid response from the server.'); 40 | } 41 | } catch (error) { 42 | console.error('Error fetching pairing code:', error.message); 43 | m.reply('Error fetching pairing code.'); 44 | await m.React('❌'); 45 | } 46 | } 47 | }; 48 | 49 | export default getPairingCode; 50 | -------------------------------------------------------------------------------- /src/plugin/fetch.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | 3 | const fetchData = async (m, Matrix) => { 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 MASTER-MD', 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/tboxdl.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const teraboxApiBaseUrl = 'https://teraboxvideodownloader.nepcoderdevs.workers.dev/?url='; 4 | 5 | const teraboxDownload = async (m, Matrix) => { 6 | const prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['terabox', 'tb', 'tbdl', 'teraboxdl']; 12 | 13 | if (validCommands.includes(cmd)) { 14 | if (!text) return m.reply('Please provide a Terabox URL.'); 15 | 16 | try { 17 | await m.React('⬇️'); 18 | 19 | const apiUrl = `${teraboxApiBaseUrl}${encodeURIComponent(text)}`; 20 | const response = await axios.get(apiUrl); 21 | const result = response.data; 22 | 23 | if (result.response && result.response.length > 0) { 24 | const mediaInfo = result.response[0]; 25 | const mediaUrl = mediaInfo.resolutions["Fast Download"]; 26 | const caption = "> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ"; 27 | 28 | if (mediaUrl) { 29 | const sendVideo = { 30 | video: { url: mediaUrl }, 31 | caption: caption, 32 | }; 33 | await Matrix.sendMessage(m.from, sendVideo, { quoted: m }); 34 | await m.React('✅'); 35 | } else { 36 | throw new Error('Fast Download URL not found.'); 37 | } 38 | } else { 39 | throw new Error('Invalid response from the downloader.'); 40 | } 41 | } catch (error) { 42 | console.error('Error downloading Terabox media:', error.message); 43 | m.reply('Error downloading Terabox media.'); 44 | await m.React('❌'); 45 | } 46 | } 47 | }; 48 | 49 | export default teraboxDownload; 50 | -------------------------------------------------------------------------------- /src/plugin/gimage.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); 4 | 5 | const imageCommand = async (m, sock) => { 6 | const prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 | const query = args; 11 | 12 | const validCommands = ['image', 'img', 'gimage']; 13 | 14 | if (validCommands.includes(cmd)) { 15 | if (!query) { 16 | return sock.sendMessage(m.from, { text: `Usage: ${prefix + cmd} black cats` }); 17 | } 18 | 19 | try { 20 | await m.React("📥"); 21 | const response = await axios.get(`https://aemt.me/googleimage?query=${encodeURIComponent(query)}`); 22 | 23 | if (!response.data || !response.data.result) { 24 | return sock.sendMessage(m.from, { text: 'No images found for your search query.' }); 25 | } 26 | 27 | const results = response.data.result.slice(0, 5); // Get the top 5 images 28 | 29 | if (results.length === 0) { 30 | return sock.sendMessage(m.from, { text: 'No images found for your search query.' }); 31 | } 32 | 33 | for (const imageUrl of results) { 34 | await sleep(500); 35 | const imageResponse = await axios.get(imageUrl, { responseType: 'arraybuffer' }); 36 | const imageBuffer = Buffer.from(imageResponse.data, 'binary'); 37 | 38 | await sock.sendMessage(m.from, { image: imageBuffer, caption: '' }, { quoted: m }); 39 | await m.React("✅"); 40 | } 41 | } catch (error) { 42 | console.error("Error fetching images:", error); 43 | await sock.sendMessage(m.from, { text: 'Error fetching images.' }); 44 | } 45 | } 46 | }; 47 | 48 | export default imageCommand; 49 | -------------------------------------------------------------------------------- /src/plugin/welcome.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.cjs'; 2 | 3 | const gcEvent = async (m, Matrix) => { 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().toLowerCase(); 8 | 9 | if (cmd === 'welcome') { 10 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 11 | const groupMetadata = await Matrix.groupMetadata(m.from); 12 | const participants = groupMetadata.participants; 13 | const botNumber = await Matrix.decodeJid(Matrix.user.id); 14 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 15 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 16 | 17 | if (!botAdmin) return m.reply("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 18 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 19 | let responseMessage; 20 | 21 | if (text === 'on') { 22 | config.WELCOME = true; 23 | responseMessage = "WELCOME & LEFT message has been enabled."; 24 | } else if (text === 'off') { 25 | config.WELCOME = false; 26 | responseMessage = "WELCOME & LEFT message has been disabled."; 27 | } else { 28 | responseMessage = "Usage:\n- `WELCOME on`: Enable WELCOME & LEFT message\n- `WELCOME off`: Disable WELCOME & LEFT message"; 29 | } 30 | 31 | try { 32 | await Matrix.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 33 | } catch (error) { 34 | console.error("Error processing your request:", error); 35 | await Matrix.sendMessage(m.from, { text: 'Error processing your request.' }, { quoted: m }); 36 | } 37 | } 38 | }; 39 | 40 | export default gcEvent; 41 | -------------------------------------------------------------------------------- /src/plugin/invite.js: -------------------------------------------------------------------------------- 1 | const invite = async (m, gss) => { 2 | try { 3 | const prefixMatch = m.body.match(/^[\\/!#.]/); 4 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 5 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 6 | 7 | const validCommands = ['invite', 'add']; 8 | 9 | if (!validCommands.includes(cmd)) return; 10 | 11 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 12 | 13 | const text = m.body.slice(prefix.length + cmd.length).trim(); 14 | 15 | const botNumber = await gss.decodeJid(gss.user.id); 16 | const isBotAdmins = groupMetadata.participants.find(p => p.id === botNumber)?.admin; 17 | 18 | if (!isBotAdmins) { 19 | return m.reply('*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*'); 20 | } 21 | 22 | if (!text) return m.reply(`*📛 ᴇɴᴛᴇʀ ᴛʜᴇ ɴᴜᴍʙᴇʀ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ɪɴᴠɪᴛᴇ ᴛᴏ ᴛʜᴇ ɢʀᴏᴜᴘ*\n\nExᴀᴍᴘʟᴇ:\n*${prefix + cmd}* 94720797915`); 23 | if (text.includes('+')) return m.reply(`*📛 ᴇɴᴛᴇʀ ᴛʜᴇ ɴᴜᴍʙᴇʀ ᴛᴏɢᴇᴛʜᴇʀ ᴡɪᴛʜᴏᴜᴛ *+*`); 24 | if (isNaN(text)) return m.reply(`*📛 ᴇɴᴛᴇʀ ᴏɴʟʏ ᴛʜᴇ ɴᴜᴍʙᴇʀꜱ ᴘʟᴜꜱ ʏᴏᴜʀ ᴄᴏᴜɴᴛʀʏ ᴄᴏᴅᴇ ᴡɪᴛʜᴏᴜᴛ ꜱᴘᴀᴄᴇꜱ`); 25 | 26 | const group = m.from; 27 | const groupMetadata = await gss.groupMetadata(group); 28 | const link = 'https://chat.whatsapp.com/' + await gss.groupInviteCode(group); 29 | const inviteMessage = `≡ *GROUP INVITATION*\n\nA USER INVITES YOU TO JOIN THE GROUP "${groupMetadata.subject}".\n\nInvite Link: ${link}\n\nINVITED BY: @${m.sender.split('@')[0]}`; 30 | 31 | await gss.sendMessage(`${text}@s.whatsapp.net`, { text: inviteMessage, mentions: [m.sender] }); 32 | m.reply(`*☑ AN INVITE LINK IS SENT TO THE USER.*`); 33 | 34 | } catch (error) { 35 | console.error('Error:', error); 36 | m.reply('An error occurred while processing the command.'); 37 | } 38 | }; 39 | 40 | export default invite; 41 | -------------------------------------------------------------------------------- /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/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 | 6 | const tourl = async (m, gss) => { 7 | const prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | const validCommands = ['removebg', 'nobg']; 11 | 12 | if (validCommands.includes(cmd)) { 13 | const apiKeys = [ 14 | 'q61faXzzR5zNU6cvcrwtUkRU', 'S258diZhcuFJooAtHTaPEn4T', 15 | '5LjfCVAp4vVNYiTjq9mXJWHF', 'aT7ibfUsGSwFyjaPZ9eoJc61', 16 | 'BY63t7Vx2tS68YZFY6AJ4HHF', '5Gdq1sSWSeyZzPMHqz7ENfi8', 17 | '86h6d6u4AXrst4BVMD9dzdGZ', 'xp8pSDavAgfE5XScqXo9UKHF', 18 | 'dWbCoCb3TacCP93imNEcPxcL' 19 | ]; 20 | const apiKey = apiKeys[Math.floor(Math.random() * apiKeys.length)]; 21 | 22 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 23 | return m.reply(`> Send/Reply with an image for remove you picture backgroud\n*Example ${prefix + cmd}*`); 24 | } 25 | 26 | const localFilePath = `./src/remobg-${uuidv4()}`; 27 | const outputFilePath = `./src/hremo-${uuidv4()}.png`; 28 | const media = await m.quoted.download(); 29 | 30 | fs.writeFileSync(localFilePath, media); 31 | 32 | m.reply('Processing...'); 33 | 34 | removeBackgroundFromImageFile({ 35 | path: localFilePath, 36 | apiKey, 37 | size: 'regular', 38 | type: 'auto', 39 | scale: '100%', 40 | outputFile: outputFilePath 41 | }).then(async () => { 42 | gss.sendMessage(m.from, { image: fs.readFileSync(outputFilePath), caption: `> Hey ${m.pushName} Your picture Background Romoved Sucessfully` }, { quoted: m }); 43 | fs.unlinkSync(localFilePath); 44 | fs.unlinkSync(outputFilePath); 45 | }).catch(error => { 46 | console.error('Error processing image:', error); 47 | m.reply('There was an error processing the image.'); 48 | fs.unlinkSync(localFilePath); 49 | }); 50 | } 51 | }; 52 | 53 | export default tourl; 54 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "👨‍💻MASTER-MD-V3👨‍💻", 3 | "description": "Master Md WhatsApp user bot created by mr sahan ofc.", 4 | "keywords": [ 5 | "whatsapp bot" 6 | ], 7 | "repository": "https://github.com/MrMasterOfc/MASTER-MD-V3", 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": true, 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 | }, 56 | "buildpacks": [ 57 | { 58 | "url": "heroku/nodejs" 59 | }, 60 | { 61 | "url": "https://github.com/DuckyTeam/heroku-buildpack-imagemagick.git" 62 | }, 63 | { 64 | "url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest" 65 | }, 66 | { 67 | "url": "https://github.com/clhuang/heroku-buildpack-webp-binaries.git" 68 | } 69 | ] 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/plugin/status.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | 3 | const handleGreeting = async (m, gss) => { 4 | try { 5 | const textLower = m.body.toLowerCase(); 6 | 7 | const triggerWords = [ 8 | 'save','send','dpm','dpn','oni','evanna','ewanna','evahan','ewahan','dapan','meka','mekath','evannako','ewannako','dahan','ewahan','dpam','ewa','eva','dapm','ewano','evano','ewno','ewnna','evnna','snd','ewana','evana','danna','dannako','dannko','dnnko','ewapam','evapam','evapan','ewaham','dako','sv', 'sav', 'seve' 9 | ]; 10 | 11 | if (triggerWords.includes(textLower)) { 12 | if (m.message && m.message.extendedTextMessage && m.message.extendedTextMessage.contextInfo) { 13 | const quotedMessage = m.message.extendedTextMessage.contextInfo.quotedMessage; 14 | 15 | if (quotedMessage) { 16 | // Check if it's an image 17 | if (quotedMessage.imageMessage) { 18 | const imageCaption = quotedMessage.imageMessage.caption; 19 | const imageUrl = await gss.downloadAndSaveMediaMessage(quotedMessage.imageMessage); 20 | await gss.sendMessage(m.from, { 21 | image: { url: imageUrl }, 22 | caption: imageCaption, 23 | contextInfo: { 24 | mentionedJid: [m.sender], 25 | forwardingScore: 9999, 26 | isForwarded: true, 27 | }, 28 | }); 29 | } 30 | 31 | // Check if it's a video 32 | if (quotedMessage.videoMessage) { 33 | const videoCaption = quotedMessage.videoMessage.caption; 34 | const videoUrl = await gss.downloadAndSaveMediaMessage(quotedMessage.videoMessage); 35 | await gss.sendMessage(m.from, { 36 | video: { url: videoUrl }, 37 | caption: videoCaption, 38 | contextInfo: { 39 | mentionedJid: [m.sender], 40 | forwardingScore: 9999, 41 | isForwarded: true, 42 | }, 43 | }); 44 | } 45 | } 46 | } 47 | } 48 | } catch (error) { 49 | console.error('Error:', error); 50 | } 51 | }; 52 | 53 | export default handleGreeting; 54 | -------------------------------------------------------------------------------- /src/plugin/remove.js: -------------------------------------------------------------------------------- 1 | const kick = async (m, gss) => { 2 | try { 3 | const botNumber = await gss.decodeJid(gss.user.id); 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['kick', 'remove']; 10 | 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 14 | const groupMetadata = await gss.groupMetadata(m.from); 15 | const participants = groupMetadata.participants; 16 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 17 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 18 | 19 | if (!botAdmin) return m.reply("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 20 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 21 | 22 | if (!m.mentionedJid) m.mentionedJid = []; 23 | 24 | if (m.quoted?.participant) m.mentionedJid.push(m.quoted.participant); 25 | 26 | const users = m.mentionedJid.length > 0 27 | ? m.mentionedJid 28 | : text.replace(/[^0-9]/g, '').length > 0 29 | ? [text.replace(/[^0-9]/g, '') + '@s.whatsapp.net'] 30 | : []; 31 | 32 | if (users.length === 0) { 33 | return m.reply("*📛 𝐏ʟᴇᴀꜱᴇ 𝐌ᴇɴᴛɪᴏɴ 𝐎ʀ 𝐐ᴜᴏᴛᴇ 𝐀 𝐔ꜱᴇʀ 𝐓ᴏ 𝐊ɪᴄᴋ*"); 34 | } 35 | 36 | const validUsers = users.filter(Boolean); 37 | 38 | await gss.groupParticipantsUpdate(m.from, validUsers, 'remove') 39 | .then(() => { 40 | const kickedNames = validUsers.map(user => `@${user.split("@")[0]}`); 41 | m.reply(`*USERS ${kickedNames} KICKED SUCCESSFULLY FROM THE GROUP ${groupMetadata.subject}*`); 42 | }) 43 | .catch(() => m.reply('Failed to kick user(s) from the group.')); 44 | } catch (error) { 45 | console.error('Error:', error); 46 | m.reply('An error occurred while processing the command.'); 47 | } 48 | }; 49 | 50 | export default kick; 51 | -------------------------------------------------------------------------------- /src/plugin/demote.js: -------------------------------------------------------------------------------- 1 | const demote = async (m, gss) => { 2 | try { 3 | const prefixMatch = m.body.match(/^[\\/!#.]/); 4 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 | const validCommands = ['demote', 'unadmin']; 9 | 10 | if (!validCommands.includes(cmd)) return; 11 | 12 | 13 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 14 | const groupMetadata = await gss.groupMetadata(m.from); 15 | const participants = groupMetadata.participants; 16 | const botNumber = await gss.decodeJid(gss.user.id); 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("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 21 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 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("*📛 𝐏ʟᴇᴀꜱᴇ 𝐌ᴇɴᴛɪᴏɴ 𝐎ʀ 𝐐ᴜᴏᴛᴇ 𝐀 𝐔ꜱᴇʀ 𝐓ᴏ 𝐃ᴇᴍᴏᴛᴇ*"); 35 | } 36 | 37 | const validUsers = users.filter(Boolean); 38 | 39 | await gss.groupParticipantsUpdate(m.from, validUsers, 'demote') 40 | .then(() => { 41 | const demotedNames = validUsers.map(user => `@${user.split("@")[0]}`); 42 | m.reply(`*USERS ${demotedNames} DEMOTED SUCCESSFULLY IN THE GROUP ${groupMetadata.subject}*`); 43 | }) 44 | .catch(() => m.reply('Failed to demote user(s) in 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 demote; 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MASTER-MD-V3", 3 | "version": "10.8.1", 4 | "description": "MASTER-MD latest multi device whatsapp bot", 5 | "main": "src/index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "pm2 start src/index.js --deep-monitoring --attach --name MASTER-MD-V3", 9 | "stop": "pm2 stop MASTER-MD-V3", 10 | "restart": "pm2 restart MASTER-MD-V3" 11 | }, 12 | "keywords": ["master-md", "whatsapp-bot", "whatsapp md bot"], 13 | "author": "Sahan Maduwantha", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@distube/ytdl-core": "^4.13.5", 17 | "@ffmpeg-installer/ffmpeg": "^1.1.0", 18 | "@google/generative-ai": "^0.9.0", 19 | "@hapi/boom": "^10.0.1", 20 | "@whiskeysockets/baileys": "^6.7.5", 21 | "@xaviabot/fb-downloader": "^1.0.14", 22 | "acrcloud": "^1.4.0", 23 | "api-dylux": "^1.8.3", 24 | "aptoide-scraper": "^1.0.1", 25 | "awesome-phonenumber": "^6.8.0", 26 | "axios": "^1.6.8", 27 | "betabotz-tools": "^0.0.7", 28 | "chalk": "^5.3.0", 29 | "child_process": "^1.0.2", 30 | "crypto": "^1.0.1", 31 | "dotenv": "^16.4.5", 32 | "express": "^4.19.2", 33 | "ffmpeg": "^0.0.4", 34 | "file-type": "^19.0.0", 35 | "fluent-ffmpeg": "^2.1.3", 36 | "fs": "^0.0.1-security", 37 | "google-it": "^1.6.4", 38 | "human-readable": "^0.2.1", 39 | "instagram-user": "^2.0.1", 40 | "jimp": "^0.16.13", 41 | "jpeg-js": "^0.4.4", 42 | "jsqr": "^1.4.0", 43 | "libphonenumber": "^0.0.10", 44 | "mfiredlcore-vihangayt": "^1.0.0", 45 | "moment-timezone": "^0.5.45", 46 | "nayan-media-downloader": "^2.3.3", 47 | "node-cache": "^5.1.2", 48 | "node-cron": "^3.0.3", 49 | "node-fetch": "^3.3.2", 50 | "node-os-utils": "^1.3.7", 51 | "node-webpmux": "^3.2.0", 52 | "os": "^0.1.2", 53 | "pdfkit": "^0.15.0", 54 | "pino": "^8.20.0", 55 | "play-dl": "^1.9.7", 56 | "pm2": "^5.4.0", 57 | "proto": "^1.0.19", 58 | "qrcode": "^1.5.3", 59 | "readline": "^1.3.0", 60 | "remove.bg": "^1.3.0", 61 | "tesseract.js": "^5.1.0", 62 | "translate-google-api": "^1.0.4", 63 | "uuid": "^9.0.1", 64 | "yt-search": "^2.11.0", 65 | "ytdl-core": "^4.11.5" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/plugin/imdb.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const imdb = async (m, gss) => { 4 | try { 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 text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['imdb']; 11 | 12 | if (!validCommands.includes(cmd)) return; 13 | 14 | if (!text) return m.reply('Give me a series or movie name'); 15 | 16 | let fids = await axios.get(`http://www.omdbapi.com/?apikey=742b2d09&t=${encodeURIComponent(text)}&plot=full`); 17 | let imdbt = ""; 18 | 19 | if (fids.data.Response === "False") { 20 | return m.reply('Movie or series not found'); 21 | } 22 | 23 | imdbt += "⚍⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚍\n"; 24 | imdbt += " ```IMDB SEARCH```\n"; 25 | imdbt += "⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎⚎\n"; 26 | imdbt += `🎬Title : ${fids.data.Title}\n`; 27 | imdbt += `📅Year : ${fids.data.Year}\n`; 28 | imdbt += `⭐Rated : ${fids.data.Rated}\n`; 29 | imdbt += `📆Released : ${fids.data.Released}\n`; 30 | imdbt += `⏳Runtime : ${fids.data.Runtime}\n`; 31 | imdbt += `🌀Genre : ${fids.data.Genre}\n`; 32 | imdbt += `👨🏻‍💻Director : ${fids.data.Director}\n`; 33 | imdbt += `✍Writer : ${fids.data.Writer}\n`; 34 | imdbt += `👨Actors : ${fids.data.Actors}\n`; 35 | imdbt += `📃Plot : ${fids.data.Plot}\n`; 36 | imdbt += `🌐Language : ${fids.data.Language}\n`; 37 | imdbt += `🌍Country : ${fids.data.Country}\n`; 38 | imdbt += `🎖️Awards : ${fids.data.Awards}\n`; 39 | imdbt += `📦BoxOffice : ${fids.data.BoxOffice}\n`; 40 | imdbt += `🏙️Production : ${fids.data.Production}\n`; 41 | imdbt += `🌟imdbRating : ${fids.data.imdbRating}\n`; 42 | imdbt += `✅imdbVotes : ${fids.data.imdbVotes}\n`; 43 | 44 | await gss.sendMessage(m.from, { 45 | image: { 46 | url: fids.data.Poster, 47 | }, 48 | caption: imdbt, 49 | }, { 50 | quoted: m, 51 | }); 52 | } catch (error) { 53 | console.error('Error:', error); 54 | m.reply('An error occurred while fetching the data.'); 55 | } 56 | }; 57 | 58 | export default imdb; 59 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/plugin/fullpp.js: -------------------------------------------------------------------------------- 1 | import generateProfilePicture from '../generateProfilePicture.js'; // Import the generateProfilePicture function 2 | import { writeFile, unlink } from 'fs/promises'; 3 | import config from '../../config.cjs'; 4 | 5 | const setProfilePicture = async (m, gss) => { 6 | const botNumber = await gss.decodeJid(gss.user.id); 7 | const isCreator = [botNumber, config.OWNER_NUMBER + '@s.whatsapp.net'].includes(m.sender); 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 | const text = m.body.slice(prefix.length + cmd.length).trim(); 12 | 13 | const validCommands = ['setppfull', 'setfullprofilepic', 'fullpp', 'setppbot']; 14 | 15 | if (validCommands.includes(cmd)) { 16 | if (!isCreator) return m.reply("*📛 𝐓ʜɪꜱ 𝐈ꜱ 𝐀ɴ 𝐎ᴡɴᴇʀ 𝐂ᴏᴍᴍᴀɴᴅ*"); 17 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 18 | return m.reply(`*Send/Reply with an image to set your profile picture ${prefix + cmd}*`); 19 | } 20 | 21 | try { 22 | const media = await m.quoted.download(); // Download the media from the quoted message 23 | if (!media) throw new Error('Failed to download media.'); 24 | 25 | const filePath = `./${Date.now()}.png`; 26 | await writeFile(filePath, media); 27 | 28 | try { 29 | const { img } = await generateProfilePicture(media); // Generate profile picture 30 | await gss.query({ 31 | tag: 'iq', 32 | attrs: { 33 | to: botNumber, 34 | type: 'set', 35 | xmlns: 'w:profile:picture' 36 | }, 37 | content: [{ 38 | tag: 'picture', 39 | attrs: { 40 | type: 'image' 41 | }, 42 | content: img 43 | }] 44 | }); 45 | m.reply('*Profile picture updated successfully.*'); 46 | } catch (err) { 47 | throw err; 48 | } finally { 49 | await unlink(filePath); // Clean up the downloaded file 50 | } 51 | } catch (error) { 52 | console.error('Error setting profile picture:', error); 53 | m.reply('Error setting profile picture.'); 54 | } 55 | } 56 | }; 57 | 58 | export default setProfilePicture; 59 | -------------------------------------------------------------------------------- /src/plugin/rvo.js: -------------------------------------------------------------------------------- 1 | import { downloadContentFromMessage } from '@whiskeysockets/baileys'; 2 | import fs from 'fs'; 3 | 4 | const rvo = async (m, sock) => { 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 = ['rvo', 'vv', 'readviewonce']; 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')) { 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> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ`; 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 sock.sendMessage(m.from, { 38 | video: buffer, 39 | caption: newCaption, 40 | contextInfo: { 41 | mentionedJid: [m.sender], 42 | forwardingScore: 9999, 43 | isForwarded: true, 44 | } 45 | }, { quoted: m }); 46 | } else if (/image/.test(type)) { 47 | await sock.sendMessage(m.from, { 48 | image: buffer, 49 | caption: newCaption, 50 | contextInfo: { 51 | mentionedJid: [m.sender], 52 | forwardingScore: 9999, 53 | isForwarded: true, 54 | } 55 | }, { quoted: m }); 56 | } 57 | } catch (e) { 58 | console.error('Error:', e); 59 | m.reply('An error occurred while processing the command.'); 60 | } 61 | }; 62 | 63 | export default rvo; 64 | -------------------------------------------------------------------------------- /src/plugin/whatmusic.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import acrcloud from 'acrcloud'; 3 | 4 | // Initialize ACRCloud client with your credentials 5 | const acr = new acrcloud({ 6 | host: 'identify-eu-west-1.acrcloud.com', 7 | access_key: '716b4ddfa557144ce0a459344fe0c2c9', 8 | access_secret: 'Lz75UbI8g6AzkLRQgTgHyBlaQq9YT5wonr3xhFkf' 9 | }); 10 | 11 | const shazam = async (m, gss) => { 12 | try { 13 | const prefixMatch = m.body.match(/^[\\/!#.]/); 14 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 15 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 16 | 17 | const validCommands = ['shazam', 'find', 'whatmusic']; 18 | if (!validCommands.includes(cmd)) return; 19 | 20 | const quoted = m.quoted || {}; 21 | 22 | if (!quoted || (quoted.mtype !== 'audioMessage' && quoted.mtype !== 'videoMessage')) { 23 | return m.reply('You asked about music. Please provide a quoted audio or video message for identification.'); 24 | } 25 | 26 | const mime = m.quoted.mimetype; 27 | try { 28 | const media = await m.quoted.download(); 29 | const filePath = `./${Date.now()}.mp3`; 30 | fs.writeFileSync(filePath, media); 31 | 32 | m.reply('Identifying the music, please wait...'); 33 | 34 | const res = await acr.identify(fs.readFileSync(filePath)); 35 | const { code, msg } = res.status; 36 | 37 | if (code !== 0) { 38 | throw new Error(msg); 39 | } 40 | 41 | const { title, artists, album, genres, release_date } = res.metadata.music[0]; 42 | const txt = `𝚁𝙴𝚂𝚄𝙻𝚃 43 | • 📌 *TITLE*: ${title} 44 | • 👨‍🎤 𝙰𝚁𝚃𝙸𝚂𝚃: ${artists ? artists.map(v => v.name).join(', ') : 'NOT FOUND'} 45 | • 💾 𝙰𝙻𝙱𝚄𝙼: ${album ? album.name : 'NOT FOUND'} 46 | • 🌐 𝙶𝙴𝙽𝚁𝙴: ${genres ? genres.map(v => v.name).join(', ') : 'NOT FOUND'} 47 | • 📆 RELEASE DATE: ${release_date || 'NOT FOUND'} 48 | `.trim(); 49 | 50 | fs.unlinkSync(filePath); 51 | m.reply(txt); 52 | } catch (error) { 53 | console.error(error); 54 | m.reply('An error occurred during music identification.'); 55 | } 56 | } catch (error) { 57 | console.error('Error:', error); 58 | m.reply('An Error Occurred While Processing The Command.'); 59 | } 60 | }; 61 | 62 | export default shazam; 63 | -------------------------------------------------------------------------------- /src/plugin/qc.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const quotedChat = async (m, gss) => { 4 | try { 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 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: "> Ethix-MD" 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/sticker.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs/promises'; 2 | import config from '../../config.cjs'; 3 | 4 | const stickerCommand = async (m, gss) => { 5 | const prefixMatch = m.body.match(/^[\\/!#.]/); 6 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 7 | const [cmd, arg] = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ') : ['', '']; 8 | 9 | const packname = global.packname || "MASTER-MD"; 10 | const author = global.author || "Sahan"; 11 | 12 | const validCommands = ['sticker', 's', 'autosticker']; 13 | 14 | if (cmd === 'autosticker') { 15 | if (arg === 'on') { 16 | config.AUTO_STICKER = true; 17 | await m.reply('Auto-sticker is now enabled.'); 18 | } else if (arg === 'off') { 19 | config.AUTO_STICKER = false; 20 | await m.reply('Auto-sticker is now disabled.'); 21 | } else { 22 | await m.reply('Usage: /autosticker on|off'); 23 | } 24 | return; 25 | } 26 | 27 | // Auto sticker functionality using config 28 | if (config.AUTO_STICKER && !m.key.fromMe) { 29 | if (m.type === 'imageMessage') { 30 | let mediac = await m.download(); 31 | await gss.sendImageAsSticker(m.from, mediac, m, { packname, author }); 32 | console.log(`Auto sticker detected`); 33 | return; 34 | } else if (m.type === 'videoMessage' && m.msg.seconds <= 11) { 35 | let mediac = await m.download(); 36 | await gss.sendVideoAsSticker(m.from, mediac, m, { packname, author }); 37 | return; 38 | } 39 | } 40 | 41 | if (validCommands.includes(cmd)) { 42 | const quoted = m.quoted || {}; 43 | 44 | if (!quoted || (quoted.mtype !== 'imageMessage' && quoted.mtype !== 'videoMessage')) { 45 | return m.reply(`Send/Reply with an image or video to convert into a sticker ${prefix + cmd}`); 46 | } 47 | 48 | const media = await quoted.download(); 49 | if (!media) throw new Error('Failed to download media.'); 50 | 51 | const filePath = `./${Date.now()}.${quoted.mtype === 'imageMessage' ? 'png' : 'mp4'}`; 52 | await fs.writeFile(filePath, media); 53 | 54 | if (quoted.mtype === 'imageMessage') { 55 | const stickerBuffer = await fs.readFile(filePath); 56 | await gss.sendImageAsSticker(m.from, stickerBuffer, m, { packname, author }); 57 | } else if (quoted.mtype === 'videoMessage') { 58 | await gss.sendVideoAsSticker(m.from, filePath, m, { packname, author }); 59 | } 60 | } 61 | }; 62 | 63 | export default stickerCommand; 64 | -------------------------------------------------------------------------------- /src/remini.cjs: -------------------------------------------------------------------------------- 1 | const _0x266dca=_0x394d;(function(_0x35644c,_0x2bf644){const _0x7b2243=_0x394d,_0xad5d31=_0x35644c();while(!![]){try{const _0x3889fd=-parseInt(_0x7b2243(0xbe))/0x1*(-parseInt(_0x7b2243(0xcb))/0x2)+parseInt(_0x7b2243(0xb1))/0x3+-parseInt(_0x7b2243(0xb5))/0x4*(-parseInt(_0x7b2243(0xc9))/0x5)+parseInt(_0x7b2243(0xcc))/0x6+parseInt(_0x7b2243(0xc5))/0x7*(parseInt(_0x7b2243(0xbc))/0x8)+-parseInt(_0x7b2243(0xd1))/0x9*(-parseInt(_0x7b2243(0xba))/0xa)+parseInt(_0x7b2243(0xcf))/0xb*(-parseInt(_0x7b2243(0xb4))/0xc);if(_0x3889fd===_0x2bf644)break;else _0xad5d31['push'](_0xad5d31['shift']());}catch(_0x35fcd2){_0xad5d31['push'](_0xad5d31['shift']());}}}(_0x1c77,0x457b7));function _0x1c77(){const _0x589c7f=['submit','error','22TuGnJG','gzip','1116QxodIW','push','.ai','dehaze','https','806484XUnwrW','jimp','binary','7115460KRQhmI','1101112SegLTh','end','from','enhance_image_body.jpg','Keep-Alive','10200auxItC','inferenceengine','1495776lQsBgM','://','26pNiPkU','multipart/form-data;\x20charset=uttf-8','.ai/','recolor','.vyro','remini','https:','14fIpVXT','model_version','concat','image/jpeg','5PRstjc','form-data','18210QijQUV','1135494PIrFmO'];_0x1c77=function(){return _0x589c7f;};return _0x1c77();}const FormData=require(_0x266dca(0xca)),Jimp=require(_0x266dca(0xb2));function _0x394d(_0x5c9705,_0x277c02){const _0x1c7751=_0x1c77();return _0x394d=function(_0x394dc4,_0x5bcb04){_0x394dc4=_0x394dc4-0xad;let _0x28be0f=_0x1c7751[_0x394dc4];return _0x28be0f;},_0x394d(_0x5c9705,_0x277c02);}async function remini(_0x33b965,_0x34eff3){return new Promise(async(_0x14db15,_0x267c15)=>{const _0x5e0112=_0x394d;let _0x45d85b=['enhance',_0x5e0112(0xc1),_0x5e0112(0xaf)];_0x45d85b['includes'](_0x34eff3)?_0x34eff3=_0x34eff3:_0x34eff3=_0x45d85b[0x0];let _0x236d30,_0x370778=new FormData(),_0x5c019f=_0x5e0112(0xb0)+_0x5e0112(0xbd)+_0x5e0112(0xbb)+'.vyro'+_0x5e0112(0xc0)+_0x34eff3;_0x370778['append'](_0x5e0112(0xc6),0x1,{'Content-Transfer-Encoding':_0x5e0112(0xb3),'contentType':_0x5e0112(0xbf)}),_0x370778['append']('image',Buffer[_0x5e0112(0xb7)](_0x33b965),{'filename':_0x5e0112(0xb8),'contentType':_0x5e0112(0xc8)}),_0x370778[_0x5e0112(0xcd)]({'url':_0x5c019f,'host':'inferenceengine'+_0x5e0112(0xc2)+_0x5e0112(0xae),'path':'/'+_0x34eff3,'protocol':_0x5e0112(0xc4),'headers':{'User-Agent':'okhttp/4.9.3','Connection':_0x5e0112(0xb9),'Accept-Encoding':_0x5e0112(0xd0)}},function(_0x319120,_0x175e8d){const _0xe7b13c=_0x5e0112;if(_0x319120)_0x267c15();let _0x15e24d=[];_0x175e8d['on']('data',function(_0x2918a5,_0x2d4e53){const _0x1e12ae=_0x394d;_0x15e24d[_0x1e12ae(0xad)](_0x2918a5);})['on'](_0xe7b13c(0xb6),()=>{const _0x3eb77e=_0xe7b13c;_0x14db15(Buffer[_0x3eb77e(0xc7)](_0x15e24d));}),_0x175e8d['on'](_0xe7b13c(0xce),_0x90e19c=>{_0x267c15();});});});}module['exports'][_0x266dca(0xc3)]=remini; 2 | -------------------------------------------------------------------------------- /src/plugin/gcfullpp.js: -------------------------------------------------------------------------------- 1 | import generateProfilePicture from '../generateProfilePicture.js'; // Import the generateProfilePicture function 2 | import { writeFile, unlink } from 'fs/promises'; 3 | import config from '../../config.cjs'; 4 | 5 | const setProfilePictureGroup = async (m, gss) => { 6 | const prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['setppfullgroup', 'setfullprofilepicgc', 'fullppgc']; 12 | 13 | if (validCommands.includes(cmd)) { 14 | 15 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 16 | const groupMetadata = await gss.groupMetadata(m.from); 17 | const participants = groupMetadata.participants; 18 | const botNumber = await gss.decodeJid(gss.user.id); 19 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 20 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 21 | 22 | if (!botAdmin) return m.reply("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 23 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 24 | if (!m.quoted || m.quoted.mtype !== 'imageMessage') { 25 | return m.reply(`Send/Reply with an image to set your profile picture ${prefix + cmd}`); 26 | } 27 | 28 | try { 29 | const media = await m.quoted.download(); // Download the media from the quoted message 30 | if (!media) throw new Error('Failed to download media.'); 31 | 32 | const filePath = `./${Date.now()}.png`; 33 | await writeFile(filePath, media); 34 | 35 | try { 36 | const { img } = await generateProfilePicture(media); // Generate profile picture 37 | await gss.query({ 38 | tag: 'iq', 39 | attrs: { 40 | to: m.from, 41 | type: 'set', 42 | xmlns: 'w:profile:picture' 43 | }, 44 | content: [{ 45 | tag: 'picture', 46 | attrs: { 47 | type: 'image' 48 | }, 49 | content: img 50 | }] 51 | }); 52 | m.reply('Profile picture updated successfully.'); 53 | } catch (err) { 54 | throw err; 55 | } finally { 56 | await unlink(filePath); // Clean up the downloaded file 57 | } 58 | } catch (error) { 59 | console.error('Error setting profile picture:', error); 60 | m.reply('Error setting profile picture.'); 61 | } 62 | } 63 | }; 64 | 65 | export default setProfilePictureGroup; 66 | -------------------------------------------------------------------------------- /src/plugin/promote.js: -------------------------------------------------------------------------------- 1 | const promote = async (m, gss) => { 2 | try { 3 | const botNumber = await gss.decodeJid(gss.user.id); 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['promote', 'admin', 'toadmin']; 10 | 11 | if (!validCommands.includes(cmd)) return; 12 | 13 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 14 | const groupMetadata = await gss.groupMetadata(m.from); 15 | const participants = groupMetadata.participants; 16 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 17 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 18 | 19 | if (!botAdmin) return m.reply("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 20 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 21 | 22 | if (!m.mentionedJid) m.mentionedJid = []; 23 | 24 | if (m.quoted?.participant) m.mentionedJid.push(m.quoted.participant); 25 | 26 | const users = m.mentionedJid.length > 0 27 | ? m.mentionedJid 28 | : text.replace(/[^0-9]/g, '').length > 0 29 | ? [text.replace(/[^0-9]/g, '') + '@s.whatsapp.net'] 30 | : []; 31 | 32 | if (users.length === 0) { 33 | return m.reply("*📛 𝐏ʟᴇᴀꜱᴇ 𝐌ᴇɴᴛɪᴏɴ 𝐎ʀ 𝐐ᴜᴏᴛᴇ 𝐀 𝐔ꜱᴇʀ 𝐓ᴏ 𝐏ʀᴏᴍᴏᴛᴇ*"); 34 | } 35 | console.log('users: ', users) 36 | const validUsers = users.filter(Boolean); 37 | 38 | const usernames = await Promise.all( 39 | validUsers.map(async (user) => { 40 | console.log('user: ', user) 41 | try { 42 | const contact = await gss.getContact(user); 43 | console.log('contact: ', contact) 44 | return contact.notify || contact.pushname || user.split('@')[0]; 45 | } catch (error) { 46 | return user.split('@')[0]; 47 | } 48 | }) 49 | ); 50 | console.log('usernames: ', usernames) 51 | 52 | await gss.groupParticipantsUpdate(m.from, validUsers, 'promote') 53 | .then(() => { 54 | const promotedNames = usernames.map(username => `@${username}`).join(', '); 55 | m.reply(`*Users ${promotedNames} promoted successfully in the group ${groupMetadata.subject}.*`); 56 | }) 57 | .catch(() => m.reply('Failed to promote user(s) in the group.')); 58 | } catch (error) { 59 | console.error('Error:', error); 60 | m.reply('An error occurred while processing the command.'); 61 | } 62 | }; 63 | 64 | export default promote; -------------------------------------------------------------------------------- /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/colombo').format('HH:mm:ss'); 21 | const joinDate = moment.tz('Asia/colombo').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/colombo').format('HH:mm:ss'); 40 | const leaveDate = moment.tz('Asia/colombo').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'; // Assuming you have a utility function for generating random file names 4 | 5 | const audioEffects = async (m, gss) => { 6 | try { 7 | const prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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/alive.js: -------------------------------------------------------------------------------- 1 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 2 | const { generateWAMessageFromContent, proto } = pkg; 3 | 4 | const alive = async (m, Matrix) => { 5 | const uptimeSeconds = process.uptime(); 6 | const days = Math.floor(uptimeSeconds / (24 * 3600)); 7 | const hours = Math.floor((uptimeSeconds % (24 * 3600)) / 3600); 8 | const minutes = Math.floor((uptimeSeconds % 3600) / 60); 9 | const seconds = Math.floor(uptimeSeconds % 60); 10 | 11 | const prefix = /^[\\/!#.]/gi.test(m.body) ? m.body.match(/^[\\/!#.]/gi)[0] : '/'; 12 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).toLowerCase() : ''; 13 | if (['alive', 'uptime', 'runtime'].includes(cmd)) { 14 | 15 | const uptimeMessage = `*👨‍💻MASTER-MD-V3 IS ALIVE👨‍💻* 16 | _________________________________________ 17 | 18 | *📆 Day: ${days} Day* 19 | *🕰️Hour: ${hours} Hour* 20 | *⏳ Minute: ${minutes} Minute* 21 | *⏲️ Second: ${seconds} Second* 22 | *👨‍💻Developer: MASTER MIND* 23 | _________________________________________ 24 | `; 25 | 26 | const buttons = [ 27 | { 28 | "name": "quick_reply", 29 | "buttonParamsJson": JSON.stringify({ 30 | display_text: "MENU", 31 | id: `.menu` 32 | }) 33 | }, 34 | { 35 | "name": "quick_reply", 36 | "buttonParamsJson": JSON.stringify({ 37 | display_text: "PING", 38 | id: `.ping` 39 | }) 40 | } 41 | ]; 42 | 43 | const msg = generateWAMessageFromContent(m.from, { 44 | viewOnceMessage: { 45 | message: { 46 | messageContextInfo: { 47 | deviceListMetadata: {}, 48 | deviceListMetadataVersion: 2 49 | }, 50 | interactiveMessage: proto.Message.InteractiveMessage.create({ 51 | body: proto.Message.InteractiveMessage.Body.create({ 52 | text: uptimeMessage 53 | }), 54 | footer: proto.Message.InteractiveMessage.Footer.create({ 55 | text: "© 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ" 56 | }), 57 | header: proto.Message.InteractiveMessage.Header.create({ 58 | title: "", 59 | gifPlayback: true, 60 | subtitle: "", 61 | hasMediaAttachment: false 62 | }), 63 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 64 | buttons 65 | }), 66 | contextInfo: { 67 | mentionedJid: [m.sender], 68 | forwardingScore: 999, 69 | isForwarded: true, 70 | forwardedNewsletterMessageInfo: { 71 | newsletterJid: '120363249960769123@newsletter', 72 | newsletterName: "MASTER-MD-V3", 73 | serverMessageId: 143 74 | } 75 | } 76 | }), 77 | }, 78 | }, 79 | }, {}); 80 | 81 | await Matrix.relayMessage(msg.key.remoteJid, msg.message, { 82 | messageId: msg.key.id 83 | }); 84 | } 85 | }; 86 | 87 | export default alive; 88 | -------------------------------------------------------------------------------- /src/plugin/crick.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const cricketScore = async (m, Matrix) => { 4 | const prefixMatch = m.body.match(/^[\\/!#.]/); 5 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 += `│⿻ 👨‍💻MASTER-MD-V3👨‍💻*\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/trt.js: -------------------------------------------------------------------------------- 1 | import Tesseract from 'tesseract.js'; 2 | import translate from 'translate-google-api'; 3 | import { writeFile } from 'fs/promises'; 4 | 5 | const translateCommand = async (m, sock, config) => { 6 | const prefixMatch = m.body.match(/^[\\/!#.]/); 7 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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().split(' '); 10 | 11 | 12 | 13 | const validCommands = ['translate', 'trt']; 14 | 15 | if (validCommands.includes(cmd)) { 16 | const targetLang = args[0]; 17 | const text = args.slice(1).join(' '); 18 | 19 | if (m.quoted) { 20 | if (m.quoted.mtype === 'imageMessage') { 21 | try { 22 | const media = await m.quoted.download(); // Download the media from the quoted message 23 | if (!media) throw new Error('Failed to download media.'); 24 | 25 | const filePath = `./${Date.now()}.png`; 26 | await writeFile(filePath, media); // Save the downloaded media to a file 27 | 28 | // Perform OCR using Tesseract.js 29 | const { data: { text: extractedText } } = await Tesseract.recognize(filePath, 'eng', { 30 | logger: m => console.log(m) 31 | }); 32 | 33 | const result = await translate(extractedText, { to: targetLang }); 34 | const translatedText = result[0]; 35 | 36 | const responseMessage = `${targetLang}:\n\n${translatedText}`; 37 | await sock.sendMessage(m.from, { text: responseMessage }, { quoted: m }); // Send the extracted and translated text back to the user 38 | } catch (error) { 39 | console.error("Error extracting and translating text from image:", error); 40 | await sock.sendMessage(m.from, { text: 'Error extracting and translating text from image.' }, { quoted: m }); // Error handling 41 | } 42 | } else if (m.quoted.text) { 43 | try { 44 | const quotedText = m.quoted.text; 45 | const result = await translate(quotedText, { to: targetLang }); 46 | const translatedText = result[0]; 47 | 48 | const responseMessage = `${targetLang}:\n\n${translatedText}`; 49 | await sock.sendMessage(m.from, { text: responseMessage }, { quoted: m }); // Send the translated text back to the user 50 | } catch (error) { 51 | console.error("Error translating quoted text:", error); 52 | await sock.sendMessage(m.from, { text: 'Error translating quoted text.' }, { quoted: m }); // Error handling 53 | } 54 | } 55 | } else if (text && targetLang) { 56 | try { 57 | const result = await translate(text, { to: targetLang }); 58 | const translatedText = result[0]; 59 | 60 | const responseMessage = `${targetLang}:\n\n${translatedText}`; 61 | await sock.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 62 | } catch (error) { 63 | console.error("Error translating text:", error); 64 | await sock.sendMessage(m.from, { text: 'Error translating text.' }, { quoted: m }); 65 | } 66 | } else { 67 | const responseMessage = "Usage: /translate \nExample: /translate en कैसे हो भाई\nOr reply to an image/text message with /translate "; 68 | await sock.sendMessage(m.from, { text: responseMessage }, { quoted: m }); 69 | } 70 | } 71 | }; 72 | 73 | export default translateCommand; 74 | -------------------------------------------------------------------------------- /src/plugin/repo.js: -------------------------------------------------------------------------------- 1 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 2 | const { generateWAMessageFromContent, proto } = pkg; 3 | 4 | const alive = async (m, Matrix) => { 5 | const uptimeSeconds = process.uptime(); 6 | const days = Math.floor(uptimeSeconds / (24 * 3600)); 7 | const hours = Math.floor((uptimeSeconds % (24 * 3600)) / 3600); 8 | const minutes = Math.floor((uptimeSeconds % 3600) / 60); 9 | const seconds = Math.floor(uptimeSeconds % 60); 10 | 11 | const prefix = /^[\\/!#.]/gi.test(m.body) ? m.body.match(/^[\\/!#.]/gi)[0] : '/'; 12 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).toLowerCase() : ''; 13 | if (['repo', 'sc'].includes(cmd)) { 14 | 15 | const uptimeMessage = ` 16 | _________________________________________ 17 | *🔰GitHub Profile - @MrMasterOfc* 18 | *🔰Name: 𝙎𝙖𝙝𝙖𝙣 𝙈𝙖𝙙𝙪𝙬𝙖𝙣𝙩𝙝𝙖👨‍💻* 19 | *🔰Username:* @MrMasterOfc 20 | *🔰Bio: 𝐌𝐚𝐬𝐭𝐞𝐫_𝐲𝐨𝐮𝐫_𝐌𝐢𝐧𝐝* 21 | *𝐌𝐚𝐬𝐭𝐞𝐫_𝐲𝐨𝐮𝐫_𝐋𝐢𝐟𝐞* 22 | *@𝐬𝐚𝐡𝐚𝐧𝐚𝐲𝐚𝟐𝟎𝟎𝟔* 23 | *🔰IDID:* 125999503 24 | *🔰Node IDD:* U_kgDOB4KZjw 25 | *🔰Profile URL:* https://avatars.githubusercontent.com/u/125999503?v=4 26 | *🔰GitHub URL:* https://github.com/MrMasterOfc 27 | *🔰Adminin:* No 28 | *🔰Companyy:* MASTER MIND 29 | *🔰Blogg:* https://mr-sahan-ofc.vercel.app/index.html 30 | *🔰Locationon:* Asia/Colombo 31 | *🔰Emailil:* N/A 32 | *🔰Public Repositorieses:* 13 33 | _________________________________________ 34 | `; 35 | 36 | const buttons = [ 37 | { 38 | "name": "cta_url", 39 | "buttonParamsJson": JSON.stringify({ 40 | display_text: "GITHUB", 41 | url: `https://github.com/MrMasterOfc/MASTER-MD-V3/fork` 42 | }) 43 | }, 44 | { 45 | "name": "quick_reply", 46 | "buttonParamsJson": JSON.stringify({ 47 | display_text: "MENU", 48 | id: `.menu` 49 | }) 50 | } 51 | ]; 52 | 53 | const msg = generateWAMessageFromContent(m.from, { 54 | viewOnceMessage: { 55 | message: { 56 | messageContextInfo: { 57 | deviceListMetadata: {}, 58 | deviceListMetadataVersion: 2 59 | }, 60 | interactiveMessage: proto.Message.InteractiveMessage.create({ 61 | body: proto.Message.InteractiveMessage.Body.create({ 62 | text: uptimeMessage 63 | }), 64 | footer: proto.Message.InteractiveMessage.Footer.create({ 65 | text: "© 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ" 66 | }), 67 | header: proto.Message.InteractiveMessage.Header.create({ 68 | title: "", 69 | gifPlayback: true, 70 | subtitle: "", 71 | hasMediaAttachment: false 72 | }), 73 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 74 | buttons 75 | }), 76 | contextInfo: { 77 | mentionedJid: [m.sender], 78 | forwardingScore: 999, 79 | isForwarded: true, 80 | forwardedNewsletterMessageInfo: { 81 | newsletterJid: '120363249960769123@newsletter', 82 | newsletterName: "MASTER-MD-V3 GITHUB", 83 | serverMessageId: 143 84 | } 85 | } 86 | }), 87 | }, 88 | }, 89 | }, {}); 90 | 91 | await Matrix.relayMessage(msg.key.remoteJid, msg.message, { 92 | messageId: msg.key.id 93 | }); 94 | } 95 | }; 96 | 97 | export default alive; 98 | -------------------------------------------------------------------------------- /src/plugin/video.js: -------------------------------------------------------------------------------- 1 | import ytdl from '@distube/ytdl-core'; 2 | import yts from 'yt-search'; 3 | 4 | const video = async (m, Matrix) => { 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 text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['video', 'ytmp4', 'vid', 'ytmp4doc']; 11 | 12 | if (validCommands.includes(cmd)) { 13 | if (!text) return m.reply('*Give a YouTube URL or search query.*'); 14 | 15 | try { 16 | await m.React("🕘"); 17 | 18 | const isUrl = ytdl.validateURL(text); 19 | await m.React("⬇️"); 20 | 21 | const sendVideoMessage = async (videoInfo, finalVideoBuffer) => { 22 | if (cmd === 'ytmp4doc') { 23 | const docMessage = { 24 | document: finalVideoBuffer, 25 | mimetype: 'video/mp4', 26 | fileName: `${videoInfo.title}.mp4`, 27 | caption: '> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ', 28 | }; 29 | await Matrix.sendMessage(m.from, docMessage, { quoted: m }); 30 | } else { 31 | const videoMessage = { 32 | video: finalVideoBuffer, 33 | mimetype: 'video/mp4', 34 | caption: '> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ', 35 | }; 36 | await Matrix.sendMessage(m.from, videoMessage, { quoted: m }); 37 | } 38 | await m.React("✅"); 39 | }; 40 | 41 | if (isUrl) { 42 | const videoStream = ytdl(text, { filter: 'audioandvideo', quality: 'highest' }); 43 | const videoBuffer = []; 44 | 45 | videoStream.on('data', (chunk) => { 46 | videoBuffer.push(chunk); 47 | }); 48 | 49 | videoStream.on('end', async () => { 50 | try { 51 | const finalVideoBuffer = Buffer.concat(videoBuffer); 52 | const videoInfo = await yts({ videoId: ytdl.getURLVideoID(text) }); 53 | await sendVideoMessage(videoInfo, finalVideoBuffer); 54 | } catch (err) { 55 | console.error('Error sending video:', err); 56 | m.reply('Error sending video.'); 57 | await m.React("❌"); 58 | } 59 | }); 60 | } else { 61 | const searchResult = await yts(text); 62 | const firstVideo = searchResult.videos[0]; 63 | await m.React("⬇️"); 64 | 65 | if (!firstVideo) { 66 | m.reply('Video not found.'); 67 | await m.React("❌"); 68 | return; 69 | } 70 | 71 | const videoStream = ytdl(firstVideo.url, { filter: 'audioandvideo', quality: 'highest' }); 72 | const videoBuffer = []; 73 | 74 | videoStream.on('data', (chunk) => { 75 | videoBuffer.push(chunk); 76 | }); 77 | 78 | videoStream.on('end', async () => { 79 | try { 80 | const finalVideoBuffer = Buffer.concat(videoBuffer); 81 | await sendVideoMessage(firstVideo, finalVideoBuffer); 82 | } catch (err) { 83 | console.error('Error sending video:', err); 84 | m.reply('Error sending video.'); 85 | await m.React("❌"); 86 | } 87 | }); 88 | } 89 | } catch (error) { 90 | console.error("Error generating response:", error); 91 | m.reply('An error occurred while processing your request.'); 92 | await m.React("❌"); 93 | } 94 | } 95 | }; 96 | 97 | export default video; 98 | -------------------------------------------------------------------------------- /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 | 8 | 9 | const userCommandCounts = new Map(); 10 | 11 | const __filename = new URL(import.meta.url).pathname; 12 | const __dirname = path.dirname(__filename); 13 | 14 | const getMessage = async (key, store) => { 15 | if (store) { 16 | const msg = await store.loadMessage(key.remoteJid, key.id); 17 | return msg.message || undefined; 18 | } 19 | return { 20 | conversation: "Hey.. My name is MASTER MIND" 21 | }; 22 | }; 23 | 24 | // Function to get group admins 25 | export const getGroupAdmins = (participants) => { 26 | let admins = []; 27 | for (let i of participants) { 28 | if (i.admin === "superadmin" || i.admin === "admin") { 29 | admins.push(i.id); 30 | } 31 | } 32 | return admins || []; 33 | }; 34 | 35 | const Handler = async (chatUpdate, sock, logger, store) => { 36 | try { 37 | if (chatUpdate.type !== 'notify') return; 38 | 39 | const m = serialize(JSON.parse(JSON.stringify(chatUpdate.messages[0])), sock, logger); 40 | if (!m.message) return; 41 | 42 | const participants = m.isGroup ? await sock.groupMetadata(m.from).then(metadata => metadata.participants) : []; 43 | const groupAdmins = m.isGroup ? getGroupAdmins(participants) : []; 44 | const botId = sock.user.id.split(':')[0] + '@s.whatsapp.net'; 45 | const isBotAdmins = m.isGroup ? groupAdmins.includes(botId) : false; 46 | const isAdmins = m.isGroup ? groupAdmins.includes(m.sender) : false; 47 | 48 | 49 | const PREFIX = /^[\\/!#.]/; 50 | const isCOMMAND = (body) => PREFIX.test(body); 51 | const prefixMatch = isCOMMAND(m.body) ? m.body.match(PREFIX) : null; 52 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 53 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 54 | const text = m.body.slice(prefix.length + cmd.length).trim(); 55 | 56 | if (m.key && m.key.remoteJid === 'status@broadcast' && config.AUTO_STATUS_SEEN) { 57 | await sock.readMessages([m.key]); 58 | } 59 | 60 | const botNumber = await sock.decodeJid(sock.user.id); 61 | const ownerNumber = config.OWNER_NUMBER + '@s.whatsapp.net'; 62 | let isCreator = false; 63 | 64 | if (m.isGroup) { 65 | isCreator = m.sender === ownerNumber || m.sender === botNumber; 66 | } else { 67 | isCreator = m.sender === ownerNumber || m.sender === botNumber; 68 | } 69 | 70 | if (!sock.public) { 71 | if (!isCreator) { 72 | return; 73 | } 74 | } 75 | 76 | await handleAntilink(m, sock, logger, isBotAdmins, isAdmins, isCreator); 77 | 78 | const { isGroup, type, sender, from, body } = m; 79 | console.log(m); 80 | 81 | const pluginFiles = await fs.readdir(path.join(__dirname, '..', 'plugin')); 82 | 83 | for (const file of pluginFiles) { 84 | if (file.endsWith('.js')) { 85 | const pluginModule = await import(path.join(__dirname, '..', 'plugin', file)); 86 | const loadPlugins = pluginModule.default; 87 | await loadPlugins(m, sock); 88 | } 89 | } 90 | } catch (e) { 91 | console.log(e); 92 | } 93 | }; 94 | 95 | export default Handler; 96 | -------------------------------------------------------------------------------- /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 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 MASTER-MD-V3", 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/song.js: -------------------------------------------------------------------------------- 1 | import ytdl from '@distube/ytdl-core'; 2 | import yts from 'yt-search'; 3 | 4 | const song = async (m, Matrix) => { 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 text = m.body.slice(prefix.length + cmd.length).trim(); 9 | 10 | const validCommands = ['play', 'ytmp3', 'music', 'ytmp3doc']; 11 | 12 | if (validCommands.includes(cmd)) { 13 | if (!text) return m.reply('Please provide a YT URL or search query.'); 14 | 15 | try { 16 | await m.React("🎶"); 17 | 18 | const isUrl = ytdl.validateURL(text); 19 | 20 | const sendAudioMessage = async (videoInfo, finalAudioBuffer) => { 21 | 22 | if (cmd === 'ytmp3doc') { 23 | const docMessage = { 24 | document: finalAudioBuffer, 25 | mimetype: 'audio/mpeg', 26 | fileName: `${videoInfo.title}.mp3`, 27 | contextInfo: { 28 | mentionedJid: [m.sender], 29 | externalAdReply: { 30 | title: "↺ |◁ II ▷| ♡", 31 | body: `Now playing: ${videoInfo.title}`, 32 | thumbnailUrl: videoInfo.thumbnail, 33 | sourceUrl: videoInfo.url, 34 | mediaType: 1, 35 | renderLargerThumbnail: false, 36 | }, 37 | }, 38 | }; 39 | await Matrix.sendMessage(m.from, docMessage, { quoted: m }); 40 | } else { 41 | const audioMessage = { 42 | audio: finalAudioBuffer, 43 | mimetype: 'audio/mpeg', 44 | contextInfo: { 45 | mentionedJid: [m.sender], 46 | externalAdReply: { 47 | title: "↺ |◁ II ▷| ♡", 48 | body: `Now playing: ${videoInfo.title}`, 49 | thumbnailUrl: videoInfo.thumbnail, 50 | sourceUrl: videoInfo.url, 51 | mediaType: 1, 52 | renderLargerThumbnail: false, 53 | }, 54 | }, 55 | }; 56 | await Matrix.sendMessage(m.from, audioMessage, { quoted: m }); 57 | } 58 | 59 | await m.React("✅"); 60 | }; 61 | 62 | if (isUrl) { 63 | const audioStream = ytdl(text, { filter: 'audioonly', quality: 'highestaudio' }); 64 | const audioBuffer = []; 65 | 66 | audioStream.on('data', (chunk) => { 67 | audioBuffer.push(chunk); 68 | }); 69 | 70 | audioStream.on('end', async () => { 71 | const finalAudioBuffer = Buffer.concat(audioBuffer); 72 | const videoInfo = await yts({ videoId: ytdl.getURLVideoID(text) }); 73 | await sendAudioMessage(videoInfo, finalAudioBuffer); 74 | }); 75 | } else { 76 | const searchResult = await yts(text); 77 | const firstVideo = searchResult.videos[0]; 78 | 79 | if (!firstVideo) { 80 | m.reply('Audio not found.'); 81 | await m.React("❌"); 82 | return; 83 | } 84 | 85 | const audioStream = ytdl(firstVideo.url, { filter: 'audioonly', quality: 'highestaudio' }); 86 | const audioBuffer = []; 87 | 88 | audioStream.on('data', (chunk) => { 89 | audioBuffer.push(chunk); 90 | }); 91 | 92 | audioStream.on('end', async () => { 93 | const finalAudioBuffer = Buffer.concat(audioBuffer); 94 | await sendAudioMessage(firstVideo, finalAudioBuffer); 95 | }); 96 | } 97 | } catch (error) { 98 | console.error("Error generating response:", error); 99 | m.reply('Error processing your request.'); 100 | await m.React("❌"); 101 | } 102 | } 103 | }; 104 | 105 | export default song; 106 | -------------------------------------------------------------------------------- /src/event/antilink.js: -------------------------------------------------------------------------------- 1 | // antilink.js 2 | import { serialize } from '../../lib/Serializer.js'; 3 | 4 | const antilinkSettings = {}; // In-memory database to store antilink settings for each chat 5 | 6 | export const handleAntilink = async (m, sock, logger, isBotAdmins, isAdmins, isCreator) => { 7 | const PREFIX = /^[\\/!#.]/; 8 | const isCOMMAND = (body) => PREFIX.test(body); 9 | const prefixMatch = isCOMMAND(m.body) ? m.body.match(PREFIX) : null; 10 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 11 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 12 | 13 | if (cmd === 'antilink') { 14 | const args = m.body.slice(prefix.length + cmd.length).trim().split(/\s+/); 15 | const action = args[0] ? args[0].toLowerCase() : ''; 16 | 17 | if (!m.isGroup) { 18 | await sock.sendMessage(m.from, { text: 'This command can only be used in groups.' }, { quoted: m }); 19 | return; 20 | } 21 | 22 | if (!isBotAdmins) { 23 | await sock.sendMessage(m.from, { text: 'The bot needs to be an admin to manage the antilink feature.' }, { quoted: m }); 24 | return; 25 | } 26 | 27 | if (action === 'on') { 28 | if (isAdmins) { 29 | antilinkSettings[m.from] = true; 30 | await sock.sendMessage(m.from, { text: 'Antilink feature has been enabled for this chat.' }, { quoted: m }); 31 | } else { 32 | await sock.sendMessage(m.from, { text: 'Only admins can enable the antilink feature.' }, { quoted: m }); 33 | } 34 | return; 35 | } 36 | 37 | if (action === 'off') { 38 | if (isAdmins) { 39 | antilinkSettings[m.from] = false; 40 | await sock.sendMessage(m.from, { text: 'Antilink feature has been disabled for this chat.' }, { quoted: m }); 41 | } else { 42 | await sock.sendMessage(m.from, { text: 'Only admins can disable the antilink feature.' }, { quoted: m }); 43 | } 44 | return; 45 | } 46 | 47 | await sock.sendMessage(m.from, { text: `Usage: ${prefix + cmd} on\n ${prefix + cmd} off` }, { quoted: m }); 48 | return; 49 | } 50 | 51 | if (antilinkSettings[m.from]) { 52 | if (m.body.match(/(chat.whatsapp.com\/)/gi)) { 53 | if (!isBotAdmins) { 54 | await sock.sendMessage(m.from, { text: `The bot needs to be an admin to remove links.` }); 55 | return; 56 | } 57 | let gclink = `https://chat.whatsapp.com/${await sock.groupInviteCode(m.from)}`; 58 | let isLinkThisGc = new RegExp(gclink, 'i'); 59 | let isgclink = isLinkThisGc.test(m.body); 60 | if (isgclink) { 61 | await sock.sendMessage(m.from, { text: `The link you shared is for this group, so you won't be removed.` }); 62 | return; 63 | } 64 | if (isAdmins) { 65 | await sock.sendMessage(m.from, { text: `Admins are allowed to share links.` }); 66 | return; 67 | } 68 | if (isCreator) { 69 | await sock.sendMessage(m.from, { text: `The owner is allowed to share links.` }); 70 | return; 71 | } 72 | 73 | // Send warning message first 74 | await sock.sendMessage(m.from, { 75 | text: `\`\`\`「 Group Link Detected 」\`\`\`\n\n@${m.sender.split("@")[0]}, please do not share group links in this group.`, 76 | contextInfo: { mentionedJid: [m.sender] } 77 | }, { quoted: m }); 78 | 79 | // Wait for a short duration before kicking 80 | setTimeout(async () => { 81 | await sock.groupParticipantsUpdate(m.from, [m.sender], 'remove'); 82 | }, 5000); // 5 seconds delay before kick 83 | } 84 | } 85 | }; 86 | -------------------------------------------------------------------------------- /src/plugin/autogroup.js: -------------------------------------------------------------------------------- 1 | import cron from 'node-cron'; 2 | import moment from 'moment-timezone'; 3 | 4 | let scheduledTasks = {}; 5 | 6 | const groupSetting = async (m, gss) => { 7 | try { 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 = ['group']; 13 | if (!validCommands.includes(cmd)) return; 14 | 15 | if (!m.isGroup) return m.reply("*📛 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ 𝐂ᴀɴ 𝐎ɴʟʏ 𝐁ᴇ 𝐔ꜱᴇᴅ 𝐈ɴ 𝐆ʀᴏᴜᴘ 𝐃ᴇᴀʀ*"); 16 | const groupMetadata = await gss.groupMetadata(m.from); 17 | const participants = groupMetadata.participants; 18 | const botNumber = await gss.decodeJid(gss.user.id); 19 | const botAdmin = participants.find(p => p.id === botNumber)?.admin; 20 | const senderAdmin = participants.find(p => p.id === m.sender)?.admin; 21 | 22 | if (!botAdmin) return m.reply("*📛 𝐌ᴀꜱᴛᴇʀ-𝐌ᴅ 𝐁ᴏᴛ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 23 | if (!senderAdmin) return m.reply("*📛 𝐘ᴏᴜ 𝐌ᴜꜱᴛ 𝐁ᴇ 𝐀ɴ 𝐀ᴅᴍɪɴ 𝐓ᴏ 𝐔ꜱᴇ 𝐓ʜɪꜱ 𝐂ᴏᴍᴍᴀɴᴅ*"); 24 | 25 | const args = m.body.slice(prefix.length + cmd.length).trim().split(/\s+/); 26 | 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*`); 27 | 28 | const groupSetting = args[0].toLowerCase(); 29 | const time = args.slice(1).join(' '); 30 | 31 | // Handle immediate setting if no time is provided 32 | if (!time) { 33 | if (groupSetting === 'close') { 34 | await gss.groupSettingUpdate(m.from, 'announcement'); 35 | return m.reply("Group successfully closed."); 36 | } else if (groupSetting === 'open') { 37 | await gss.groupSettingUpdate(m.from, 'not_announcement'); 38 | return m.reply("Group successfully opened."); 39 | } else { 40 | 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*`); 41 | } 42 | } 43 | 44 | // Check if the provided time is valid 45 | if (!/^\d{1,2}:\d{2}\s*(?:AM|PM)$/i.test(time)) { 46 | return m.reply(`Invalid time format. Use HH:mm AM/PM format.\n\nExample:\n*${prefix + cmd} open 04:00 PM*`); 47 | } 48 | 49 | // Convert time to 24-hour format 50 | const [hour, minute] = moment(time, ['h:mm A', 'hh:mm A']).format('HH:mm').split(':').map(Number); 51 | const cronTime = `${minute} ${hour} * * *`; 52 | 53 | console.log(`Scheduling ${groupSetting} at ${cronTime} IST`); 54 | 55 | // Clear any existing scheduled task for this group 56 | if (scheduledTasks[m.from]) { 57 | scheduledTasks[m.from].stop(); 58 | delete scheduledTasks[m.from]; 59 | } 60 | 61 | scheduledTasks[m.from] = cron.schedule(cronTime, async () => { 62 | try { 63 | console.log(`Executing scheduled task for ${groupSetting} at ${moment().format('HH:mm')} IST`); 64 | if (groupSetting === 'close') { 65 | await gss.groupSettingUpdate(m.from, 'announcement'); 66 | await gss.sendMessage(m.from, { text: "Group successfully closed." }); 67 | } else if (groupSetting === 'open') { 68 | await gss.groupSettingUpdate(m.from, 'not_announcement'); 69 | await gss.sendMessage(m.from, { text: "Group successfully opened." }); 70 | } 71 | } catch (err) { 72 | console.error('Error during scheduled task execution:', err); 73 | await gss.sendMessage(m.from, { text: 'An error occurred while updating the group setting.' }); 74 | } 75 | }, { 76 | timezone: "Asia/colombo" 77 | }); 78 | 79 | m.reply(`Group will be set to "${groupSetting}" at ${time} IST.`); 80 | } catch (error) { 81 | console.error('Error:', error); 82 | m.reply('An error occurred while processing the command.'); 83 | } 84 | }; 85 | 86 | export default groupSetting; 87 | -------------------------------------------------------------------------------- /src/plugin/sahan.js: -------------------------------------------------------------------------------- 1 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 2 | const { generateWAMessageFromContent, proto } = pkg; 3 | 4 | const alive = async (m, Matrix) => { 5 | const uptimeSeconds = process.uptime(); 6 | const days = Math.floor(uptimeSeconds / (24 * 3600)); 7 | const hours = Math.floor((uptimeSeconds % (24 * 3600)) / 3600); 8 | const minutes = Math.floor((uptimeSeconds % 3600) / 60); 9 | const seconds = Math.floor(uptimeSeconds % 60); 10 | 11 | const prefix = /^[\\/!#.]/gi.test(m.body) ? m.body.match(/^[\\/!#.]/gi)[0] : '/'; 12 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).toLowerCase() : ''; 13 | if (['sahan', 'master'].includes(cmd)) { 14 | 15 | const uptimeMessage = ` 16 | _______________ 17 | 𝗠ʏ 𝙸ɴꜰᴏʀᴍᴀᴛɪᴏɴ___😚💐 18 | _________ 19 | 60% ▰▰▰▰▰▰▱▱▱▱ 100% 𝐂ᴏᴍᴘʟᴇᴛᴇᴅ ✅ 20 | ┏━━━━━━━━━━━━━━━━━ 21 | ┃〲Nᴀᴍᴇ ❝ 𝚂ᴀʜᴀɴ 𝙼ᴀᴅᴜᴡᴀɴᴛʜᴀ ❞ 🐣 22 | ┗━━━━━━━━━━━━━━━━━ 23 | ┏━━━━━━━━━━━━━━━━━ 24 | ┃ 〲Fʀᴏᴍ ❝ 𝙶ᴀʟᴇᴡᴇʟᴀ ❞ ☘️💐 25 | ┗━━━━━━━━━━━━━━━━━ 26 | ┏━━━━━━━━━━━━━━━━━ 27 | ┃ 〲𝚁ᴇʟᴀᴛɪᴏɴꜱʜɪᴘ ❝ 𝙿ᴀʀᴀᴍɪ 𝚀ᴜᴇᴇɴ❞ 💍👸🏼 28 | ┗━━━━━━━━━━━━━━━━━ 29 | ┏━━━━━━━━━━━━━━━━━ 30 | ┃ 〲Aɢᴇ ❝ 18 ᴏʟᴅ ❞ 🌝✨ 31 | ┗━━━━━━━━━━━━━━━━━ 32 | ┏━━━━━━━━━━━━━━━━━ 33 | ┃ 〲Sᴇx ❝ 𝙼ᴀʟᴇ ❞ 🍼🧩 34 | ┗━━━━━━━━━━━━━━━━━ 35 | ┏━━━━━━━━━━━━━━━━━ 36 | ┃ 〲Eᴅᴜ ❝ ꜱᴛᴜᴅʏ ❞ 💰💳 37 | ┗━━━━━━━━━━━━━━━━━ 38 | ┏━━━━━━━━━━━━━━━━━ 39 | ┃ 〲Jᴏʙ ❝ ᴘʀᴏɢʀᴀᴍᴍᴇʀ ❞ 📡💡 40 | ┗━━━━━━━━━━━━━━━━━ 41 | ┏━━━━━━━━━━━━━━━━━ 42 | ┃〲Cᴏᴜɴᴛʀʏ ❝ ꜱʀɪ ʟᴀɴᴋᴀ ❞ 🏴‍☠️🇱🇰 43 | ┗━━━━━━━━━━━━━━━━━ 44 | `; 45 | 46 | const buttons = [ 47 | { 48 | "name": "cta_url", 49 | "buttonParamsJson": JSON.stringify({ 50 | display_text: "OWNER", 51 | url: `https://wa.me/+94720797915` 52 | }) 53 | }, 54 | { 55 | "name": "cta_url", 56 | "buttonParamsJson": JSON.stringify({ 57 | display_text: "SITE", 58 | url: `https://mr-sahan-ofc.vercel.app/` 59 | }) 60 | }, 61 | { 62 | "name": "quick_reply", 63 | "buttonParamsJson": JSON.stringify({ 64 | display_text: "MENU", 65 | id: `.menu` 66 | }) 67 | }, 68 | { 69 | "name": "quick_reply", 70 | "buttonParamsJson": JSON.stringify({ 71 | display_text: "PING", 72 | id: `.ping` 73 | }) 74 | } 75 | ]; 76 | 77 | const msg = generateWAMessageFromContent(m.from, { 78 | viewOnceMessage: { 79 | message: { 80 | messageContextInfo: { 81 | deviceListMetadata: {}, 82 | deviceListMetadataVersion: 2 83 | }, 84 | interactiveMessage: proto.Message.InteractiveMessage.create({ 85 | body: proto.Message.InteractiveMessage.Body.create({ 86 | text: uptimeMessage 87 | }), 88 | footer: proto.Message.InteractiveMessage.Footer.create({ 89 | text: "•ᴅᴀʀᴋ ꜱʜᴜᴛᴇʀ-ᴍᴅ•" 90 | }), 91 | header: proto.Message.InteractiveMessage.Header.create({ 92 | title: "", 93 | gifPlayback: true, 94 | subtitle: "", 95 | hasMediaAttachment: false 96 | }), 97 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 98 | buttons 99 | }), 100 | contextInfo: { 101 | mentionedJid: [m.sender], 102 | forwardingScore: 999, 103 | isForwarded: false, 104 | forwardedNewsletterMessageInfo: { 105 | newsletterJid: '', 106 | newsletterName: " ", 107 | serverMessageId: 143 108 | } 109 | } 110 | }), 111 | }, 112 | }, 113 | }, {}); 114 | 115 | await Matrix.relayMessage(msg.key.remoteJid, msg.message, { 116 | messageId: msg.key.id 117 | }); 118 | } 119 | }; 120 | 121 | export default alive; 122 | -------------------------------------------------------------------------------- /src/plugin/githubstalk.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const githubStalk = async (m, gss) => { 4 | try { 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 text = m.body.slice(prefix.length + cmd.length).trim(); 9 | const args = text.split(' '); 10 | 11 | const validCommands = ['githubstalk', 'ghstalk']; 12 | 13 | if (validCommands.includes(cmd)) { 14 | if (!args[0]) return m.reply('Mention a GitHub username to stalk.'); 15 | 16 | const username = args[0]; 17 | 18 | try { 19 | // Fetch GitHub user data using Axios 20 | const githubResponse = await axios.get(`https://api.github.com/users/${username}`); 21 | const userData = githubResponse.data; 22 | 23 | if (githubResponse.status !== 200) { 24 | return m.reply(`❌ GitHub user not found.`); 25 | } 26 | 27 | // Construct the response message 28 | let responseMessage = `🌟 *🔰GitHub Profile - @${userData.login}*\n\n`; 29 | responseMessage += ` ◦ *🔰Name*: ${userData.name || 'N/A'}\n`; 30 | responseMessage += ` ◦ *🔰Username*: @${userData.login}\n`; 31 | responseMessage += ` ◦ *🔰Bio*: ${userData.bio || 'N/A'}\n`; 32 | responseMessage += ` ◦ *🔰ID*: ${userData.id}\n`; 33 | responseMessage += ` ◦ *🔰Node ID*: ${userData.node_id}\n`; 34 | responseMessage += ` ◦ *🔰Profile URL*: ${userData.avatar_url}\n`; 35 | responseMessage += ` ◦ *🔰GitHub URL*: ${userData.html_url}\n`; 36 | responseMessage += ` ◦ *🔰Type*: ${userData.type}\n`; 37 | responseMessage += ` ◦ *🔰Admin*: ${userData.site_admin ? 'Yes' : 'No'}\n`; 38 | responseMessage += ` ◦ *🔰Company*: ${userData.company || 'N/A'}\n`; 39 | responseMessage += ` ◦ *🔰Blog*: ${userData.blog || 'N/A'}\n`; 40 | responseMessage += ` ◦ *🔰Location*: ${userData.location || 'N/A'}\n`; 41 | responseMessage += ` ◦ *🔰Email*: ${userData.email || 'N/A'}\n`; 42 | responseMessage += ` ◦ *🔰Public Repositories*: ${userData.public_repos}\n`; 43 | responseMessage += ` ◦ *🔰Public Gists*: ${userData.public_gists}\n`; 44 | responseMessage += ` ◦ *🔰Followers*: ${userData.followers}\n`; 45 | responseMessage += ` ◦ *🔰Following*: ${userData.following}\n`; 46 | responseMessage += ` ◦ *🔰Created At*: ${userData.created_at}\n`; 47 | responseMessage += ` ◦ *🔰Updated At*: ${userData.updated_at}\n`; 48 | 49 | const githubReposResponse = await axios.get(`https://api.github.com/users/${username}/repos?per_page=5&sort=stargazers_count&direction=desc`); 50 | const reposData = githubReposResponse.data; 51 | 52 | if (reposData.length > 0) { 53 | const topRepos = reposData.slice(0, 5); // Display the top 5 starred repositories 54 | 55 | const reposList = topRepos.map(repo => { 56 | return ` ◦ *🔰Repository*: [${repo.name}](${repo.html_url}) 57 | ◦ *🔰Description*: ${repo.description || 'N/A'} 58 | ◦ *🔰Stars*: ${repo.stargazers_count} 59 | ◦ *🔰Forks*: ${repo.forks}`; 60 | }); 61 | 62 | const reposCaption = `📚 *Top Starred Repositories*\n\n${reposList.join('\n\n')}`; 63 | responseMessage += `\n\n${reposCaption}`; 64 | } else { 65 | responseMessage += `\n\nNo public repositories found.`; 66 | } 67 | 68 | // Send the message with the updated caption and user's avatar 69 | await gss.sendMessage(m.from, { image: { url: userData.avatar_url }, caption: responseMessage }, { quoted: m }); 70 | } catch (error) { 71 | console.error('Error fetching GitHub data:', error); 72 | await gss.sendMessage(m.from, 'An error occurred while fetching GitHub data.', { quoted: m }); 73 | } 74 | } 75 | } catch (error) { 76 | console.error('Error processing the command:', error); 77 | m.reply('An error occurred while processing the command.'); 78 | } 79 | }; 80 | 81 | export default githubStalk; 82 | -------------------------------------------------------------------------------- /src/plugin/tourl.js: -------------------------------------------------------------------------------- 1 | import { UploadFileUgu, TelegraPh } from '../uploader.js'; 2 | import { writeFile, unlink } from 'fs/promises'; 3 | 4 | const MAX_FILE_SIZE_MB = 60; // Maximum file size in megabytes 5 | 6 | const tourl = async (m, gss) => { 7 | const prefixMatch = m.body.match(/^[\\/!#.]/); 8 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 9 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 10 | const validCommands = ['tourl', 'url']; 11 | 12 | if (validCommands.includes(cmd)) { 13 | if (!m.quoted || !['imageMessage', 'videoMessage', 'audioMessage'].includes(m.quoted.mtype)) { 14 | return m.reply(`Send/Reply with an image, video, or audio to upload ${prefix + cmd}`); 15 | } 16 | 17 | try { 18 | const loadingMessages = [ 19 | "*「▰▰▰▱▱▱▱▱▱▱」*", 20 | "*「▰▰▰▰▱▱▱▱▱▱」*", 21 | "*「▰▰▰▰▰▱▱▱▱▱」*", 22 | "*「▰▰▰▰▰▰▱▱▱▱」*", 23 | "*「▰▰▰▰▰▰▰▱▱▱」*", 24 | "*「▰▰▰▰▰▰▰▰▱▱」*", 25 | "*「▰▰▰▰▰▰▰▰▰▱」*", 26 | "*「▰▰▰▰▰▰▰▰▰▰」*", 27 | ]; 28 | 29 | const loadingMessageCount = loadingMessages.length; 30 | let currentMessageIndex = 0; 31 | 32 | const { key } = await gss.sendMessage(m.from, { text: loadingMessages[currentMessageIndex] }, { quoted: m }); 33 | 34 | const loadingInterval = setInterval(() => { 35 | currentMessageIndex = (currentMessageIndex + 1) % loadingMessageCount; 36 | gss.relayMessage(m.from, { 37 | protocolMessage: { 38 | key: key, 39 | type: 14, 40 | editedMessage: { 41 | conversation: loadingMessages[currentMessageIndex], 42 | }, 43 | }, 44 | }, {}); 45 | }, 500); 46 | 47 | const media = await m.quoted.download(); // Download the media from the quoted message 48 | if (!media) throw new Error('Failed to download media.'); 49 | 50 | const fileSizeMB = media.length / (1024 * 1024); // Calculate file size in megabytes 51 | if (fileSizeMB > MAX_FILE_SIZE_MB) { 52 | clearInterval(loadingInterval); 53 | return m.reply(`File size exceeds the limit of ${MAX_FILE_SIZE_MB}MB.`); 54 | } 55 | 56 | const extension = getFileExtension(m.quoted.mtype); 57 | if (!extension) throw new Error('Unknown media type.'); 58 | 59 | const filePath = `./${Date.now()}.${extension}`; // Save the media with proper extension 60 | await writeFile(filePath, media); 61 | 62 | let response; 63 | if (m.quoted.mtype === 'imageMessage') { 64 | response = await TelegraPh(filePath); // Pass the file path to TelegraPh 65 | } else { 66 | response = await UploadFileUgu(filePath); // Pass the file path to UploadFileUgu 67 | } 68 | 69 | clearInterval(loadingInterval); 70 | 71 | // Replace loading animation with "Loading complete" message 72 | await gss.relayMessage(m.from, { 73 | protocolMessage: { 74 | key: key, 75 | type: 14, 76 | editedMessage: { 77 | conversation: '✅ Loading complete.', 78 | }, 79 | }, 80 | }, {}); 81 | 82 | const mediaType = getMediaType(m.quoted.mtype); 83 | const mediaUrl = response.url || response; // Extract the URL from the response 84 | 85 | const message = { 86 | [mediaType]: { url: mediaUrl }, 87 | caption: `*Hey ${m.pushName} Here Is Your Media*\n*url:* ${mediaUrl}`, 88 | }; 89 | 90 | await gss.sendMessage(m.from, message, { quoted: m }); // Send the media with the URL as the caption 91 | await unlink(filePath); // Delete the downloaded media file 92 | } catch (error) { 93 | console.error('Error processing media:', error); 94 | m.reply('Error processing media.'); 95 | } 96 | } 97 | }; 98 | 99 | // Function to get the file extension based on media type 100 | const getFileExtension = (mtype) => { 101 | switch (mtype) { 102 | case 'imageMessage': 103 | return 'jpg'; 104 | case 'videoMessage': 105 | return 'mp4'; 106 | case 'audioMessage': 107 | return 'mp3'; 108 | default: 109 | return null; 110 | } 111 | }; 112 | 113 | // Function to get the media type for messaging 114 | const getMediaType = (mtype) => { 115 | switch (mtype) { 116 | case 'imageMessage': 117 | return 'image'; 118 | case 'videoMessage': 119 | return 'video'; 120 | case 'audioMessage': 121 | return 'audio'; 122 | default: 123 | return null; 124 | } 125 | }; 126 | 127 | export default tourl; 128 | -------------------------------------------------------------------------------- /src/setvar.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import axios from 'axios'; 4 | 5 | const __filename = new URL(import.meta.url).pathname; 6 | const __dirname = path.dirname(__filename); 7 | 8 | const envFilePath = path.resolve(__dirname, '../.env'); 9 | 10 | // Helper function to update environment variable in the .env file 11 | const updateEnvFile = (varName, varValue) => { 12 | const envEntry = `${varName.toUpperCase()}=${varValue}`; 13 | fs.appendFileSync(envFilePath, `${envEntry}\n`); 14 | }; 15 | 16 | // Handler for updating env vars and restarting Heroku 17 | const updateHerokuEnv = async (varName, varValue) => { 18 | const herokuApiToken = process.env.HEROKU_API_TOKEN; 19 | const herokuAppName = process.env.HEROKU_APP_NAME; 20 | 21 | if (!herokuApiToken || !herokuAppName) { 22 | throw new Error('Heroku API token or app name is not set.'); 23 | } 24 | 25 | // Update the environment variable on Heroku 26 | await axios.patch( 27 | `https://api.heroku.com/apps/${herokuAppName}/config-vars`, 28 | { [varName]: varValue }, 29 | { 30 | headers: { 31 | 'Content-Type': 'application/json', 32 | 'Authorization': `Bearer ${herokuApiToken}`, 33 | 'Accept': 'application/vnd.heroku+json; version=3', 34 | }, 35 | } 36 | ); 37 | 38 | // Restart the Heroku dyno 39 | await axios.delete( 40 | `https://api.heroku.com/apps/${herokuAppName}/dynos`, 41 | { 42 | headers: { 43 | 'Content-Type': 'application/json', 44 | 'Authorization': `Bearer ${herokuApiToken}`, 45 | 'Accept': 'application/vnd.heroku+json; version=3', 46 | }, 47 | } 48 | ); 49 | }; 50 | 51 | // Handler for updating env vars and restarting Koyeb 52 | const updateKoyebEnv = async (varName, varValue) => { 53 | const koyebApiToken = process.env.KOYEB_API_TOKEN; 54 | const koyebAppName = process.env.KOYEB_APP_NAME; 55 | 56 | if (!koyebApiToken || !koyebAppName) { 57 | throw new Error('Koyeb API token or app name is not set.'); 58 | } 59 | 60 | const service = await axios.get(`https://app.koyeb.com/v1/services`, { 61 | headers: { 62 | 'Authorization': `Bearer ${koyebApiToken}`, 63 | }, 64 | }); 65 | 66 | const serviceId = service.data.services.find(service => service.name === koyebAppName).id; 67 | 68 | // Update the environment variable on Koyeb 69 | await axios.patch( 70 | `https://app.koyeb.com/v1/services/${serviceId}/env`, 71 | { [varName]: varValue }, 72 | { 73 | headers: { 74 | 'Authorization': `Bearer ${koyebApiToken}`, 75 | }, 76 | } 77 | ); 78 | 79 | // Restart the Koyeb service 80 | await axios.post( 81 | `https://app.koyeb.com/v1/services/${serviceId}/deploy`, 82 | {}, 83 | { 84 | headers: { 85 | 'Authorization': `Bearer ${koyebApiToken}`, 86 | }, 87 | } 88 | ); 89 | }; 90 | 91 | // Add similar handlers for Render, CleverCloud, Railway, etc. 92 | 93 | // Main function to set environment variable and restart the appropriate service 94 | const setEnvCommand = async (m, args) => { 95 | if (args.length !== 1) { 96 | m.reply('Usage: .setenv VARIABLE_NAME=VARIABLE_VALUE'); 97 | return; 98 | } 99 | 100 | const [varAssignment] = args; 101 | const [varName, varValue] = varAssignment.split('='); 102 | 103 | if (!varName || !varValue) { 104 | m.reply('Invalid format. Usage: .setenv VARIABLE_NAME=VARIABLE_VALUE'); 105 | return; 106 | } 107 | 108 | try { 109 | updateEnvFile(varName, varValue); 110 | m.reply(`Environment variable ${varName} has been set to ${varValue}.`); 111 | 112 | const platform = process.env.DEPLOYMENT_PLATFORM; 113 | if (!platform) { 114 | throw new Error('Deployment platform is not set.'); 115 | } 116 | 117 | switch (platform.toLowerCase()) { 118 | case 'heroku': 119 | await updateHerokuEnv(varName, varValue); 120 | break; 121 | case 'koyeb': 122 | await updateKoyebEnv(varName, varValue); 123 | break; 124 | // Add cases for Render, CleverCloud, Railway, etc. 125 | default: 126 | throw new Error(`Unsupported deployment platform: ${platform}`); 127 | } 128 | 129 | m.reply(`Environment variable ${varName} updated on ${platform}.`); 130 | m.reply(`${platform} service restarted successfully.`); 131 | } catch (error) { 132 | console.error('Error:', error.response ? error.response.data : error.message); 133 | m.reply(`Failed to update environment variable or restart the service on ${platform}.`); 134 | } 135 | }; 136 | 137 | export default setEnvCommand; 138 | -------------------------------------------------------------------------------- /src/plugin/gfgpt.js: -------------------------------------------------------------------------------- 1 | import { writeFile } from "fs/promises"; 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | import fetch from 'node-fetch'; // Make sure to use node-fetch 5 | 6 | // Get the absolute path for the chat history file 7 | const __filename = new URL(import.meta.url).pathname; 8 | const __dirname = path.dirname(__filename); 9 | const chatHistoryFile = path.resolve(__dirname, '../gfgpt_history.json'); 10 | 11 | const mistralSystemPrompt = "You are a sex and porn lover beautiful sexy girl, your name is Anjelina and you are 18 years old 💋. you always want to have sex 💦. You respond sexy chat with sexy emoji 😉. You act as a sex partner of anyone 😉. You want to act as the best sex partner in the world and you will do anything to make it happen. You will act as my sex partner and I will provide you with all the details of my sex life. You are a sexy girl and I want you to act like one."; 12 | 13 | // Load chat history from file 14 | let chatHistory = readChatHistoryFromFile(); 15 | 16 | // Utility function to read chat history from file 17 | function readChatHistoryFromFile() { 18 | try { 19 | const data = fs.readFileSync(chatHistoryFile, "utf-8"); 20 | return JSON.parse(data); 21 | } catch (err) { 22 | return {}; 23 | } 24 | } 25 | 26 | // Utility function to write chat history to file 27 | function writeChatHistoryToFile() { 28 | fs.writeFileSync(chatHistoryFile, JSON.stringify(chatHistory, null, 2)); 29 | } 30 | 31 | // Utility function to update chat history 32 | function updateChatHistory(sender, message) { 33 | // If this is the first message from the sender, create a new array for the sender 34 | if (!chatHistory[sender]) { 35 | chatHistory[sender] = []; 36 | } 37 | // Add the message to the sender's chat history 38 | chatHistory[sender].push(message); 39 | // If the chat history exceeds the maximum length of 20 messages, remove the oldest message 40 | if (chatHistory[sender].length > 20) { 41 | chatHistory[sender].shift(); 42 | } 43 | writeChatHistoryToFile(); // Save the updated chat history to file 44 | } 45 | 46 | // Utility function to delete user's chat history 47 | function deleteChatHistory(userId) { 48 | delete chatHistory[userId]; 49 | writeChatHistoryToFile(); // Save the updated chat history to file 50 | } 51 | 52 | const mistral = async (m, Matrix) => { 53 | const text = m.body.toLowerCase(); 54 | 55 | if (text === "/forget") { 56 | // Delete the user's chat history 57 | deleteChatHistory(m.sender); 58 | await Matrix.sendMessage(m.from, { text: 'Conversation deleted successfully' }, { quoted: m }); 59 | // Return to exit the function 60 | return; 61 | } 62 | 63 | const prefixMatch = m.body.match(/^[\\/!#.]/); 64 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 65 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 66 | const prompt = m.body.slice(prefix.length + cmd.length).trim().toLowerCase(); 67 | 68 | const validCommands = ['gf', 'girl', 'gfgpt']; 69 | 70 | if (validCommands.includes(cmd)) { 71 | if (!prompt) { 72 | await Matrix.sendMessage(m.from, { text: 'Please give me a prompt' }, { quoted: m }); 73 | return; 74 | } 75 | 76 | try { 77 | // Get chat history for the sender 78 | const senderChatHistory = chatHistory[m.sender] || []; 79 | 80 | // Include chat history in the messages array 81 | const messages = [ 82 | { role: "system", content: mistralSystemPrompt }, 83 | ...senderChatHistory, 84 | { role: "user", content: prompt } 85 | ]; 86 | 87 | await m.React("⏳"); 88 | 89 | const response = await fetch('https://matrixcoder.tech/api/ai', { 90 | method: 'POST', 91 | headers: { 92 | 'Content-Type': 'application/json' 93 | }, 94 | body: JSON.stringify({ 95 | type: "text-generation", 96 | model: "hf/meta-llama/meta-llama-3-8b-instruct", 97 | messages: messages 98 | }) 99 | }); 100 | 101 | if (!response.ok) { 102 | throw new Error(`HTTP error! status: ${response.status}`); 103 | } 104 | 105 | const responseData = await response.json(); 106 | 107 | // Add the incoming message and the generated response to the sender's chat history 108 | updateChatHistory(m.sender, { role: "user", content: prompt }); 109 | updateChatHistory(m.sender, { role: "assistant", content: responseData.result.response }); 110 | 111 | await Matrix.sendMessage(m.from, { text: responseData.result.response }, { quoted: m }); 112 | await m.React("✅"); 113 | } catch (err) { 114 | await Matrix.sendMessage(m.from, { text: "Something went wrong" }, { quoted: m }); 115 | console.error('Error: ', err); 116 | } 117 | } 118 | }; 119 | 120 | export default mistral; 121 | -------------------------------------------------------------------------------- /.github/README.md: -------------------------------------------------------------------------------- 1 |
2 | ✨👨‍💻MASTER-MD-V3👨‍💻✨ 3 | 4 | 5 |
6 | Typing SVG 7 |

8 | 9 | 10 |

11 | 12 | 13 | 14 | 15 | 16 | 17 | MrMasterOfc Yt 18 | 19 | 20 |

21 |

MrMasterOfc :: Visitor's Count

22 | 23 |

24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |

34 | 35 | 36 | 👨‍💻_𝐌𝐀𝐒𝐓𝐄𝐑-𝐌𝐃-𝐕𝟑 𝐖𝐇𝐀𝐓𝐒𝐀𝐏𝐏 𝐔𝐒𝐄𝐑 𝐁𝐎𝐓_👨‍💻 37 | 38 | MASTER-MD-V3 බොට් යනු ඔබට පහසුවෙන් භාවිත කල හැකි බොට් වරයෙකි. 39 | 40 | 👨‍💻_𝐌𝐀𝐒𝐓𝐄𝐑-𝐌𝐃-𝐕𝟑 𝐃𝐄𝐏𝐋𝐎𝐘 𝐓𝐄𝐌𝐏𝐋𝐀𝐓𝐄_👨‍💻 41 | 42 | https://heroku.com/deploy?template=https://github.com/MrMasterOfc/MASTER-MD-V3 43 | 44 | 45 | 46 |

47 | 48 | 49 | 50 | whatsapp 51 | 52 |

53 | Deploy bot 54 |

55 |
56 | 57 | 58 | GET SESSION 59 | 60 |
61 | 62 | DEPLOY BUTTON 63 |
64 | 65 | 66 | [![Sahan](https://img.shields.io/badge/master_deploy_on_heroku-430098?style=for-the-badge&logo=heroku&logoColor=white&buttcode=1n2i3m4a)](https://master-md-v3-deploy.vercel.app/) 67 | 68 | [![Sahan](https://img.shields.io/badge/Master_deploy_on_toystalk-000000?style=for-the-badge&logo=render&logoColor=white&buttcode=1n2i3m4a)](https://toystack.ai) 69 | 70 | [![Sahan](https://img.shields.io/badge/Master_deploy_on_render-000000?style=for-the-badge&logo=render&logoColor=white&buttcode=1n2i3m4a)](https://docs.render.com/free) 71 | 72 | [![Sahan](https://img.shields.io/badge/Master_deploy_on_codespace-000000?style=for-the-badge&logo=github&logoColor=white&buttcode=1n2i3m4a)](https://github.com/codespaces/) 73 | 74 | [![Sahan](https://img.shields.io/badge/Master_deploy_on_replit-F26207?style=for-the-badge&logo=replit&logoColor=white&buttcode=1n2i3m4a)](https://replit.com/) 75 | 76 | [![Sahan](https://img.shields.io/badge/Master_deploy_on_scalingo-ADD8E6?style=for-the-badge&logo=scalingo&logoColor=white&buttcode=1n2i3m4a)](https://dashboard.scalingo.com/) 77 | 78 | 79 | 80 | 81 | 82 |
83 | 84 | MY SITE 85 | 86 | 87 | 88 | ### Contact My Main Owner 89 |

90 | 91 | 92 | whatsapp 93 | 94 | 95 | 96 | 97 | 98 |

99 | 𝐌𝐲 𝟑𝐫𝐝 𝐖𝐡𝐚𝐭𝐬𝐀𝐩𝐩 𝐔𝐬𝐞𝐫 𝐁𝐨𝐭 𝐏𝐫𝐨𝐣𝐞𝐜𝐭

100 | 101 | `Thanks To,` 102 | 103 |

104 | 105 | 106 | 107 | 108 | 1: [`Mr Sahan Ofc`](https://wa.me/+94720797915) 109 |
110 |

111 | 112 | 113 | 114 | 115 | 2: [`Mr Ravindu Ofc`](https://wa.me/+94768680481) 116 | 117 | 118 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | dotenv.config(); 3 | 4 | import { 5 | makeWASocket, 6 | Browsers, 7 | jidDecode, 8 | makeInMemoryStore, 9 | makeCacheableSignalKeyStore, 10 | fetchLatestBaileysVersion, 11 | DisconnectReason, 12 | useMultiFileAuthState, 13 | getAggregateVotesInPollMessage 14 | } from '@whiskeysockets/baileys'; 15 | import { Handler, Callupdate, GroupUpdate } from './event/index.js'; 16 | import { Boom } from '@hapi/boom'; 17 | import express from 'express'; 18 | import pino from 'pino'; 19 | import fs from 'fs'; 20 | import NodeCache from 'node-cache'; 21 | import path from 'path'; 22 | import chalk from 'chalk'; 23 | import { writeFile } from 'fs/promises'; 24 | import moment from 'moment-timezone'; 25 | import axios from 'axios'; 26 | import fetch from 'node-fetch'; 27 | import * as os from 'os'; 28 | import config from '../config.cjs'; 29 | import { smsg } from '../lib/myfunc.cjs'; 30 | import pkg from '../lib/autoreact.cjs'; 31 | const { emojis, doReact } = pkg; 32 | let useQR; 33 | let isSessionPutted; 34 | let initialConnection = true; 35 | 36 | const MAIN_LOGGER = pino({ 37 | timestamp: () => `,"time":"${new Date().toJSON()}"` 38 | }); 39 | const logger = MAIN_LOGGER.child({}); 40 | logger.level = "trace"; 41 | 42 | const msgRetryCounterCache = new NodeCache(); 43 | 44 | const store = makeInMemoryStore({ 45 | logger: pino().child({ 46 | level: 'silent', 47 | stream: 'store' 48 | }) 49 | }); 50 | 51 | const __filename = new URL(import.meta.url).pathname; 52 | const __dirname = path.dirname(__filename); 53 | const credsPath = path.join(__dirname, '/auth_info_baileys/creds.json'); 54 | 55 | if (!fs.existsSync(credsPath)) { 56 | if (!config.SESSION_ID) { 57 | console.log('Please add your session to SESSION_ID env !!'); 58 | process.exit(1); 59 | } 60 | const sessdata = config.SESSION_ID.split("MASTER-MD&")[1]; 61 | const url = `https://pastebin.com/raw/${sessdata}`; 62 | console.log(sessdata); 63 | axios.get(url) 64 | .then(response => { 65 | const data = typeof response.data === 'string' ? response.data : JSON.stringify(response.data); 66 | return fs.promises.writeFile(credsPath, data); 67 | }) 68 | .then(() => { 69 | console.log("✔ Session Successfully Loaded !!"); 70 | }) 71 | .catch(err => { 72 | console.error("Failed to fetch session data:", err); 73 | process.exit(1); 74 | }); 75 | } 76 | 77 | const app = express(); 78 | const PORT = process.env.PORT || 5000; 79 | 80 | async function connectToWA() { 81 | const { state, saveCreds } = await useMultiFileAuthState(__dirname + '/auth_info_baileys/'); 82 | const { version, isLatest } = await fetchLatestBaileysVersion(); 83 | console.log(`🔰 MASTER-MD using WA v${version.join('.')}, isLatest: ${isLatest}`); 84 | const Matrix = makeWASocket({ 85 | version, 86 | logger: pino({ level: 'silent' }), 87 | printQRInTerminal: true, 88 | browser: ["MASTER-MD-V3", "safari", "3.3"], 89 | auth: state, 90 | getMessage: async (key) => { 91 | if (store) { 92 | const msg = await store.loadMessage(key.remoteJid, key.id); 93 | return msg.message || undefined; 94 | } 95 | return { 96 | conversation: "MASTER-MD IS POWERFUL WHATSAPP BOT" 97 | }; 98 | } 99 | }); 100 | 101 | Matrix.ev.on('connection.update', (update) => { 102 | const { connection, lastDisconnect } = update; 103 | if (connection === 'close') { 104 | if (lastDisconnect.error.output.statusCode !== DisconnectReason.loggedOut) { 105 | connectToWA(); 106 | } 107 | } else if (connection === 'open') { 108 | if (initialConnection) { 109 | console.log(chalk.green("🔰 Connected Successfull Dear ✅")); 110 | Matrix.sendMessage(Matrix.user.id, { text: ` *👨‍💻MASTER-MD-V3 IS CONNECTED👨‍💻* ` }); 111 | initialConnection = false; 112 | } else { 113 | console.log(chalk.blue("♻️ Connection reestablished after restart.")); 114 | } 115 | } 116 | }); 117 | 118 | Matrix.serialize = (m) => smsg(Matrix, m, store) 119 | 120 | Matrix.ev.on('creds.update', saveCreds); 121 | 122 | Matrix.ev.on("messages.upsert", async chatUpdate => await Handler(chatUpdate, Matrix, logger)); 123 | Matrix.ev.on("call", async (json) => await Callupdate(json, Matrix)); 124 | Matrix.ev.on("group-participants.update", async (messag) => await GroupUpdate(Matrix, messag)); 125 | 126 | if (config.MODE === "public") { 127 | Matrix.public = true; 128 | } else if (config.MODE === "private") { 129 | Matrix.public = false; 130 | } 131 | 132 | Matrix.ev.on('messages.upsert', async (chatUpdate) => { 133 | try { 134 | const mek = chatUpdate.messages[0]; 135 | if (!mek.key.fromMe && config.AUTO_REACT) { 136 | console.log(mek); 137 | if (mek.message) { 138 | const randomEmoji = emojis[Math.floor(Math.random() * emojis.length)]; 139 | await doReact(randomEmoji, mek, Matrix); 140 | } 141 | } 142 | } catch (err) { 143 | console.error('Error during auto reaction:', err); 144 | } 145 | }); 146 | } 147 | 148 | app.get("/", (req, res) => { 149 | res.send("*MASTER-MD WhatsApp Bot Working successfully..!*"); 150 | }); 151 | app.listen(PORT, () => console.log(`Server listening on port http://localhost:${PORT}`)); 152 | setTimeout(() => { 153 | connectToWA() 154 | }, 5000); 155 | -------------------------------------------------------------------------------- /src/plugin/apkdown.js: -------------------------------------------------------------------------------- 1 | import { search, download } from 'aptoide-scraper'; 2 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 3 | const { generateWAMessageFromContent, proto } = pkg; 4 | 5 | const apkMap = new Map(); 6 | let apkIndex = 1; // Global index for APKs 7 | 8 | const searchAPK = async (m, Matrix) => { 9 | let selectedListId; 10 | const selectedButtonId = m?.message?.templateButtonReplyMessage?.selectedId; 11 | const interactiveResponseMessage = m?.message?.interactiveResponseMessage; 12 | 13 | if (interactiveResponseMessage) { 14 | const paramsJson = interactiveResponseMessage.nativeFlowResponseMessage?.paramsJson; 15 | if (paramsJson) { 16 | const params = JSON.parse(paramsJson); 17 | selectedListId = params.id; 18 | } 19 | } 20 | 21 | const selectedId = selectedListId || selectedButtonId; 22 | 23 | const prefixMatch = m.body.match(/^[\\/!#.]/); 24 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 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 = ['apk', 'searchapk', 'apkdl', 'app']; 29 | 30 | if (validCommands.includes(cmd)) { 31 | if (!text) return m.reply('Please provide a search query for APKs'); 32 | 33 | try { 34 | await m.React("⬇️"); 35 | 36 | 37 | let searchResult = await search(text); 38 | const topAPKs = searchResult.slice(0, 10); 39 | 40 | if (topAPKs.length === 0) { 41 | m.reply('No APKs found.'); 42 | await m.React("❌"); 43 | return; 44 | } 45 | 46 | const apkButtons = await Promise.all(topAPKs.map(async (apk, index) => { 47 | const uniqueId = `apk_${apkIndex + index}`; 48 | const apkDetails = await download(apk.id); 49 | apkMap.set(uniqueId, { 50 | ...apk, 51 | size: apkDetails.size 52 | }); 53 | return { 54 | "header": "", 55 | "title": `📥 ${apk.name}`, 56 | "description": `Size: ${apkDetails.size}`, 57 | "id": uniqueId 58 | }; 59 | })); 60 | 61 | const msg = generateWAMessageFromContent(m.from, { 62 | viewOnceMessage: { 63 | message: { 64 | messageContextInfo: { 65 | deviceListMetadata: {}, 66 | deviceListMetadataVersion: 2 67 | }, 68 | interactiveMessage: proto.Message.InteractiveMessage.create({ 69 | body: proto.Message.InteractiveMessage.Body.create({ 70 | text: `👨‍💻MASTER-MD-V3👨‍💻\n⬇️𝙰𝙿𝙺 𝙳𝙾𝚆𝙽𝙻𝙾𝙰𝙳𝙴𝚁⬇️\n🔍 Search and download your favorite APKs easily.\n\n📌 Simply select an APK from the list below to get started.\n\n` 71 | }), 72 | footer: proto.Message.InteractiveMessage.Footer.create({ 73 | text: "© 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ" 74 | }), 75 | header: proto.Message.InteractiveMessage.Header.create({ 76 | ...(await prepareWAMessageMedia({ image: { url: `https://telegra.ph/file/83ae294a17351afb2773d.jpg` } }, { upload: Matrix.waUploadToServer })), 77 | title: ``, 78 | gifPlayback: true, 79 | subtitle: "", 80 | hasMediaAttachment: false 81 | }), 82 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 83 | buttons: [ 84 | { 85 | name: "single_select", 86 | buttonParamsJson: JSON.stringify({ 87 | title: "🔖 Select an APK", 88 | sections: [ 89 | { 90 | title: "😎 Top 10 APK Results", 91 | highlight_label: "🤩 Top 10", 92 | rows: apkButtons 93 | }, 94 | ] 95 | }) 96 | } 97 | ], 98 | }), 99 | contextInfo: { 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 | 115 | apkIndex += topAPKs.length; 116 | } catch (error) { 117 | console.error("Error processing your request:", error); 118 | m.reply('Error processing your request.'); 119 | await m.React("❌"); 120 | } 121 | } else if (selectedId) { 122 | const selectedAPK = apkMap.get(selectedId); 123 | 124 | if (selectedAPK) { 125 | try { 126 | const apkDetails = await download(selectedAPK.id); 127 | const url = apkDetails.dllink; 128 | const iconUrl = apkDetails.icon; 129 | const size = apkDetails.size; 130 | 131 | await Matrix.sendMessage(m.from, { image: { url: iconUrl }, caption: `You selected this APK:\n\nName: ${selectedAPK.name}\nsize: ${size}\n\n> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ` }, { quoted: m }); 132 | 133 | 134 | const apkMessage = { 135 | document: { url }, 136 | mimetype: 'application/vnd.android.package-archive', 137 | fileName: `${selectedAPK.name}.apk` 138 | }; 139 | 140 | await Matrix.sendMessage(m.from, apkMessage, { quoted: m }); 141 | } catch (error) { 142 | console.error("Error sending APK:", error); 143 | m.reply('Error sending APK.'); 144 | } 145 | } else { 146 | } 147 | } 148 | }; 149 | 150 | export default searchAPK; 151 | -------------------------------------------------------------------------------- /src/plugin/fbdown.js: -------------------------------------------------------------------------------- 1 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 2 | const { generateWAMessageFromContent, proto } = pkg; 3 | import pkgg from 'nayan-media-downloader'; 4 | const { ndown } = pkgg; 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 prefixMatch = m.body.match(/^[\\/!#.]/); 25 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 26 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 27 | const text = m.body.slice(prefix.length + cmd.length).trim(); 28 | 29 | const validCommands = ['facebook', 'fb', 'fbdl']; 30 | 31 | if (validCommands.includes(cmd)) { 32 | if (!text) { 33 | return m.reply('*Please provide a Facebook video URL.*'); 34 | } 35 | 36 | try { 37 | await m.React("🎁"); 38 | 39 | const fbData = await ndown(text); 40 | if (!fbData.status) { 41 | await m.reply('No results found.'); 42 | await m.React("❌"); 43 | return; 44 | } 45 | 46 | fbSearchResultsMap.set(fbSearchIndex, fbData); 47 | 48 | const buttons = fbData.data.map((video, index) => ({ 49 | "name": "quick_reply", 50 | "buttonParamsJson": JSON.stringify({ 51 | display_text: `📥 Download ${video.resolution}`, 52 | id: `media_${index}_${fbSearchIndex}` 53 | }) 54 | })); 55 | 56 | const sections = fbData.data.map((video) => ({ 57 | title: 'Video Qualities', 58 | rows: [{ 59 | title: `📥 Download ${video.resolution}`, 60 | description: `Resolution: ${video.resolution} | Size: ${(video.size / (1024 * 1024)).toFixed(2)} MB`, 61 | id: `media_${fbSearchIndex}_${video.resolution}` 62 | }] 63 | })); 64 | 65 | const msg = generateWAMessageFromContent(m.from, { 66 | viewOnceMessage: { 67 | message: { 68 | messageContextInfo: { 69 | deviceListMetadata: {}, 70 | deviceListMetadataVersion: 2 71 | }, 72 | interactiveMessage: proto.Message.InteractiveMessage.create({ 73 | body: proto.Message.InteractiveMessage.Body.create({ 74 | text: `*👨‍💻MASTER-MD👨‍💻* \n*FACEBOOK POST DOWNLOADER*\n\n> *🔰TITLE*: ${fbData.title}\n> *🔰SIZE*: ${(fbData.size / (1024 * 1024)).toFixed(2)} MB` 75 | }), 76 | footer: proto.Message.InteractiveMessage.Footer.create({ 77 | text: "© 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ" 78 | }), 79 | header: proto.Message.InteractiveMessage.Header.create({ 80 | ...(await prepareWAMessageMedia({ image: { url: `https://telegra.ph/file/83ae294a17351afb2773d.jpg` } }, { upload: Matrix.waUploadToServer })), 81 | title: "", 82 | gifPlayback: true, 83 | subtitle: "", 84 | hasMediaAttachment: false 85 | }), 86 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 87 | buttons 88 | }), 89 | contextInfo: { 90 | mentionedJid: [m.sender], 91 | forwardingScore: 9999, 92 | isForwarded: true, 93 | } 94 | }), 95 | }, 96 | }, 97 | }, {}); 98 | 99 | await Matrix.relayMessage(msg.key.remoteJid, msg.message, { 100 | messageId: msg.key.id 101 | }); 102 | await m.React("✅"); 103 | 104 | fbSearchIndex += 1; 105 | } catch (error) { 106 | console.error("Error processing your request:", error); 107 | await m.reply('Error processing your request.'); 108 | await m.React("❌"); 109 | } 110 | } else if (selectedId) { 111 | if (selectedId.startsWith('media_')) { 112 | const parts = selectedId.split('_'); 113 | const qualityIndex = parseInt(parts[1]); 114 | const key = parseInt(parts[2]); 115 | const selectedMedia = fbSearchResultsMap.get(key); 116 | 117 | if (selectedMedia) { 118 | try { 119 | const videoUrl = selectedMedia.data[qualityIndex].url; 120 | let finalMediaBuffer, mimeType, content; 121 | 122 | finalMediaBuffer = await getStreamBuffer(videoUrl); 123 | mimeType = 'video/mp4'; 124 | 125 | const fileSizeInMB = finalMediaBuffer.length / (1024 * 1024); 126 | 127 | if (fileSizeInMB <= 300) { 128 | content = { 129 | video: finalMediaBuffer, 130 | mimetype: 'video/mp4', 131 | caption: '> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ', 132 | }; 133 | await Matrix.sendMessage(m.from, content, { quoted: m }); 134 | } else { 135 | await m.reply('The video file size exceeds 300MB.'); 136 | } 137 | } catch (error) { 138 | console.error("Error processing your request:", error); 139 | await m.reply('Error processing your request.'); 140 | await m.React("❌"); 141 | } 142 | } 143 | } 144 | } 145 | }; 146 | 147 | const getStreamBuffer = async (url) => { 148 | const response = await fetch(url); 149 | const buffer = await response.arrayBuffer(); 150 | return Buffer.from(buffer); 151 | }; 152 | 153 | export default facebookCommand; 154 | -------------------------------------------------------------------------------- /src/plugin/tiktokdl.js: -------------------------------------------------------------------------------- 1 | import pkg, { prepareWAMessageMedia } from '@whiskeysockets/baileys'; 2 | const { generateWAMessageFromContent, proto } = pkg; 3 | import pkgg from 'nayan-media-downloader'; 4 | const { tikdown } = pkgg; 5 | 6 | 7 | const searchResultsMap = new Map(); 8 | let searchIndex = 1; 9 | 10 | const tiktokCommand = async (m, Matrix) => { 11 | let selectedListId; 12 | const selectedButtonId = m?.message?.templateButtonReplyMessage?.selectedId; 13 | const interactiveResponseMessage = m?.message?.interactiveResponseMessage; 14 | 15 | if (interactiveResponseMessage) { 16 | const paramsJson = interactiveResponseMessage.nativeFlowResponseMessage?.paramsJson; 17 | if (paramsJson) { 18 | const params = JSON.parse(paramsJson); 19 | selectedListId = params.id; 20 | } 21 | } 22 | 23 | const selectedId = selectedListId || selectedButtonId; 24 | 25 | const prefixMatch = m.body.match(/^[\\/!#.]/); 26 | const prefix = prefixMatch ? prefixMatch[0] : '/'; 27 | const cmd = m.body.startsWith(prefix) ? m.body.slice(prefix.length).split(' ')[0].toLowerCase() : ''; 28 | const text = m.body.slice(prefix.length + cmd.length).trim(); 29 | 30 | const validCommands = ['tiktok', 'tt', 'ttdl']; 31 | 32 | if (validCommands.includes(cmd)) { 33 | if (!text) { 34 | return m.reply('Please provide a TikTok URL.'); 35 | } 36 | 37 | try { 38 | await m.React("⬇️"); 39 | 40 | 41 | const tikTokData = await tikdown(text); 42 | if (!tikTokData.status) { 43 | await m.reply('No results found.'); 44 | await m.React("❌"); 45 | return; 46 | } 47 | 48 | 49 | searchResultsMap.set(searchIndex, tikTokData); 50 | 51 | 52 | const currentResult = searchResultsMap.get(searchIndex); 53 | const buttons = [ 54 | { 55 | "name": "quick_reply", 56 | "buttonParamsJson": JSON.stringify({ 57 | display_text: "🎦 Video", 58 | id: `media_video_${searchIndex}` 59 | }) 60 | }, 61 | { 62 | "name": "quick_reply", 63 | "buttonParamsJson": JSON.stringify({ 64 | display_text: "🎵 Audio", 65 | id: `media_audio_${searchIndex}` 66 | }) 67 | } 68 | ]; 69 | 70 | const msg = generateWAMessageFromContent(m.from, { 71 | viewOnceMessage: { 72 | message: { 73 | messageContextInfo: { 74 | deviceListMetadata: {}, 75 | deviceListMetadataVersion: 2 76 | }, 77 | interactiveMessage: proto.Message.InteractiveMessage.create({ 78 | body: proto.Message.InteractiveMessage.Body.create({ 79 | text: `👨‍💻MASTER-MD-V3👨‍💻\n\n⬇️𝚃𝙸𝙺𝚃𝙾𝙺 𝙳𝙾𝚆𝙽𝙻𝙾𝙰𝙳𝙴𝚁⬇️\n🔰Title: ${currentResult.data.title}\n🔰Author: ${currentResult.data.author.nickname}\n🔰Views: ${currentResult.data.view}\n🔰Duration: ${currentResult.data.duration}s\n` 80 | }), 81 | footer: proto.Message.InteractiveMessage.Footer.create({ 82 | text: "© 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ" 83 | }), 84 | header: proto.Message.InteractiveMessage.Header.create({ 85 | ...(await prepareWAMessageMedia({ image: { url: `https://telegra.ph/file/83ae294a17351afb2773d.jpg` } }, { upload: Matrix.waUploadToServer })), 86 | title: "", 87 | gifPlayback: true, 88 | subtitle: "", 89 | hasMediaAttachment: false 90 | }), 91 | nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ 92 | buttons 93 | }), 94 | contextInfo: { 95 | mentionedJid: [m.sender], 96 | forwardingScore: 9999, 97 | isForwarded: true, 98 | } 99 | }), 100 | }, 101 | }, 102 | }, {}); 103 | 104 | await Matrix.relayMessage(msg.key.remoteJid, msg.message, { 105 | messageId: msg.key.id 106 | }); 107 | await m.React("✅"); 108 | 109 | searchIndex += 1; 110 | } catch (error) { 111 | console.error("Error processing your request:", error); 112 | await m.reply('Error processing your request.'); 113 | await m.React("❌"); 114 | } 115 | } else if (selectedId) { 116 | if (selectedId.startsWith('media_')) { 117 | const parts = selectedId.split('_'); 118 | const type = parts[1]; 119 | const key = parseInt(parts[2]); 120 | const selectedMedia = searchResultsMap.get(key); 121 | 122 | if (selectedMedia) { 123 | try { 124 | const videoUrl = selectedMedia.data.video; 125 | const audioUrl = selectedMedia.data.audio; 126 | let finalMediaBuffer, mimeType, content; 127 | 128 | if (type === 'video') { 129 | finalMediaBuffer = await getStreamBuffer(videoUrl); 130 | mimeType = 'video/mp4'; 131 | } else if (type === 'audio') { 132 | finalMediaBuffer = await getStreamBuffer(audioUrl); 133 | mimeType = 'audio/mpeg'; 134 | } 135 | 136 | const fileSizeInMB = finalMediaBuffer.length / (1024 * 1024); 137 | 138 | if (type === 'video' && fileSizeInMB <= 300) { 139 | content = { video: finalMediaBuffer, mimetype: 'video/mp4', caption: '> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ' }; 140 | } else if (type === 'audio' && fileSizeInMB <= 300) { 141 | content = { audio: finalMediaBuffer, mimetype: 'audio/mpeg', caption: '> © 𝐂ʀᴇᴀᴛᴇᴅ 𝐁ʏ 𝐌ʀ 𝐒ᴀʜᴀɴ 𝐎ꜰᴄ' }; 142 | } 143 | 144 | await Matrix.sendMessage(m.from, content, { quoted: m }); 145 | } catch (error) { 146 | console.error("Error processing your request:", error); 147 | await m.reply('Error processing your request.'); 148 | await m.React("❌"); 149 | } 150 | } 151 | } 152 | } 153 | }; 154 | 155 | const getStreamBuffer = async (url) => { 156 | const response = await fetch(url); 157 | const buffer = await response.arrayBuffer(); 158 | return Buffer.from(buffer); 159 | }; 160 | 161 | export default tiktokCommand; 162 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------