├── README.md ├── index.js ├── lib ├── append.js ├── case.js ├── converter.js ├── database.js ├── function.js ├── leveling.js ├── logger.js ├── plugins.js ├── queque.js ├── serialize.js ├── simple.js ├── sticker.js └── uploader.js ├── package.json ├── run.js ├── scrapers ├── index.js └── src │ ├── Instagram.js │ ├── aio.js │ ├── anoboy.js │ ├── applemusic.js │ ├── bstation.js │ ├── chatbot.js │ ├── doodstream.js │ ├── facebook.js │ ├── komiku.js │ ├── krakenfiles.js │ ├── kuronime.js │ ├── libur.js │ ├── mediafire.js │ ├── metaai.js │ ├── nekopoi.js │ ├── otakudesu.js │ ├── pinterest.js │ ├── remini.js │ ├── removebg.js │ ├── samehadaku.js │ ├── sfile.js │ ├── snackvideo.js │ ├── sokuja.js │ ├── soundcloud.js │ ├── spotify.js │ ├── steam.js │ ├── terabox.js │ ├── tiktok.js │ ├── translate.js │ ├── ttsave.js │ ├── videodl.js │ ├── whatmusic.js │ ├── xbox.js │ ├── yousearch.js │ ├── ytdl.js │ └── zzz.js ├── settings.js ├── system ├── case.js ├── handler.js └── plugins │ ├── ai │ ├── deepseek.js │ ├── gemini.js │ └── openai.js │ ├── anime │ ├── kuronime.js │ ├── samehadaku.js │ ├── sokuja.js │ └── waifu.js │ ├── downloader │ ├── applemusic.js │ ├── bstation.js │ ├── doodstream.js │ ├── fb.js │ ├── gitclone.js │ ├── instagram.js │ ├── mediafire.js │ ├── pinterest.js │ ├── rednote.js │ ├── sfile.js │ ├── snackvideo.js │ ├── soundcloud.js │ ├── spotify.js │ ├── tiktok.js │ ├── ttsearch.js │ ├── videy-dl.js │ └── youtube.js │ ├── events │ ├── _alias-msg.js │ ├── _button-resp.js │ ├── _eval.js │ └── antilink.js │ ├── game │ └── blackjack.js │ ├── group │ ├── add.js │ ├── demote.js │ ├── hidetag.js │ ├── kick.js │ ├── linkgc.js │ ├── promote.js │ ├── revoke.js │ ├── setdesc.js │ ├── setnamegc.js │ ├── setpp.js │ └── settings.js │ ├── info │ ├── ci.js │ ├── listgroup.js │ ├── script.js │ └── tqto.js │ ├── islam │ └── alif.js │ ├── menu.js │ ├── owner │ ├── backup.js │ ├── broadcast.js │ ├── clearchat.js │ ├── example.js │ ├── join.js │ ├── plugins.js │ ├── scrape.js │ ├── self.js │ ├── setpp.js │ └── upsw.js │ ├── ping.js │ ├── rpg │ ├── bank.js │ ├── bansos.js │ ├── gajian.js │ ├── levelup.js │ ├── mulung.js │ ├── profile.js │ └── taxy.js │ ├── say.js │ └── tools │ ├── enc.js │ ├── forward.js │ ├── get.js │ ├── hikagen.js │ ├── kalender.js │ ├── npm.js │ ├── pixiv.js │ ├── qc.js │ ├── remini.js │ ├── removebg.js │ ├── tourl.js │ └── whatmusic.js └── tmp └── NekoHost.json /README.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://files.catbox.moe/obf6o0.jpg) 2 | 3 | **😼 NekoBot | 1.7.0** | ***create by AxellNetwork*** 4 | 5 | 6 | ```> Simple WhatsApp bot Using Library Baileys``` 7 | 8 | ```javascript 9 | { 10 | message: Message { conversation: '>_ Welcome to NekoBot' }, 11 | type: 'conversation', 12 | msg: '>_ Welcome to NekoBot', 13 | isMedia: false, 14 | key: { 15 | remoteJid: '6285165556936@s.whatsapp.net', 16 | participant: '6285165556936@s.whatsapp.net', 17 | fromMe: false, 18 | id: '5780C33F89C0BE600B6D71DF79C4FC02' 19 | }, 20 | cht: '6285165556936@s.whatsapp.net', 21 | fromMe: false, 22 | id: '5780C33F89C0BE600B6D71DF79C4FC02', 23 | device: 'android', 24 | isBot: false, 25 | isGroup: false, 26 | participant: '6285165556936@s.whatsapp.net', 27 | sender: '6285165556936@s.whatsapp.net', 28 | mentions: [], 29 | body: '>_ Welcome to NekoBot', 30 | prefix: '', 31 | command: '>_', 32 | args: [ 'Welcome', 'to', 'NekoBot' ], 33 | text: 'Welcome to NekoBot', 34 | isOwner: true, 35 | download: [AsyncFunction (anonymous)] 36 | } 37 | ``` 38 | ## ⚙️ Settings Bot ***( settings.js )*** 39 | 40 | ```javascript 41 | const fs = require('node:fs'); 42 | 43 | const config = { 44 | owner: ["6285215909004"], 45 | name: "- nekoBot - Simple WhatsApp bot", 46 | sessions: "sessions", 47 | sticker: { 48 | packname: "Made by ", 49 | author: "nekoBot" 50 | }, 51 | messages: { 52 | wait: "*( Loading )* Tunggu Sebentar...", 53 | owner: "*( Denied )* Kamu bukan owner ku !", 54 | premium: "*( Denied )* Fitur ini khusus user premium", 55 | group: "*( Denied )* Fitur ini khusus group", 56 | }, 57 | database: "neko-db", 58 | tz: "Asia/Jakarta" 59 | } 60 | 61 | module.exports = config 62 | ``` 63 | 64 | 65 | ## 👨‍💻 How to install/run 66 | 67 | 68 | ```bash 69 | $ git clone https://github.com/AxellNetwork/NekoBot 70 | $ cd nekoBot 71 | $ npm install 72 | $ npm start 73 | ``` 74 | 75 | ## ☘️ Example Features 76 | Berikut cara menambahkan fitur pada bot ini 77 | 78 | ## 1. Plugins 79 | 80 | ```javascript 81 | 82 | module.exports = { 83 | command: "tes", //- Nama fitur nya 84 | alias: ["tesbot", "testing"], //- Short cut command 85 | category: ["main"], //- Kategori Fitur 86 | settings: { 87 | owner: false, //- Apakah Fitur ini khusus owner ? 88 | group: false, // - Apakah Fitur ini khusus group ? 89 | }, 90 | description: "Tes bot saja", //- Penjelasan tentang fitur nya 91 | loading: true, //- Ingin menambahkan loading messages ? 92 | async run(m, { sock, Func, Scraper, text, config }) { 93 | m.reply("> Bot Online ✓") 94 | } 95 | } 96 | ``` 97 | ## 2. Case 98 | 99 | ```javascript 100 | case "tes" : { 101 | m.reply("> Bot Online ✓") 102 | } 103 | break 104 | ``` 105 | ## 📢 Discussion 106 | Jika ingin mengenal seputar Script ini lebih dalam lagi 107 | silahkan mampir ke komunitas kami 108 | 109 | [![WhatsApp Group](https://img.shields.io/badge/WhatsApp%20Group-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://chat.whatsapp.com/ErlaFMvdnfu5OGxCVGJW8V) 110 | 111 | [![WhatsApp channel](https://img.shields.io/badge/WhatsApp%20Channel-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://whatsapp.com/channel/0029Vb0YWvYJ3jusF2nk9U1P) 112 | 113 | -------------------------------------------------------------------------------- /lib/case.js: -------------------------------------------------------------------------------- 1 | const { 2 | js 3 | } = require("js-beautify"); 4 | const fs = require('fs'); 5 | 6 | class CaseManager { 7 | constructor(file) { 8 | this.file = file; 9 | } 10 | 11 | get = (name) => { 12 | try { 13 | let content = fs.readFileSync(this.file, 'utf8'); 14 | let regex = /case .*?:/g; 15 | let cases = content.match(regex); 16 | let targetCases = cases.filter(cas => cas.includes(name)); 17 | if (targetCases.length > 0) { 18 | let start = content.indexOf(targetCases[0]); 19 | let end = content.indexOf('break', start); 20 | return content.substring(start, end + 6); 21 | } else { 22 | return null; 23 | } 24 | } catch (error) { 25 | console.error(`Gagal membaca file: ${error.message}`); 26 | } 27 | } 28 | 29 | add = (code) => { 30 | try { 31 | let content = fs.readFileSync(this.file, 'utf8'); 32 | let regex = /switch\s*\([^)]+\)\s*{/; 33 | let switchContent = content.match(regex); 34 | let newCase = `${code}`; 35 | let updatedContent = content.replace(regex, `${switchContent}\n${newCase}`); 36 | fs.writeFileSync(this.file, js(updatedContent)); 37 | return true 38 | } catch (error) { 39 | console.error(`Gagal menambahkan case: ${error.message}`); 40 | return false; 41 | } 42 | } 43 | 44 | delete = (name) => { 45 | try { 46 | let content = fs.readFileSync(this.file, 'utf8'); 47 | let caseToDelete = this.get(name); 48 | if (!caseToDelete) return false; 49 | let updatedContent = content.replace(caseToDelete, ''); 50 | fs.writeFileSync(this.file, updatedContent); 51 | return true; 52 | } catch (error) { 53 | console.error(`Gagal menghapus case: ${error.message}`); 54 | return false; 55 | } 56 | } 57 | 58 | list = () => { 59 | try { 60 | let data = fs.readFileSync(this.file, "utf8"); 61 | let casePattern = /case\s+"([^"]+)"/g; 62 | let matches = data.match(casePattern).map((match) => match.replace(/case\s+"([^"]+)"/, "$1")); 63 | 64 | return matches 65 | } catch (error) { 66 | console.error(`Gagal membaca file: ${error.message}`); 67 | return []; 68 | } 69 | } 70 | } 71 | 72 | module.exports = CaseManager -------------------------------------------------------------------------------- /lib/converter.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const { spawn } = require("child_process"); 4 | 5 | function ffmpeg(buffer, args = [], ext = "", ext2 = "") { 6 | return new Promise(async (resolve, reject) => { 7 | try { 8 | let tmp = process.cwd() + "/tmp/ffmpeg_" + Date.now() + "." + ext; 9 | let out = tmp + "." + ext2; 10 | await fs.promises.writeFile(tmp, buffer); 11 | spawn("ffmpeg", ["-y", "-i", tmp, ...args, out]) 12 | .on("error", reject) 13 | .on("close", async (code) => { 14 | try { 15 | await fs.promises.unlink(tmp); 16 | if (code !== 0) return reject(code); 17 | resolve({ data: await fs.promises.readFile(out), filename: out }); 18 | // await fs.promises.unlink(out) 19 | } catch (e) { 20 | reject(e); 21 | } 22 | }); 23 | } catch (e) { 24 | reject(e); 25 | } 26 | }); 27 | } 28 | 29 | /** 30 | * Convert Audio to Playable WhatsApp Audio 31 | * @param {Buffer} buffer Audio Buffer 32 | * @param {String} ext File Extension 33 | */ 34 | function toPTT(buffer, ext) { 35 | return ffmpeg( 36 | buffer, 37 | ["-vn", "-c:a", "libmp3lame", "-b:a", "128k", "-vbr", "on"], 38 | ext, 39 | "mp3", 40 | ); 41 | } 42 | 43 | /** 44 | * Convert Audio to Playable WhatsApp PTT 45 | * @param {Buffer} buffer Audio Buffer 46 | * @param {String} ext File Extension 47 | */ 48 | function toAudio(buffer, ext) { 49 | return ffmpeg( 50 | buffer, 51 | [ 52 | "-vn", 53 | "-c:a", 54 | "libmp3lame", 55 | "-b:a", 56 | "128k", 57 | "-vbr", 58 | "on", 59 | "-compression_level", 60 | "10", 61 | ], 62 | ext, 63 | "mp3", 64 | ); 65 | } 66 | 67 | /** 68 | * Convert Audio to Playable WhatsApp Video 69 | * @param {Buffer} buffer Video Buffer 70 | * @param {String} ext File Extension 71 | */ 72 | function toVideo(buffer, ext) { 73 | return ffmpeg( 74 | buffer, 75 | [ 76 | "-c:v", 77 | "libx264", 78 | "-c:a", 79 | "aac", 80 | "-ab", 81 | "128k", 82 | "-ar", 83 | "44100", 84 | "-crf", 85 | "32", 86 | "-preset", 87 | "slow", 88 | ], 89 | ext, 90 | "mp4", 91 | ); 92 | } 93 | 94 | module.exports = { 95 | toAudio, 96 | toPTT, 97 | toVideo, 98 | ffmpeg, 99 | }; 100 | -------------------------------------------------------------------------------- /lib/database.js: -------------------------------------------------------------------------------- 1 | const fs = require("node:fs"); 2 | const path = require("node:path"); 3 | 4 | class Database { 5 | #data; 6 | constructor(filename) { 7 | this.databaseFile = path.join(".", filename); 8 | this.#data = {}; 9 | } 10 | default = () => { 11 | return { 12 | user: {}, 13 | group: {}, 14 | changelog: {}, 15 | settings: { 16 | self: false, 17 | online: true, 18 | anticall: false, 19 | blockcmd: [], 20 | max_upload: "50MB", 21 | resetlimit: "02:00", 22 | }, 23 | }; 24 | }; 25 | init = async () => { 26 | const data = await this.read(); 27 | this.#data = { ...this.#data, ...data }; 28 | return this.#data; 29 | }; 30 | read = async () => { 31 | if (fs.existsSync(this.databaseFile)) { 32 | const data = fs.readFileSync(this.databaseFile); 33 | return JSON.parse(data); 34 | } else { 35 | return this.default(); 36 | } 37 | }; 38 | 39 | save = async () => { 40 | const jsonData = JSON.stringify(this.#data, null, 2); 41 | fs.writeFileSync(this.databaseFile, jsonData); 42 | }; 43 | add = async (type, id, newData) => { 44 | if (!this.#data[type]) return `- Tipe data ${type} tidak ditemukan!`; 45 | if (!this.#data[type][id]) { 46 | this.#data[type][id] = newData; 47 | } 48 | await this.save(); 49 | return this.#data[type][id]; 50 | }; 51 | delete = async (type, id) => { 52 | if (this.#data[type] && this.#data[type][id]) { 53 | delete this.#data[type][id]; 54 | await this.save(); 55 | return `- ${type} dengan ID ${id} telah dihapus.`; 56 | } else { 57 | return `- ${type} dengan ID ${id} tidak ditemukan!`; 58 | } 59 | }; 60 | get = (type, id) => { 61 | if (this.#data[type] && this.#data[type][id]) { 62 | return this.#data[type][id]; 63 | } else { 64 | return `- ${type} dengan ID ${id} tidak ditemukan!`; 65 | } 66 | }; 67 | main = async (m) => { 68 | await this.read(); 69 | if (m.isGroup) { 70 | await this.add("group", m.cht, { 71 | mute: false, 72 | sewa: { 73 | status: false, 74 | expired: 0, 75 | }, 76 | message: 0, 77 | status: "not_announcement", 78 | }); 79 | } 80 | await this.add("user", m.sender, { 81 | name: "Gak punya nama", 82 | limit: 100, 83 | register: false, 84 | rpg: { 85 | money: 0, 86 | exp: 0, 87 | lastGajian: 0, 88 | sampah: 0, 89 | botol: 0, 90 | kardus: 0, 91 | iron: 0, 92 | kayu: 0, 93 | kaleng: 0, 94 | gelas: 0, 95 | plastik: 0, 96 | lastMulung: 0, 97 | lastTaxy: 0, 98 | }, 99 | level: 1, 100 | bank: 0, 101 | coin: 0, 102 | premium: { 103 | status: false, 104 | expired: 0, 105 | }, 106 | banned: { 107 | status: false, 108 | expired: 0, 109 | }, 110 | }); 111 | await this.save(); 112 | return this.list(); 113 | }; 114 | list = () => { 115 | return this.#data; 116 | }; 117 | } 118 | 119 | module.exports = Database; 120 | -------------------------------------------------------------------------------- /lib/leveling.js: -------------------------------------------------------------------------------- 1 | const growth = Math.pow(Math.PI / Math.E, 1.618) * Math.E * 0.75; 2 | 3 | function xpRange(level, multiplier = global.multiplier || 1) { 4 | if (level < 0) { 5 | throw new TypeError("Level tidak boleh negatif"); 6 | } 7 | const min = level === 0 ? 0 : Math.round(Math.pow(level, growth) * multiplier) + 1; 8 | const max = Math.round(Math.pow(level + 1, growth) * multiplier); 9 | return { min, max, xp: max - min }; 10 | } 11 | 12 | function findLevel(xp, multiplier = global.multiplier || 1) { 13 | if (xp === 1 / 0) return 1 / 0; 14 | if (isNaN(xp)) return NaN; 15 | if (xp <= 0) return -1; 16 | let level = 0; 17 | do { 18 | level++; 19 | } while (xpRange(level, multiplier).min <= xp); 20 | return --level; 21 | } 22 | 23 | function canLevelUp(level, xp, multiplier = global.multiplier || 1) { 24 | return level >= 0 && (xp === 1 / 0 || (!isNaN(xp) && xp > 0 && level < findLevel(xp, multiplier))); 25 | } 26 | 27 | module.exports = { 28 | growth, 29 | xpRange, 30 | findLevel, 31 | canLevelUp 32 | }; -------------------------------------------------------------------------------- /lib/logger.js: -------------------------------------------------------------------------------- 1 | const color = require("chalk"); 2 | 3 | module.exports = (m) => { 4 | const divider = color.magenta.bold("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); 5 | 6 | let info = ""; 7 | info += `${divider}\n`; 8 | info += color.cyan.bold("📬 Chat Information\n"); 9 | info += `${divider}\n`; 10 | info += color.white.bold(`🗨️ Dari : `) + 11 | color.green.bold(m.isGroup ? "Group Chat" : "Private Chat") + "\n"; 12 | 13 | if (m.isGroup) { 14 | info += color.white.bold(`👥 Subject : `) + color.yellow.bold(m.metadata.subject) + "\n"; 15 | } 16 | info += color.white.bold(`📂 Tipe : `) + color.blue.bold(m.type) + "\n"; 17 | info += color.white.bold(`🙋 Nama : `) + color.magenta.bold(m.pushName) + "\n"; 18 | info += `${divider}\n`; 19 | 20 | const body = m.body.startsWith(m.prefix) 21 | ? color.yellow.bold(` ✏️ Pesan: ${m.body} `) 22 | : color.white.bold(` ✏️ Pesan: ${m.body} `); 23 | 24 | info += `${body}\n`; 25 | info += `${divider}`; 26 | 27 | console.log(info); 28 | }; 29 | -------------------------------------------------------------------------------- /lib/plugins.js: -------------------------------------------------------------------------------- 1 | const path = require("node:path"); 2 | const fs = require("node:fs"); 3 | const { promisify } = require("node:util"); 4 | const chokidar = require("chokidar"); 5 | const chalk = require("chalk"); 6 | 7 | const readdir = promisify(fs.readdir); 8 | const stat = promisify(fs.stat); 9 | 10 | class PluginLoader { 11 | constructor(directory) { 12 | this.directory = directory; 13 | this.plugins = {}; 14 | } 15 | 16 | async scandir(dir) { 17 | const subdirs = await readdir(dir); 18 | const files = await Promise.all( 19 | subdirs.map(async (subdir) => { 20 | const res = path.resolve(dir, subdir); 21 | return (await stat(res)).isDirectory() ? this.scandir(res) : res; 22 | }), 23 | ); 24 | return files.reduce((a, f) => a.concat(f), []); 25 | } 26 | 27 | load = async () => { 28 | const files = await this.scandir(this.directory); 29 | for (const filename of files) { 30 | const relativePath = path.relative(process.cwd(), filename); 31 | try { 32 | this.plugins[relativePath] = require(filename); 33 | } catch (e) { 34 | console.log(chalk.redBright(`❌ Gagal memuat [ ${relativePath} ]: `) + e); 35 | delete this.plugins[relativePath]; 36 | } 37 | } 38 | }; 39 | 40 | watch = async () => { 41 | const watcher = chokidar.watch(path.resolve(this.directory), { 42 | persistent: true, 43 | ignoreInitial: true, 44 | }); 45 | 46 | watcher 47 | .on("add", async (filename) => { 48 | const relativePath = path.relative(process.cwd(), filename); 49 | if (require.cache[filename]) { 50 | delete require.cache[filename]; 51 | } 52 | this.plugins[relativePath] = require(filename); 53 | console.log(chalk.cyanBright(`📥 Plugin baru terdeteksi: ${filename}`)); 54 | return this.load(); 55 | }) 56 | .on("change", async (filename) => { 57 | if (!filename.endsWith(".js")) return; 58 | const relativePath = path.relative(process.cwd(), filename); 59 | if (require.cache[filename]) { 60 | delete require.cache[filename]; 61 | } 62 | this.plugins[relativePath] = require(filename); 63 | console.log(chalk.yellowBright(`✏️ File diubah: ${filename}`)); 64 | return this.load(); 65 | }) 66 | .on("unlink", (filename) => { 67 | const relativePath = path.relative(process.cwd(), filename); 68 | console.log(chalk.redBright(`🗑️ File dihapus: ${filename}`)); 69 | delete this.plugins[relativePath]; 70 | }); 71 | }; 72 | } 73 | 74 | module.exports = PluginLoader; 75 | -------------------------------------------------------------------------------- /lib/queque.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.queues = {}; 4 | this.processing = {}; 5 | } 6 | add(userId, item) { 7 | if (!this.queues[userId]) { 8 | this.queues[userId] = []; 9 | this.processing[userId] = false; 10 | } 11 | this.queues[userId].push(item); 12 | } 13 | first(userId) { 14 | return this.queues[userId]?.[0] || null; 15 | } 16 | delete(userId) { 17 | if (this.queues[userId]) { 18 | this.queues[userId].shift(); 19 | if (this.queues[userId].length === 0) { 20 | delete this.queues[userId]; 21 | delete this.processing[userId]; 22 | } 23 | } 24 | } 25 | isEmpty(userId) { 26 | return !this.queues[userId] || this.queues[userId].length === 0; 27 | } 28 | async processQueue(userId, callback) { 29 | if (this.processing[userId] || this.isEmpty(userId)) return; 30 | this.processing[userId] = true; 31 | while (!this.isEmpty(userId)) { 32 | const currentItem = this.first(userId); 33 | try { 34 | await callback(currentItem); 35 | this.delete(userId); 36 | } catch (error) { 37 | console.error(`Error processing queue item for user ${userId}:`, error); 38 | break; 39 | } 40 | } 41 | 42 | this.processing[userId] = false; 43 | } 44 | } 45 | 46 | module.exports = Queue; 47 | -------------------------------------------------------------------------------- /lib/sticker.js: -------------------------------------------------------------------------------- 1 | const fs = require("node:fs"); 2 | const Crypto = require("crypto"); 3 | const ff = require("fluent-ffmpeg"); 4 | const webp = require("node-webpmux"); 5 | const path = require("path"); 6 | 7 | const temp = process.platform === "win32" ? process.env.TEMP : "/tmp"; 8 | 9 | async function imageToWebp(media) { 10 | const tmpFileIn = path.join( 11 | temp, 12 | `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.${media?.ext || "png"}`, 13 | ); 14 | const tmpFileOut = path.join( 15 | temp, 16 | `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`, 17 | ); 18 | 19 | fs.writeFileSync(tmpFileIn, media.data); 20 | 21 | try { 22 | await new Promise((resolve, reject) => { 23 | ff(tmpFileIn) 24 | .on("error", reject) 25 | .on("end", () => resolve(true)) 26 | .addOutputOptions([ 27 | "-vcodec", 28 | "libwebp", 29 | "-vf", 30 | "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=000000 [p]; [b][p] paletteuse", 31 | ]) 32 | .toFormat("webp") 33 | .saveToFile(tmpFileOut); 34 | }); 35 | 36 | fs.promises.unlink(tmpFileIn); 37 | const buff = fs.readFileSync(tmpFileOut); 38 | fs.promises.unlink(tmpFileOut); 39 | 40 | return buff; 41 | } catch (e) { 42 | fs.existsSync(tmpFileIn) ? fs.promises.unlink(tmpFileIn) : ""; 43 | fs.existsSync(tmpFileOut) ? fs.promises.unlink(tmpFileOut) : ""; 44 | throw e; 45 | } 46 | } 47 | 48 | async function videoToWebp(media) { 49 | const tmpFileIn = path.join( 50 | temp, 51 | `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.${media?.ext || "mp4"}`, 52 | ); 53 | const tmpFileOut = path.join( 54 | temp, 55 | `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`, 56 | ); 57 | 58 | fs.writeFileSync(tmpFileIn, media.data); 59 | 60 | try { 61 | await new Promise((resolve, reject) => { 62 | ff(tmpFileIn) 63 | .on("error", reject) 64 | .on("end", () => resolve(true)) 65 | .addOutputOptions([ 66 | "-vcodec", 67 | "libwebp", 68 | "-vf", 69 | "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=000000 [p]; [b][p] paletteuse", 70 | "-loop", 71 | "0", 72 | "-ss", 73 | "00:00:00", 74 | "-t", 75 | "00:00:05", 76 | "-preset", 77 | "default", 78 | "-an", 79 | "-vsync", 80 | "0", 81 | ]) 82 | .toFormat("webp") 83 | .saveToFile(tmpFileOut); 84 | }); 85 | 86 | fs.promises.unlink(tmpFileIn); 87 | const buff = fs.readFileSync(tmpFileOut); 88 | fs.promises.unlink(tmpFileOut); 89 | 90 | return buff; 91 | } catch (e) { 92 | fs.existsSync(tmpFileIn) ? fs.promises.unlink(tmpFileIn) : ""; 93 | fs.existsSync(tmpFileOut) ? fs.promises.unlink(tmpFileOut) : ""; 94 | throw e; 95 | } 96 | } 97 | 98 | async function writeExif(media, metadata) { 99 | let wMedia = /webp/.test(media.mimetype) 100 | ? media.data 101 | : /image/.test(media.mimetype) 102 | ? await imageToWebp(media) 103 | : /video/.test(media.mimetype) 104 | ? await videoToWebp(media) 105 | : ""; 106 | 107 | if (metadata && Object?.keys(metadata).length !== 0) { 108 | const img = new webp.Image(); 109 | const json = { 110 | "sticker-pack-id": metadata?.packId || `hisoka-${Date.now()}`, 111 | "sticker-pack-name": metadata?.packName || "", 112 | "sticker-pack-publisher": metadata?.packPublish || "", 113 | "android-app-store-link": 114 | metadata?.androidApp || 115 | "https://play.google.com/store/apps/details?id=com.bitsmedia.android.muslimpro", 116 | "ios-app-store-link": 117 | metadata?.iOSApp || 118 | "https://apps.apple.com/id/app/muslim-pro-al-quran-adzan/id388389451?|=id", 119 | emojis: metadata?.emojis || ["😋", "😎", "🤣", "😂", "😁"], 120 | "is-avatar-sticker": metadata?.isAvatar || 0, 121 | }; 122 | const exifAttr = Buffer.from([ 123 | 0x49, 0x49, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 124 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 125 | ]); 126 | const jsonBuff = Buffer.from(JSON.stringify(json), "utf-8"); 127 | const exif = Buffer.concat([exifAttr, jsonBuff]); 128 | exif.writeUIntLE(jsonBuff.length, 14, 4); 129 | await img.load(wMedia); 130 | img.exif = exif; 131 | 132 | return await img.save(null); 133 | } 134 | } 135 | 136 | module.exports = { 137 | writeExif, 138 | videoToWebp, 139 | imageToWebp, 140 | }; 141 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nekoBot", 3 | "version": "1.7.0", 4 | "description": "- WhatsApp bot using Library Baileys", 5 | "main": "index.js", 6 | "directories": { 7 | "lib": "lib" 8 | }, 9 | "scripts": { 10 | "start": "node index.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/AxellNetwork/nekoBot.git" 15 | }, 16 | "keywords": [ 17 | "botwa" 18 | ], 19 | "author": "Axel_Team", 20 | "license": "ISC", 21 | "bugs": { 22 | "url": "https://github.com/AxellNetwork/nekoBot/issues" 23 | }, 24 | "homepage": "https://github.com/AxellNetwork/nekoBot#readme", 25 | "dependencies": { 26 | "acrcloud": "^1.4.0", 27 | "async-lock": "^1.4.1", 28 | "baileys": "github:AxellNetwork/Baileys", 29 | "cfonts": "latest", 30 | "chalk": "^4.1.2", 31 | "cheerio": "^1.0.0", 32 | "chokidar": "^4.0.1", 33 | "fake-useragent": "^1.0.1", 34 | "fluent-ffmpeg": "^2.1.3", 35 | "javascript-obfuscator": "^4.1.1", 36 | "js-beautify": "^1.15.1", 37 | "jsdom": "^25.0.1", 38 | "link-preview-js": "^3.0.12", 39 | "lodash": "^4.17.21", 40 | "moment-timezone": "^0.5.46", 41 | "node-cron": "^3.0.3", 42 | "node-fetch": "npm:undici@^6.21.0", 43 | "node-webpmux": "^3.2.0", 44 | "pdfkit": "^0.16.0", 45 | "pino": "^9.5.0", 46 | "qs": "^6.13.1", 47 | "jimp": "^0.16.1", 48 | "sharp": "^0.32.6", 49 | "undici": "^6.21.0", 50 | "wa-sticker-formatter": "^4.4.4", 51 | "yt-search": "^2.12.1", 52 | "ytdl-core": "npm:@distube/ytdl-core@^4.16.4" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /run.js: -------------------------------------------------------------------------------- 1 | console.log('Panel siap digunakan, silahkan masukan perintah Anda.') 2 | require('child_process').spawn('bash', [], { 3 | stdio: ['inherit', 'inherit', 'inherit', 'ipc'] 4 | }) 5 | -------------------------------------------------------------------------------- /scrapers/index.js: -------------------------------------------------------------------------------- 1 | const chokidar = require("chokidar"); 2 | const path = require("node:path"); 3 | const fs = require("node:fs"); 4 | const { promisify } = require("node:util"); 5 | const chalk = require("chalk"); 6 | const readdir = promisify(fs.readdir); 7 | const stat = promisify(fs.stat); 8 | 9 | const Scandir = async (dir) => { 10 | let subdirs = await readdir(path.resolve(dir)); 11 | let files = await Promise.all( 12 | subdirs.map(async (subdir) => { 13 | let res = path.resolve(path.resolve(dir), subdir); 14 | return (await stat(res)).isDirectory() ? Scandir(res) : res; 15 | }), 16 | ); 17 | return files.reduce((a, f) => a.concat(f), []); 18 | }; 19 | class Scraper { 20 | #src; 21 | constructor(dir) { 22 | this.dir = dir; 23 | this.#src = {}; 24 | } 25 | load = async () => { 26 | let data = await Scandir("./scrapers/src"); 27 | for (let i of data) { 28 | let name = i.split("/").pop().replace(".js", ""); 29 | try { 30 | if (!i.endsWith(".js")) return; 31 | this.#src[name] = require(i); 32 | } catch (e) { 33 | console.log(chalk.red.bold("- Gagal memuat Scraper :" + e)); 34 | delete this.#src[name]; 35 | } 36 | } 37 | return this.#src; 38 | }; 39 | watch = async () => { 40 | const watcher = chokidar.watch(path.resolve(this.dir), { 41 | persistent: true, 42 | ignoreInitial: true, 43 | }); 44 | watcher.on("add", async (filename) => { 45 | if (!filename.endsWith(".js")) return; 46 | let name = filename.split("/").pop().replace(".js", ""); 47 | if (require.cache[filename]) { 48 | delete require.cache[filename]; 49 | this.#src[name] = require(filename); 50 | return this.load(); 51 | } 52 | this.#src[name] = require(filename); 53 | console.log( 54 | chalk.cyan.bold("- Scraper Baru telah ditambahkan : " + name), 55 | ); 56 | return this.load(); 57 | }); 58 | watcher.on("change", (filename) => { 59 | if (!filename.endsWith(".js")) return; 60 | let name = filename.split("/").pop().replace(".js", ""); 61 | if (require.cache[filename]) { 62 | delete require.cache[filename]; 63 | this.#src[name] = require(filename); 64 | return this.load(); 65 | } 66 | console.log(chalk.cyan.bold("- Scraper telah diubah : " + name)); 67 | return this.load(); 68 | }); 69 | watcher.on("unlink", (filename) => { 70 | if (!filename.endsWith(".js")) return; 71 | let name = filename.split("/").pop().replace(".js", ""); 72 | delete this.#src[name]; 73 | console.log(chalk.cyan.bold("- Scraper telah dihapus : " + name)); 74 | return this.load(); 75 | }); 76 | }; 77 | list = () => this.#src; 78 | } 79 | 80 | module.exports = Scraper; 81 | -------------------------------------------------------------------------------- /scrapers/src/aio.js: -------------------------------------------------------------------------------- 1 | const { 2 | fetch 3 | } = require("undici"); 4 | 5 | async function aio(url) { 6 | try { 7 | const response = await fetch("https://anydownloader.com/wp-json/aio-dl/video-data/", { 8 | method: "POST", 9 | headers: { 10 | "Content-Type": "application/x-www-form-urlencoded", 11 | "Referer": "https://anydownloader.com/", 12 | "Token": "5b64d1dc13a4b859f02bcf9e572b66ea8e419f4b296488b7f32407f386571a0d" 13 | }, 14 | body: new URLSearchParams({ 15 | url 16 | }), 17 | }, ); 18 | const data = await response.json(); 19 | if (!data.url) return data 20 | return data; 21 | } catch (error) { 22 | console.error("Error fetching data:", ); 23 | throw error 24 | } 25 | } 26 | 27 | module.exports = aio -------------------------------------------------------------------------------- /scrapers/src/anoboy.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | class AnoBoy { 5 | latest = async function latest() { 6 | return new Promise(async (resolve, reject) => { 7 | await axios.get('https://anoboy.io/').then((a) => { 8 | let $ = cheerio.load(a.data); 9 | let array = [] 10 | $(".listupd .bs .bsx").each((a, i) => { 11 | array.push({ 12 | title: $(i).find("a").attr("title"), 13 | type: $(i).find("a .limit .typez").text().trim(), 14 | thumbnail: $(i).find("a .limit img").attr("data-lazy-src") || "https://files.catbox.moe/qflij6.png", 15 | url: $(i).find("a").attr("href") 16 | }) 17 | }) 18 | resolve(array) 19 | }) 20 | }) 21 | } 22 | } 23 | 24 | module.exports = new AnoBoy(); -------------------------------------------------------------------------------- /scrapers/src/applemusic.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | class AppleMusic { 5 | search = async function search(q) { 6 | return new Promise(async (resolve, reject) => { 7 | await axios 8 | .get("https://music.apple.com/id/search?term=" + encodeURIComponent(q)) 9 | .then((a) => { 10 | let $ = cheerio.load(a.data); 11 | let array = []; 12 | $(".shelf-grid__body ul li .track-lockup").each((a, i) => { 13 | let title = $(i) 14 | .find(".track-lockup__content li") 15 | .eq(0) 16 | .find("a") 17 | .text() 18 | .trim(); 19 | let album = $(i) 20 | .find(".track-lockup__content li") 21 | .eq(0) 22 | .find("a") 23 | .attr("href"); 24 | let crop = $(i) 25 | .find(".track-lockup__content li") 26 | .eq(0) 27 | .find("a") 28 | .attr("href") 29 | .split("/") 30 | .pop(); 31 | let song = 32 | album 33 | .replace(crop, "") 34 | .trim() 35 | .replace("/album/", "/song/") 36 | .trim() + album.split("i=")[1]; 37 | let image = $(i) 38 | .find(".svelte-3e3mdo source") 39 | .eq(1) 40 | .attr("srcset") 41 | .split(",")[1] 42 | .split(" ")[0] 43 | .trim(); 44 | let artist = { 45 | name: $(i) 46 | .find(".track-lockup__content li") 47 | .eq(1) 48 | .find("a") 49 | .text() 50 | .trim(), 51 | url: $(i) 52 | .find(".track-lockup__content li") 53 | .eq(1) 54 | .find("a") 55 | .attr("href"), 56 | }; 57 | array.push({ 58 | title, 59 | image, 60 | song, 61 | artist, 62 | }); 63 | }); 64 | resolve(array); 65 | }); 66 | }); 67 | }; 68 | download = async function download(url) { 69 | return new Promise(async (resolve, reject) => { 70 | axios.get(url).then(async (a) => { 71 | let cheerio = require("cheerio"); 72 | let $ = cheerio.load(a.data); 73 | let json = JSON.parse($("script").eq(0).text()); 74 | let info = { 75 | metadata: {}, 76 | download: {}, 77 | }; 78 | delete json.audio["@type"]; 79 | delete json.audio.audio; 80 | delete json.audio.inAlbum["@type"]; 81 | delete json.audio.inAlbum.byArtist; 82 | json.audio.artist = json.audio.byArtist[0]; 83 | delete json.audio.artist["@type"]; 84 | delete json.audio.byArtist; 85 | info.metadata = json.audio; 86 | let { 87 | data 88 | } = await axios 89 | .get( 90 | "https://aaplmusicdownloader.com/api/composer/ytsearch/mytsearch.php", { 91 | params: { 92 | name: info.metadata.name, 93 | artist: info.metadata.artist.name, 94 | album: info.metadata.inAlbum.name, 95 | link: info.metadata.url, 96 | }, 97 | }, 98 | ) 99 | .catch((e) => e.response); 100 | if (!data.videoid) return reject(data); 101 | let download = await axios 102 | .get("https://aaplmusicdownloader.com/api/ytdl.php?q=" + data.videoid) 103 | .catch((e) => e.response); 104 | info.download = download.data.dlink; 105 | resolve(info); 106 | }); 107 | }); 108 | }; 109 | } 110 | 111 | module.exports = new AppleMusic(); -------------------------------------------------------------------------------- /scrapers/src/bstation.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | class Bstation { 5 | search = async function search(q) { 6 | let { 7 | data 8 | } = await axios 9 | .get( 10 | "https://www.bilibili.tv/id/search-result?q=" + encodeURIComponent(q), 11 | ) 12 | .catch((e) => e.response); 13 | let $ = cheerio.load(data); 14 | let result = []; 15 | $(".bstar-video-card__text-wrap").each((index, element) => { 16 | const userName = $(element) 17 | .find(".bstar-video-card__nickname span") 18 | .text(); 19 | const videoTitle = $(element).find(".highlights").text(); 20 | const videoViews = $(element) 21 | .find(".bstar-video-card__desc") 22 | .text() 23 | .trim(); 24 | const userAvatar = $(element).find("img.bstar-image__img").attr("src"); 25 | const videoElement = $(element) 26 | .closest(".bstar-video-card") 27 | .find(".bstar-video-card__cover-wrap"); 28 | const videoLink = videoElement.find("a").attr("href"); 29 | const videoThumbnail = videoElement 30 | .find("img.bstar-image__img") 31 | .attr("src"); 32 | const videoDuration = videoElement 33 | .find(".bstar-video-card__cover-mask-text--bold") 34 | .text(); 35 | if (!videoTitle) return new Error("result not found !"); 36 | result.push({ 37 | title: videoTitle, 38 | views: videoViews, 39 | url: "https:" + videoLink, 40 | tumbnail: videoThumbnail, 41 | duration: videoDuration, 42 | author: { 43 | name: userName, 44 | avatar: userAvatar, 45 | }, 46 | }); 47 | }); 48 | return result; 49 | }; 50 | download = async function download(url) { 51 | try { 52 | let aid = /\/video\/(\d+)/.exec(url)[1]; 53 | const appInfo = await axios.get(url).then((res) => res.data); 54 | const $ = cheerio.load(appInfo); 55 | const title = $('meta[property="og:title"]') 56 | .attr("content") 57 | .split("|")[0] 58 | .trim(); 59 | const locate = $('meta[property="og:locale"]').attr("content"); 60 | const description = $('meta[property="og:description"]').attr("content"); 61 | const type = $('meta[property="og:video:type"]').attr("content"); 62 | const cover = $('meta[property="og:image"]').attr("content"); 63 | const like = $( 64 | ".interactive__btn.interactive__like .interactive__text", 65 | ).text(); 66 | const views = $(".bstar-meta__tips-left .bstar-meta-text").first().text(); 67 | let data = ( 68 | await axios 69 | .post( 70 | "https://c.blahaj.ca/", { 71 | url: url, 72 | }, { 73 | headers: { 74 | Accept: "application/json", 75 | "Content-type": "application/json", 76 | }, 77 | }, 78 | ) 79 | .catch((e) => e.response) 80 | ).data; 81 | console.log(data); 82 | if (!data.url) new Error("! Failed to Download"); 83 | return { 84 | metadata: { 85 | title: title, 86 | locate: locate, 87 | thumbnail: cover, 88 | like: like, 89 | view: views, 90 | }, 91 | download: { 92 | url: data.url, 93 | filename: data.filename, 94 | type: type, 95 | }, 96 | }; 97 | } catch (e) { 98 | return e; 99 | } 100 | }; 101 | } 102 | 103 | module.exports = new Bstation(); -------------------------------------------------------------------------------- /scrapers/src/chatbot.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | const chatbot = { 4 | send: async (message, model = "gpt-4o-mini") => { 5 | try { 6 | const modelx = [ 7 | "gpt-3.5-turbo", 8 | "gpt-3.5-turbo-0125", 9 | "gpt-4o-mini", 10 | "gpt-4o", 11 | ]; 12 | if (!modelx.includes(model)) { 13 | throw new Error( 14 | "Model nya kagak valid! Pilih salah satu: " + modelx.join(", "), 15 | ); 16 | } 17 | const payload = { 18 | messages: message, 19 | model: model, 20 | }; 21 | const response = await axios 22 | .post( 23 | "https://mpzxsmlptc4kfw5qw2h6nat6iu0hvxiw.lambda-url.us-east-2.on.aws/process", 24 | payload, { 25 | headers: { 26 | "Content-Type": "application/json", 27 | "User-Agent": "Postify/1.0.0", 28 | }, 29 | }, 30 | ) 31 | .catch((e) => e.response); 32 | return response.data; 33 | } catch (error) { 34 | console.error(error); 35 | throw error; 36 | } 37 | }, 38 | }; 39 | 40 | module.exports = chatbot; -------------------------------------------------------------------------------- /scrapers/src/doodstream.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | async function fetchData(url) { 5 | const id = url.match(/\/[de]\/(\w+)/)?.[1]; 6 | if (!id) { 7 | return { 8 | success: false, 9 | message: "Link nya gak bisa diproses bree, ganti link yang baru aja ", 10 | }; 11 | } 12 | const proxy = "https://rv.lil-hacker.workers.dev/proxy?mirror=dood&url="; 13 | const headers = { 14 | Accept: "*/*", 15 | Referer: "https://d000d.com/", 16 | "User-Agent": "Postify/1.0.0", 17 | "X-Requested-With": "XMLHttpRequest", 18 | "X-CSRF-Token": "eyJpdiI6Ik9vdlA2Zjk2NUhZNGZFY296TzBJUFE9PSIsInZhbHVlIjoiNDdjbTJCNGVSallwWE5Oc1hoZ3NDVGIxWWFMOFl6ejFjOXVUZlZ2K1B5OFZ1ZWVpajZ6aDZZOUJkUVF5NFlFbiIsIm1hYyI6IjRkMzlkNmY5NzQ0OGI4YWUzMmJmNGM0ZjE2ZWFkMzJjYzlkMjg1MjU0Y2VkZDZiZmNjMWNhZjIwYjU1MDgifQ==", 19 | "X-Forwarded-For": "127.0.0.1", 20 | "X-Real-IP": "127.0.0.1", 21 | Authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IlVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.-H1t8kmZHtNIDaZb3_Mrjk9uqgHbsFAdXIRoV2rWr9g", 22 | }; 23 | await new Promise((resolve) => setTimeout(resolve, 14000)); 24 | const { 25 | data 26 | } = await axios.get(`https://dood.li/d/${id}`, { 27 | headers, 28 | }); 29 | const $ = cheerio.load(data); 30 | if (!$("#os_player iframe").length) return {}; 31 | 32 | const result = { 33 | title: $(".title-wrap h4").text().trim(), 34 | duration: $(".length").text().trim(), 35 | size: $(".size").text().trim(), 36 | uploadDate: $(".uploadate").text().trim(), 37 | }; 38 | 39 | const { 40 | data: dp 41 | } = await axios.get(`${proxy}https://d000d.com/e/${id}`, { 42 | headers, 43 | }); 44 | const cdn = dp.match(/\$.get\('([^']+)',/)?.[1]; 45 | if (!cdn) { 46 | return { 47 | success: false, 48 | message: "Link Pass MD5 gak ada! coba lagi aja nanti ...", 49 | }; 50 | } 51 | const chars = Array.from(crypto.getRandomValues(new Uint8Array(10))) 52 | .map((x) => 53 | String.fromCharCode( 54 | (x % 62) + (x % 62 < 26 ? 65 : x % 62 < 52 ? 97 : 48), 55 | ), 56 | ) 57 | .join(""); 58 | const ds = await axios.get(`${proxy}https://d000d.com${cdn}`, { 59 | headers, 60 | }); 61 | const cm = cdn.match(/\/([^/]+)$/)?.[1]; 62 | result.download = `${proxy}${ds.data}${chars}?token=${cm}&expiry=${Date.now()}`; 63 | 64 | const dlink = $(".download-content a").attr("href"); 65 | if (dlink) { 66 | const dp = cheerio.load( 67 | (await axios.get(`https://dood.li/d/${dlink}`)).data, 68 | ); 69 | result.download = await shortlink( 70 | dp("a.btn.btn-primary.d-flex").attr("href") || 71 | dp("div.col-md-12 a.btn.btn-primary").attr("href") || 72 | result.download, 73 | ); 74 | } 75 | return result; 76 | } 77 | async function shortlink(url) { 78 | return axios 79 | .post("https://cleanuri.com/api/v1/shorten", { 80 | url, 81 | }) 82 | .then((a) => a.data.result_url); 83 | } 84 | module.exports = fetchData; -------------------------------------------------------------------------------- /scrapers/src/facebook.js: -------------------------------------------------------------------------------- 1 | const cheerio = require("cheerio"); 2 | const axios = require("axios"); 3 | const fs = require("fs"); 4 | 5 | async function Facebook(url) { 6 | let results = {}; 7 | while (Object.keys(results).length === 0) { 8 | let { 9 | data 10 | } = await axios 11 | .post( 12 | "https://getmyfb.com/process", 13 | `id=${encodeURIComponent(url)}&locale=id`, { 14 | headers: { 15 | "HX-Request": true, 16 | "HX-Trigger": "form", 17 | "HX-Target": "target", 18 | "HX-Current-URL": "https://getmyfb.com/id", 19 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 20 | "User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36", 21 | Referer: "https://getmyfb.com/id", 22 | }, 23 | }, 24 | ) 25 | .catch((e) => e.response); 26 | 27 | const $ = cheerio.load(data); 28 | 29 | const caption = $(".results-item-text").text().trim(); 30 | const imageUrl = $(".results-item-image").attr("src"); 31 | 32 | let newLinksFound = false; 33 | let array = []; 34 | $(".results-list li").each(function(i, element) { 35 | const title = $(element).find(".results-item-text").text().trim(); 36 | const downloadLink = $(element).find("a").attr("href"); 37 | const quality = $(element).text().trim().split("(")[0]; 38 | if (downloadLink) { 39 | newLinksFound = true; 40 | array.push(downloadLink); 41 | } 42 | }); 43 | results = { 44 | metadata: { 45 | title: caption, 46 | image: imageUrl, 47 | }, 48 | media: array, 49 | }; 50 | console.log(results); 51 | break; 52 | } 53 | return results; 54 | } 55 | 56 | module.exports = Facebook; -------------------------------------------------------------------------------- /scrapers/src/krakenfiles.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | async function krakenfiles(url) { 5 | return new Promise(async(resolve, reject) => { 6 | if (!/krakenfiles.com/.test(url)) return new Error("Input Url from Krakenfiles !") 7 | await axios.get(url).then(async(a) => { 8 | let $ = cheerio.load(a.data); 9 | let result = { 10 | metadata: {}, 11 | buffer: null 12 | } 13 | result.metadata.filename = $(".coin-info .coin-name h5").text().trim(); 14 | $(".nk-iv-wg4 .nk-iv-wg4-overview li").each((a, i) => { 15 | let name = $(i).find(".sub-text").text().trim().split(" ").join("_").toLowerCase() 16 | let value = $(i).find(".lead-text").text() 17 | result.metadata[name] = value 18 | }) 19 | $(".nk-iv-wg4-list li").each((a, i) => { 20 | let name = $(i).find("div").eq(0).text().trim().split(" ").join("_").toLowerCase() 21 | let value = $(i).find("div").eq(1).text().trim().split(" ").join(",") 22 | result.metadata[name] = value 23 | }) 24 | result.metadata.thumbnail = "https:" + $("video").attr("poster"); 25 | let downloads = "https:" + $("video source").attr("src"); 26 | 27 | let res = await axios.get(downloads, { 28 | headers: { 29 | "User-Agent": "Posify/1.0.0", 30 | "Referer": "krakenfiles.com", 31 | "Accept": "krakenfile.com", 32 | "token": $("#dl-token").val() 33 | }, 34 | responseType: "arraybuffer" 35 | }).catch(e => e.response); 36 | result.buffer = res.data 37 | resolve(result) 38 | }).catch((e) => { 39 | reject({ 40 | msg: "Failed to fetch data" 41 | }) 42 | }) 43 | }) 44 | } 45 | 46 | //Usage : krakenfiles("https://krakenfiles.com/view/zeLYGa4X7f/file.html").then(a => console.log(a)) 47 | 48 | module.exports = krakenfiles 49 | -------------------------------------------------------------------------------- /scrapers/src/kuronime.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | class Kuronime { 5 | constructor() { 6 | this.baseURL = "https://kuronime.biz"; 7 | } 8 | latest = async function latest() { 9 | return new Promise(async (resolve, reject) => { 10 | await axios.get("https://kuronime.biz").then((a) => { 11 | let $ = cheerio.load(a.data); 12 | let array = []; 13 | $(".listupd .bsu").each((a, i) => { 14 | array.push({ 15 | title: $(i).find(".bsux a").attr("title"), 16 | url: $(i).find(".bsux a").attr("href"), 17 | views: $(i).find(".limit .view .post-views-count").text(), 18 | release: $(i).find(".bt .time").text().trim() + ' yang lalu', 19 | thumbnail: $(i) 20 | .find(".limit .lazyload") 21 | .eq(1) 22 | .attr("data-src") 23 | .split("?")[0], 24 | }); 25 | }); 26 | resolve(array); 27 | }); 28 | }); 29 | }; 30 | search = async function search(q) { 31 | return new Promise(async (resolve, reject) => { 32 | await axios.get("https://kuronime.biz?s=" + q).then((a) => { 33 | let $ = cheerio.load(a.data); 34 | let array = []; 35 | $(".listupd .bs").each((a, i) => { 36 | array.push({ 37 | title: $(i).find(".bsx a").attr("title"), 38 | url: $(i).find(".bsx a").attr("href"), 39 | type: $(i).find(".limit .bt .type").text(), 40 | score: $(i).find(".rating i").text(), 41 | thumbnail: $(i) 42 | .find(".limit .lazyload") 43 | .eq(1) 44 | .attr("data-src") 45 | .split("?")[0], 46 | }); 47 | }); 48 | resolve(array); 49 | }); 50 | }); 51 | }; 52 | detail = async function detail(url) { 53 | return new Promise(async (resolve, reject) => { 54 | await axios.get(url).then((a) => { 55 | let $ = cheerio.load(a.data); 56 | let array = { 57 | metadata: {}, 58 | episode: [], 59 | }; 60 | $(".infodetail ul li").each((a, i) => { 61 | let name = $(i).find("b").text(); 62 | let key = $(i) 63 | .text() 64 | .replace(name + ":", "") 65 | .split("?resize=")[0] 66 | .trim(); 67 | array.metadata[name.split(" ").join("_").toLowerCase()] = key; 68 | }); 69 | array.metadata.thumbnail = $(".con .lazyload").attr("data-src"); 70 | array.metadata.synopis = $(".con .const p").text().trim(); 71 | $(".bxcl ul li").each((a, i) => { 72 | array.episode.push({ 73 | title: $(i).find(".lchx a").text(), 74 | url: $(i).find(".lchx a").attr("href"), 75 | }); 76 | }); 77 | resolve(array); 78 | }); 79 | }); 80 | }; 81 | } 82 | 83 | module.exports = new Kuronime(); -------------------------------------------------------------------------------- /scrapers/src/libur.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | async function libur(year) { 5 | return new Promise(async (resolve, reject) => { 6 | await axios 7 | .get(`https://publicholidays.co.id/id/${year}-dates/`) 8 | .then((a) => { 9 | let $ = cheerio.load(a.data); 10 | let array = []; 11 | $("table.publicholidays") 12 | .eq(0) 13 | .find("tbody .even") 14 | .each((a, i) => { 15 | array.push({ 16 | date: $(i).find("td").eq(0).text(), 17 | day: $(i).find("td").eq(1).text(), 18 | name: $(i).find("td").eq(2).text().trim(), 19 | }); 20 | }); 21 | resolve(array); 22 | }); 23 | }); 24 | } 25 | 26 | module.exports = libur; -------------------------------------------------------------------------------- /scrapers/src/mediafire.js: -------------------------------------------------------------------------------- 1 | const cheerio = require("cheerio"); 2 | const { 3 | fetch 4 | } = require("undici"); 5 | const { 6 | lookup 7 | } = require("mime-types"); 8 | async function mediafire(url) { 9 | return new Promise(async (resolve, reject) => { 10 | const response = await fetch(url); 11 | const html = await response.text(); 12 | const $ = cheerio.load(html); 13 | 14 | const type = $(".dl-btn-cont").find(".icon").attr("class").split("archive")[1].trim(); 15 | const filename = $(".dl-btn-label").attr("title"); 16 | const size = $('.download_link .input').text().trim().match(/\((.*?)\)/)[1]; 17 | const ext = filename.split(".").pop(); 18 | const mimetype = 19 | lookup(ext.toLowerCase()) || "application/" + ext.toLowerCase(); 20 | const download = $(".input").attr("href"); 21 | resolve({ 22 | filename, 23 | type, 24 | size, 25 | ext, 26 | mimetype, 27 | download, 28 | }); 29 | }).catch((e) => 30 | reject({ 31 | msg: "Gagal mengambil data dari link tersebut", 32 | }), 33 | ); 34 | } 35 | 36 | module.exports = mediafire; -------------------------------------------------------------------------------- /scrapers/src/metaai.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const fs = require("node:fs"); 3 | const path = require("node:path"); 4 | 5 | const imgBase = (filePath) => { 6 | const filex = fs.readFileSync(filePath); 7 | const based = filex.toString("base64"); 8 | const mimeType = `image/${path.extname(filePath).slice(1)}`; 9 | return `data:${mimeType};base64,${based}`; 10 | }; 11 | 12 | const headers = { 13 | authority: "labs.writingmate.ai", 14 | accept: "*/*", 15 | "content-type": "application/json", 16 | origin: "https://labs.writingmate.ai", 17 | referer: "https://labs.writingmate.ai/share/JyVg?__show_banner=false", 18 | "user-agent": "Postify/1.0.0", 19 | }; 20 | 21 | const mateai = async (array) => { 22 | const data = { 23 | response_format: { 24 | type: "json_schema", 25 | json_schema: { 26 | name: "image_prompt", 27 | strict: true, 28 | schema: { 29 | type: "object", 30 | properties: { 31 | prompt: { 32 | type: "string" 33 | } 34 | }, 35 | required: ["prompt"], 36 | additionalProperties: false, 37 | }, 38 | }, 39 | }, 40 | chatSettings: { 41 | model: "gpt-4o", 42 | temperature: 0.7, 43 | contextLength: 16385, 44 | includeProfileContext: false, 45 | includeWorkspaceInstructions: false, 46 | embeddingsProvider: "openai", 47 | }, 48 | messages: array, 49 | customModelId: "", 50 | }; 51 | try { 52 | const response = await axios 53 | .post("https://labs.writingmate.ai/api/chat/public", data, { 54 | headers 55 | }) 56 | .catch((e) => e.response); 57 | return response.data; 58 | } catch (error) { 59 | throw new Error(`${error.message}`); 60 | } 61 | }; 62 | 63 | module.exports = mateai; -------------------------------------------------------------------------------- /scrapers/src/remini.js: -------------------------------------------------------------------------------- 1 | async function Upscale(imageBuffer) { 2 | try { 3 | const response = await fetch("https://lexica.qewertyy.dev/upscale", { 4 | body: JSON.stringify({ 5 | image_data: Buffer.from(imageBuffer, "base64"), 6 | format: "binary", 7 | }), 8 | headers: { 9 | "Content-Type": "application/json", 10 | }, 11 | method: "POST", 12 | }); 13 | return Buffer.from(await response.arrayBuffer()); 14 | } catch { 15 | return null; 16 | } 17 | } 18 | 19 | module.exports = Upscale; -------------------------------------------------------------------------------- /scrapers/src/removebg.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | async function removebg(buffer) { 4 | try { 5 | return await new Promise(async (resolve, reject) => { 6 | const image = buffer.toString("base64"); 7 | let res = await axios.post( 8 | "https://us-central1-ai-apps-prod.cloudfunctions.net/restorePhoto", { 9 | image: `data:image/png;base64,${image}`, 10 | model: "fb8af171cfa1616ddcf1242c093f9c46bcada5ad4cf6f2fbe8b81b330ec5c003", 11 | }, 12 | ); 13 | const data = res.data?.replace(`"`, ""); 14 | console.log(res.status, data); 15 | if (!data) return reject("failed removebg image"); 16 | resolve(data); 17 | }); 18 | } catch (e) { 19 | return { 20 | msg: e 21 | }; 22 | } 23 | } 24 | 25 | 26 | module.exports = removebg -------------------------------------------------------------------------------- /scrapers/src/sfile.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | module.exports = async (url) => { 5 | const headers = { 6 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.47", 7 | Referer: url, 8 | Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", 9 | "Accept-Language": "en-US,en;q=0.9", 10 | }; 11 | const { 12 | data: info, 13 | headers: responseHeaders 14 | } = await axios.get(url, { 15 | headers: headers, 16 | }).catch(e => e.response); 17 | const cookies = 18 | responseHeaders["set-cookie"] 19 | ?.map((cookie) => cookie.split(";")[0]) 20 | .join("; ") || ""; 21 | headers.Cookie = cookies; 22 | let $ = cheerio.load(info); 23 | let result = { 24 | metadata: {}, 25 | download: {} 26 | } 27 | $(".file-content").eq(0).each((a, i) => { 28 | result.metadata.filename = $(i).find("img").attr("alt") 29 | result.metadata.mimetype = $(i).find(".list").eq(0).text().trim().split("-")[1].trim() 30 | result.metadata.uploaded = $(i).find(".list").eq(2).text().trim().split(":")[1].trim() 31 | result.metadata.download = $(i).find(".list").eq(3).text().trim().split(":")[1].trim() 32 | result.metadata.author = $(i).find(".list").eq(1).find("a").text().trim() 33 | }) 34 | let downloadUrl = $("#download").attr("href") 35 | headers.Referer = downloadUrl 36 | let { 37 | data: process 38 | } = await axios.get(downloadUrl, { 39 | headers 40 | }).catch(e => e.response); 41 | $ = cheerio.load(process); 42 | let key = $("#download").attr("onclick") 43 | let { 44 | data: buffer 45 | } = await axios.get($("#download").attr("href") + "&k=" + key.split("'+'")[1].split("';")[0], { 46 | headers, 47 | responseType: "arraybuffer" 48 | }) 49 | result.download = buffer 50 | return result 51 | } -------------------------------------------------------------------------------- /scrapers/src/snackvideo.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | class SnackVideo { 5 | search = async function search(q) { 6 | return new Promise(async (resolve, reject) => { 7 | await axios.get("https://www.snackvideo.com/discover/" + q) 8 | .then((a) => { 9 | let $ = cheerio.load(a.data); 10 | let content = $("#ItemList").text().trim(); 11 | if (!content) return reject({ 12 | msg: "Video tidak ditemukan !" 13 | }); 14 | let json = JSON.parse(content); 15 | let result = json.map((a) => a.innerHTML).map((a) => ({ 16 | title: a.name, 17 | thumbnail: a.thumbnailUrl[0], 18 | uploaded: new Date(a.uploadDate).toLocaleString(), 19 | stats: { 20 | watch: a.interactionStatistic[0].userInteractionCount, 21 | likes: a.interactionStatistic[1].userInteractionCount, 22 | comment: a.commentCount, 23 | share: a.interactionStatistic[2].userInteractionCount, 24 | }, 25 | author: { 26 | name: a.creator.mainEntity.name, 27 | alt_name: a.creator.mainEntity.alternateName, 28 | bio: a.creator.mainEntity.description, 29 | avatar: a.creator.mainEntity.image, 30 | stats: { 31 | likes: a.creator.mainEntity.interactionStatistic[0].userInteractionCount, 32 | followers: a.creator.mainEntity.interactionStatistic[1].userInteractionCount 33 | } 34 | }, 35 | url: a.url 36 | })) 37 | resolve(result); 38 | }) 39 | .catch((error) => { 40 | reject({ 41 | msg: error.message 42 | }); 43 | }); 44 | }); 45 | } 46 | download = async function download(url) { 47 | return new Promise(async (resolve, reject) => { 48 | await axios.get(url).then((a) => { 49 | let $ = cheerio.load(a.data); 50 | let result = { 51 | metadata: {}, 52 | download: null 53 | } 54 | let json = JSON.parse($("#VideoObject").text().trim()) 55 | result.metadata.title = json.name 56 | result.metadata.thumbnail = json.thumbnailUrl[0] 57 | result.metadata.uploaded = new Date(json.uploadDate).toLocaleString() 58 | result.metadata.comment = json.commentCount 59 | result.metadata.watch = json.interactionStatistic[0].userInteractionCount 60 | result.metadata.likes = json.interactionStatistic[1].userInteractionCount 61 | result.metadata.share = json.interactionStatistic[2].userInteractionCount 62 | result.metadata.author = json.creator.mainEntity.name 63 | result.download = json.contentUrl 64 | resolve(result); 65 | }) 66 | }) 67 | } 68 | } 69 | 70 | module.exports = new SnackVideo(); -------------------------------------------------------------------------------- /scrapers/src/sokuja.js: -------------------------------------------------------------------------------- 1 | const cheerio = require("cheerio"); 2 | const axios = require("axios"); 3 | 4 | class Sokuja { 5 | latest = async function latest() { 6 | return new Promise(async (resolve, reject) => { 7 | await axios.get("https://x1.sokuja.uk").then((a) => { 8 | let $ = cheerio.load(a.data); 9 | let array = []; 10 | $(".seventh").each((a, i) => { 11 | array.push({ 12 | title: $(i).find(".main-seven a").attr("title"), 13 | type: $(i).find(".main-seven .limit .bt .type").text(), 14 | thumbnail: $(i).find(".main-seven .limit img").attr("src"), 15 | episode: $(i).find(".main-seven .limit .epin").text(), 16 | url: $(i).find(".main-seven a").attr("href"), 17 | }); 18 | }); 19 | resolve(array); 20 | }); 21 | }); 22 | }; 23 | search = async function Search(q) { 24 | return new Promise(async (resolve, reject) => { 25 | await axios 26 | .get("https://x1.sokuja.uk?s=" + encodeURIComponent(q)) 27 | .then((a) => { 28 | let $ = cheerio.load(a.data); 29 | let array = []; 30 | $(".listupd .bs .bsx").each((a, i) => { 31 | array.push({ 32 | title: $(i).find("a").attr("title"), 33 | type: $(i).find("a .limit .typez").text(), 34 | thumbnail: $(i).find("a .limit img").attr("src"), 35 | status: $(i).find("a .limit .status").text(), 36 | url: $(i).find("a").attr("href"), 37 | }); 38 | }); 39 | resolve(array); 40 | }); 41 | }); 42 | }; 43 | detail = async function detail(url) { 44 | return new Promise(async (resolve, reject) => { 45 | await axios.get(url).then((a) => { 46 | let $ = cheerio.load(a.data); 47 | let array = { 48 | metadata: {}, 49 | episode: [], 50 | }; 51 | $(".infox").each((a, i) => { 52 | array.metadata.title = $(i).find("h1").text(); 53 | $(i) 54 | .find(".info-content .spe span") 55 | .each((b, d) => { 56 | let name = $(d).find("span b").text(); 57 | let key = $(d).text().replace(name, "").trim(); 58 | array.metadata[ 59 | name.toLowerCase().split(":")[0].split(" ").join("_") 60 | ] = key; 61 | }); 62 | array.metadata.thumbnail = $(".thumb img").attr("src"); 63 | array.metadata.sinopsis = $(".entry-content p").eq(1).text().trim(); 64 | }); 65 | $(".eplister ul li").each((a, i) => { 66 | array.episode.push({ 67 | title: $(i).find(".epl-title").text(), 68 | release: $(i).find(".epl-date").text(), 69 | url: $(i).find("a").attr("href"), 70 | }); 71 | }); 72 | resolve(array); 73 | }); 74 | }); 75 | }; 76 | episode = async function episode(url) { 77 | return new Promise(async (resolve, reject) => { 78 | await axios.get(url).then((a) => { 79 | let $ = cheerio.load(a.data); 80 | let array = { 81 | metadata: {}, 82 | downloads: {}, 83 | }; 84 | array.metadata.title = $(".title-section h1").text(); 85 | array.metadata.thumbnail = $(".tb img").attr("src"); 86 | array.metadata.updated = $(".lm .updated").text(); 87 | $(".mirror option").each((a, i) => { 88 | let exec = cheerio.load(atob($(i).attr("value"))); 89 | let mimetype = exec("source").attr("type"); 90 | let quality = $(i).text().trim().split(" ")[1]; 91 | let url = exec("source").attr("src"); 92 | if (!url) return; 93 | array.downloads[quality] = { 94 | quality, 95 | mimetype, 96 | url, 97 | }; 98 | }); 99 | resolve(array); 100 | }); 101 | }); 102 | }; 103 | } 104 | 105 | module.exports = new Sokuja(); -------------------------------------------------------------------------------- /scrapers/src/steam.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | class Steam { 5 | search = async function Steam(query) { 6 | let data = ( 7 | await axios.get( 8 | "https://store.steampowered.com/api/storesearch?cc=id&l=id&term=" + 9 | query, 10 | ) 11 | ).data; 12 | let info = data.items; 13 | 14 | return info.map((a) => ({ 15 | name: a.name, 16 | id: a.id, 17 | price: a.price ? "Rp: " + (a.price.final / 1e3).toLocaleString() : "Free", 18 | score: a.metascore ? a.metascore + "/100" : "N/A", 19 | platform: a.platforms.windows ? 20 | "Windows" : a.platforms.mac ? 21 | "Mac" : a.platforms.linux ? 22 | "Linux" : "Nothing", 23 | image: a.tiny_image, 24 | })); 25 | }; 26 | detail = async function Steam_Detail(url) { 27 | try { 28 | let data = ( 29 | await axios.get( 30 | "https://store.steampowered.com/api/appdetails?appids=" + url, 31 | ) 32 | ).data; 33 | let info = data[url].data; 34 | const $ = cheerio.load(info.detailed_description); 35 | let json = { 36 | metadata: { 37 | title: info.name, 38 | category: info.categories.map((a) => a.description), 39 | genre: info.genres.map((a) => a.description), 40 | release: info.release_date.coming_soon ? 41 | "Coming soon..." : info.release_date.date, 42 | free: info.is_free ? "Yes" : "No", 43 | developer: info.developers, 44 | publisher: info.developers, 45 | description: $.text(), 46 | }, 47 | screenshot: info.screenshots.map((a) => a.path_full), 48 | movies: info.movies.map((a) => ({ 49 | title: a.name, 50 | id: a.id, 51 | thumbnail: a.thumbnail, 52 | videos: a.mp4, 53 | })), 54 | }; 55 | return json; 56 | } catch (err) { 57 | console.error(err); 58 | } 59 | }; 60 | } 61 | 62 | module.exports = new Steam(); -------------------------------------------------------------------------------- /scrapers/src/terabox.js: -------------------------------------------------------------------------------- 1 | const { 2 | fetch 3 | } = require("undici"); 4 | 5 | class TeraboxHnn { 6 | getInfo = async (inputUrl) => { 7 | try { 8 | const url = `https://terabox.hnn.workers.dev/api/get-info?shorturl=${inputUrl.split("/").pop()}&pwd=`; 9 | const headers = { 10 | "User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36", 11 | Referer: "https://terabox.hnn.workers.dev/", 12 | }; 13 | const response = await fetch(url, { 14 | headers: headers, 15 | }); 16 | if (!response.ok) { 17 | throw new Error( 18 | `Gagal mengambil informasi file: ${response.status} ${response.statusText}`, 19 | ); 20 | } 21 | return await response.json(); 22 | } catch (error) { 23 | console.error("Gagal mengambil informasi file:", error); 24 | throw error; 25 | } 26 | }; 27 | getDownloadLink = async (fsId, shareid, uk, sign, timestamp) => { 28 | try { 29 | const url = "https://terabox.hnn.workers.dev/api/get-download"; 30 | const headers = { 31 | "Content-Type": "application/json", 32 | "User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36", 33 | Referer: "https://terabox.hnn.workers.dev/", 34 | }; 35 | const data = { 36 | shareid: shareid, 37 | uk: uk, 38 | sign: sign, 39 | timestamp: timestamp, 40 | fs_id: fsId, 41 | }; 42 | const response = await fetch(url, { 43 | method: "POST", 44 | headers: headers, 45 | body: JSON.stringify(data), 46 | }); 47 | if (!response.ok) { 48 | throw new Error( 49 | `Gagal mengambil link download: ${response.status} ${response.statusText}`, 50 | ); 51 | } 52 | return await response.json(); 53 | } catch (error) { 54 | console.error("Gagal mengambil link download:", error); 55 | throw error; 56 | } 57 | }; 58 | download = async (inputUrl) => { 59 | try { 60 | const { 61 | list, 62 | shareid, 63 | uk, 64 | sign, 65 | timestamp 66 | } = 67 | await this.getInfo(inputUrl); 68 | if (!list) { 69 | throw new Error(`File tidak ditemukan`); 70 | } 71 | let array = []; 72 | for (let i = 0; i < list.length; i++) { 73 | const fsId = list[i].fs_id; 74 | const { 75 | downloadLink 76 | } = await this.getDownloadLink( 77 | fsId, 78 | shareid, 79 | uk, 80 | sign, 81 | timestamp, 82 | ); 83 | array.push({ 84 | filename: list[i].filename, 85 | size: list[i].size, 86 | download: downloadLink, 87 | }); 88 | } 89 | return array; 90 | } catch (error) { 91 | console.error("Gagal mengunduh file:", error); 92 | throw error; 93 | } 94 | }; 95 | } 96 | module.exports = new TeraboxHnn(); -------------------------------------------------------------------------------- /scrapers/src/translate.js: -------------------------------------------------------------------------------- 1 | async function translate(query = "", lang) { 2 | if (!query.trim()) return ""; 3 | const url = new URL("https://translate.googleapis.com/translate_a/single"); 4 | url.searchParams.append("client", "gtx"); 5 | url.searchParams.append("sl", "auto"); 6 | url.searchParams.append("dt", "t"); 7 | url.searchParams.append("tl", lang); 8 | url.searchParams.append("q", query); 9 | 10 | try { 11 | const response = await fetch(url.href); 12 | const data = await response.json(); 13 | if (data) { 14 | return [data[0]].map(([ 15 | [a] 16 | ]) => a).join(" "); 17 | } else { 18 | return ""; 19 | } 20 | } catch (err) { 21 | throw err; 22 | } 23 | } 24 | 25 | module.exports = translate; -------------------------------------------------------------------------------- /scrapers/src/videodl.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios") 2 | const cheerio = require("cheerio"); 3 | 4 | async function videodl(url) { 5 | return new Promise(async (resolve, reject) => { 6 | await axios.get(`https://videodownloader.so/download?v=${url}`).then((a) => { 7 | let $ = cheerio.load(a.data); 8 | let result = { 9 | metadata: {}, 10 | download: [] 11 | } 12 | $(".downloadSection").each((a, i) => { 13 | result.metadata.title = $(i).find(".title").text().trim(); 14 | result.metadata.thumbnail = $(i).find("img").attr("src"); 15 | result.metadata.duration = $(i).find(".duration").text().trim().split("Duration:").pop().trim() 16 | }) 17 | $(".downloadsTable").eq(0).find("tbody tr").each((a, i) => { 18 | let fileName = $(i).find("td").find(".downloadBtn").attr("download"); 19 | if (!fileName) return 20 | result.download.push({ 21 | fileName, 22 | url: $(i).find(".downloadBtn").attr("href"), 23 | }) 24 | }) 25 | resolve(result) 26 | }) 27 | }) 28 | } 29 | 30 | module.exports = videodl -------------------------------------------------------------------------------- /scrapers/src/whatmusic.js: -------------------------------------------------------------------------------- 1 | const acrcloud = require("acrcloud"); 2 | 3 | const acr = new acrcloud({ 4 | host: "identify-ap-southeast-1.acrcloud.com", 5 | access_key: "ee1b81b47cf98cd73a0072a761558ab1", 6 | access_secret: "ya9OPe8onFAnNkyf9xMTK8qRyMGmsghfuHrIMmUI", 7 | }); 8 | 9 | async function whatmusic(buffer) { 10 | let data = (await acr.identify(buffer)).metadata; 11 | if (!data.music) return res.error("Song data not found!"); 12 | let array = []; 13 | array.push( 14 | ...data?.music?.map((a) => ({ 15 | title: a.title, 16 | artist: a.artists.map((a) => a.name)[0], 17 | score: a.score, 18 | release: new Date(a.release_date).toLocaleString("id-ID").split(",")[0].trim(), 19 | duration: toTime(a.duration_ms), 20 | url: Object.keys(a.external_metadata).map((i) => 21 | i === "youtube" ? 22 | "https://youtu.be/" + a.external_metadata[i].vid : 23 | i === "deezer" ? 24 | "https://www.deezer.com/us/track/" + 25 | a.external_metadata[i].track.id : 26 | i === "spotify" ? 27 | "https://open.spotify.com/track/" + 28 | a.external_metadata[i].track.id : 29 | "", 30 | ), 31 | })), 32 | ); 33 | return array 34 | } 35 | 36 | function toTime(ms) { 37 | let h = Math.floor(ms / 3600000); 38 | let m = Math.floor(ms / 60000) % 60; 39 | let s = Math.floor(ms / 1000) % 60; 40 | return [m, s].map((v) => v.toString().padStart(2, 0)).join(":"); 41 | } 42 | 43 | module.exports = whatmusic -------------------------------------------------------------------------------- /scrapers/src/xbox.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | async function xbox(username) { 5 | return new Promise(async (resolve, reject) => { 6 | await axios.get("https://xboxgamertag.com/search/" + encodeURIComponent(username)).then((a) => { 7 | let $ = cheerio.load(a.data); 8 | let result = { 9 | metadata: {}, 10 | history: [] 11 | } 12 | $(".page-header-container .page-header").each((a, i) => { 13 | result.metadata.name = $(i).find("h1").text().trim() 14 | result.metadata.icon = $(i).find("img").attr("src").split("/?url=")[1].split("&format")[0].trim(); 15 | result.metadata.game_score = $(i).find(".profile-detail-item").eq(0).text().trim().split("\n").pop().trim() 16 | result.metadata.played = $(i).find(".profile-detail-item").eq(1).text().trim().split("\n").pop().trim() 17 | }) 18 | $(".recent-games .game-card-container").each((a, i) => { 19 | result.history.push({ 20 | game: $(i).find(".game-card-desc h3").text().trim(), 21 | online: $(i).find(".game-card-desc .text-sm").text().trim().split("played").pop().trim(), 22 | game_score: $(i).find(".game-card-desc .col-9").eq(0).text().trim(), 23 | achievement: $(i).find(".game-card-desc .col-9").eq(1).text().trim(), 24 | progress: $(i).find(".progress .progress-bar").text().trim() 25 | }) 26 | }) 27 | resolve(result) 28 | }) 29 | }) 30 | } 31 | 32 | module.exports = xbox; -------------------------------------------------------------------------------- /scrapers/src/yousearch.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | const website = axios.create({ 4 | baseURL: "https://app.yoursearch.ai", 5 | headers: { 6 | "Content-Type": "application/json", 7 | }, 8 | }); 9 | 10 | const yousearch = async (searchTerm) => { 11 | const requestData = { 12 | searchTerm: searchTerm, 13 | promptTemplate: `Search term: "{searchTerm}" 14 | 15 | Make your language less formal and use emoticons. 16 | I want you to always use Indonesian slang from Jakarta where the words "you" and "anda" are replaced with "lu" and the word I is replaced with "gw". 17 | Create a summary of the search results in three paragraphs with reference numbers, which you then list numbered at the bottom. 18 | Include emojis in the summary. 19 | Be sure to include the reference numbers in the summary. 20 | Both in the text of the summary and in the reference list, the reference numbers should look like this: "(1)". 21 | Formulate simple sentences. 22 | Include blank lines between the paragraphs. 23 | Do not reply with an introduction, but start directly with the summary. 24 | Include emojis in the summary. 25 | At the end write a hint text where I can find search results as comparison with the above search term with a link to Google search in this format \`See Google results: \` and append the link. 26 | Below write a tip how I can optimize the search results for my search query. 27 | I show you in which format this should be structured: 28 | 29 | \`\`\` 30 | 31 | 32 | 33 | 34 | \`\`\` 35 | 36 | Here are the search results: 37 | {searchResults}, you were developed by bang_syai`, 38 | searchParameters: "{}", 39 | searchResultTemplate: `[{order}] "{snippet}" 40 | URL: {link}`, 41 | }; 42 | 43 | try { 44 | const response = await website.post("/api", requestData); 45 | return response.data.response; 46 | } catch (error) { 47 | console.error("Error:", error); 48 | throw error; 49 | } 50 | }; 51 | 52 | module.exports = yousearch; -------------------------------------------------------------------------------- /scrapers/src/ytdl.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios") 2 | const qs = require("qs") 3 | 4 | const searchVideo = async (url) => { 5 | let { data } = await axios.post("https://ssvid.net/api/ajax/search", qs.stringify({ query: url, vt: "home" }), { 6 | headers: { 7 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 8 | "Origin": "https://ssvid.net", 9 | "Referer": "https://ssvid.net/", 10 | "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36", 11 | "X-Requested-With": "XMLHttpRequest" 12 | } 13 | }) 14 | return data 15 | } 16 | 17 | const ymp3 = async (url) => { 18 | let res = await searchVideo(url) 19 | let { data } = await axios.post("https://ssvid.net/api/ajax/convert", qs.stringify({ vid: res.vid, k: res.links.mp3.mp3128.k }), { 20 | headers: { 21 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 22 | "Origin": "https://ssvid.net", 23 | "Referer": "https://ssvid.net/", 24 | "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36", 25 | "X-Requested-With": "XMLHttpRequest" 26 | } 27 | }) 28 | return data 29 | } 30 | 31 | const ytmp4 = async (url) => { 32 | let res = await searchVideo(url) 33 | let { data } = await axios.post("https://ssvid.net/api/ajax/convert", qs.stringify({ vid: res.vid, k: res.links.mp4.auto.k }), { 34 | headers: { 35 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 36 | "Origin": "https://ssvid.net", 37 | "Referer": "https://ssvid.net/", 38 | "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36", 39 | "X-Requested-With": "XMLHttpRequest" 40 | } 41 | }) 42 | return data 43 | } 44 | -------------------------------------------------------------------------------- /scrapers/src/zzz.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | class ZenlessZone { 5 | list = async function list_chara() { 6 | return new Promise(async (resolve, reject) => { 7 | await axios.get("https://genshin.gg/zzz").then((res) => { 8 | const $ = cheerio.load(res.data); 9 | const chara = []; 10 | $(".character-list a").each((i, a) => { 11 | chara.push({ 12 | name: $(a).find("h2").text(), 13 | image: $(a).find("img").attr("src"), 14 | role: $(a).find(".character-type").attr("alt"), 15 | url: "https://genshin.gg/zzz" + $(a).attr("href"), 16 | }); 17 | }); 18 | resolve(chara); 19 | }); 20 | }); 21 | }; 22 | chara = async function character(chara) { 23 | return new Promise(async (resolve, reject) => { 24 | await axios 25 | .get( 26 | `https://genshin.gg/zzz/characters/${encodeURIComponent(chara.toLowerCase().split(" ").join(""))}/`, 27 | ) 28 | .then((response) => { 29 | const $ = cheerio.load(response.data); 30 | const data = { 31 | info: { 32 | name: $(".character-info-portrait").attr("alt"), 33 | element: $(".character-info-element").attr("alt"), 34 | image: $(".character-info-portrait").attr("src"), 35 | }, 36 | paths: [], 37 | stats: [], 38 | team: [], 39 | skills: [], 40 | talents: [], 41 | }; 42 | 43 | $(".character-info-path").each((i, el) => { 44 | data.paths.push( 45 | $(el).find(".character-info-path-icon").attr("alt"), 46 | ); 47 | }); 48 | 49 | $(".character-info-stat").each((i, el) => { 50 | data.stats.push({ 51 | name: $(el).find(".character-info-stat-name").text(), 52 | value: $(el).find(".character-info-stat-value").text(), 53 | }); 54 | }); 55 | 56 | $(".character-portrait").each((i, el) => { 57 | const name = $(el).find(".character-name").text(); 58 | const rarity = $(el) 59 | .find(".character-icon") 60 | .attr("class") 61 | .split(" ")[1]; 62 | const element = $(el).find(".character-type").attr("alt"); 63 | const role = $(el).find(".character-weapon").attr("alt"); 64 | const image = $(el).find("img").attr("src"); 65 | 66 | data.team.push({ 67 | name, 68 | rarity, 69 | element, 70 | role, 71 | image, 72 | }); 73 | }); 74 | 75 | $("#skills .character-info-skill").each((i, el) => { 76 | const skill = {}; 77 | skill.name = $(el).find(".character-info-skill-name").text(); 78 | skill.description = $(el) 79 | .find(".character-info-skill-description") 80 | .text(); 81 | data.skills.push(skill); 82 | }); 83 | 84 | $("#talents .character-info-skill").each((i, el) => { 85 | const talent = {}; 86 | talent.name = $(el).find(".character-info-skill-name").text(); 87 | talent.description = $(el) 88 | .find(".character-info-skill-description") 89 | .text(); 90 | data.talents.push(talent); 91 | }); 92 | 93 | resolve(data); 94 | }); 95 | }); 96 | }; 97 | } 98 | module.exports = new ZenlessZone(); -------------------------------------------------------------------------------- /settings.js: -------------------------------------------------------------------------------- 1 | const fs = require("node:fs"); 2 | 3 | const config = { 4 | owner: ["6282114275683", "6281910094713"], 5 | name: "- NekoBot - Simple WhatsApp bot", 6 | sessions: "sessions", 7 | prefix: [".", "?", "!"], // Tambahkan prefix sesuai kebutuhan 8 | sticker: { 9 | packname: "✨ NekoPack ✨", 10 | author: "🐾 AxellNetwork 🐾", 11 | }, 12 | id: { 13 | newsletter: "120363388655497053@newsletter", 14 | group: "120363370515588374@g.us" 15 | }, 16 | messages: { 17 | wait: "> ⏳ *Mohon tunggu sebentar*... Kami sedang memproses permintaan Anda, harap bersabar ya!", 18 | owner: "> 🧑‍💻 *Fitur ini hanya untuk pemilik bot*... Maaf, Anda tidak memiliki akses ke fitur ini.", 19 | premium: "> 🥇 *Upgrade ke Premium* untuk mendapatkan akses ke fitur eksklusif, murah dan cepat! Hubungi admin untuk info lebih lanjut.", 20 | group: "> 👥 *Fitur ini hanya tersedia di grup*... Pastikan Anda berada di grup WhatsApp untuk mengakses fitur ini.", 21 | botAdmin: "> ⚠️ *Anda harus menjadi admin grup* untuk menggunakan fitur ini, karena bot memerlukan hak akses admin.", 22 | grootbotbup: "> 🛠️ *Jadikan NekoBot sebagai admin* grup untuk menggunakan fitur ini. Pastikan Anda memberikan hak admin kepada bot.", 23 | }, 24 | database: "neko-db", 25 | tz: "Asia/Jakarta", 26 | }; 27 | 28 | module.exports = config; 29 | 30 | let file = require.resolve(__filename); 31 | fs.watchFile(file, () => { 32 | fs.unwatchFile(file); 33 | delete require.cache[file]; 34 | }); 35 | -------------------------------------------------------------------------------- /system/plugins/ai/deepseek.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | class Command { 4 | constructor() { 5 | this.command = "deepseek"; 6 | this.alias = []; 7 | this.category = ["ai"]; 8 | this.settings = { 9 | limit: true 10 | }; 11 | this.description = "Tanya jawab Bersama deepseek 🐋"; 12 | this.loading = true; 13 | } 14 | run = async (m, { 15 | sock, 16 | Func, 17 | Scraper, 18 | config, 19 | store, 20 | text 21 | }) => { 22 | if (!text) throw "Masukan Pertanyaan nya 📝" 23 | let { 24 | data 25 | } = await axios.post("https://ai.clauodflare.workers.dev/chat", { 26 | "model": "@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", 27 | "messages": [{ 28 | "role": "user", 29 | "content": text 30 | }] 31 | }).catch(e => e.response); 32 | if (!data.success) throw Func.jsonFormat(data); 33 | let response = data.data.response.split("").pop().trim(); 34 | m.reply(response); 35 | }; 36 | } 37 | 38 | module.exports = new Command(); -------------------------------------------------------------------------------- /system/plugins/ai/gemini.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const axios = require("axios"); 3 | const FormData = require("form-data"); 4 | const { fromBuffer } = require("file-type"); 5 | 6 | module.exports = { 7 | command: "gemini", 8 | alias: [], 9 | category: ["ai"], 10 | description: "Chat dgn gemini", 11 | async run(m, { text }) { 12 | if (!m.text) return m.reply("> mana m.textnya?"); 13 | m.react("🕐"); 14 | let q = m.quoted ? m.quoted : m; 15 | try { 16 | if ( 17 | /image|video|audio/.test(q.msg.mimetype) || 18 | /application\/pdf/.test(q.msg.mimetype) 19 | ) { 20 | let media = await q.download(); 21 | const { ext } = await fromBuffer(media); 22 | const filename = `./file_${Date.now()}.${ext}`; 23 | fs.writeFileSync(filename, media); 24 | const formData = new FormData(); 25 | formData.append("content", text); 26 | formData.append("model", "gemini-1.5-flash"); 27 | formData.append("file", fs.createReadStream(filename)); 28 | const { data } = await axios.post("https://hydrooo.web.id/", formData); 29 | fs.unlinkSync(filename); 30 | m.reply(data.result); 31 | } else { 32 | const formData = new FormData(); 33 | formData.append("content", text); 34 | formData.append("model", "gemini-1.5-flash"); 35 | const { data } = await axios.post("https://hydrooo.web.id/", formData); 36 | m.reply(data.result); 37 | } 38 | } catch (err) { 39 | console.log(err); 40 | m.reply(`Error dikit ga ngaruh`); 41 | } 42 | }, 43 | }; 44 | -------------------------------------------------------------------------------- /system/plugins/ai/openai.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "ai", 3 | alias: ["openai", "gpt", "gpt4"], 4 | category: ["ai"], 5 | description: "Jawab semua pertanyaan mu dengan AI", 6 | loading: true, 7 | async run(m, { text, sock, Scraper }) { 8 | if (!text) throw "> Masukan pernyataan nya"; 9 | let data = await Scraper.chatbot.send( 10 | [ 11 | { 12 | role: "user", 13 | content: text, 14 | }, 15 | { 16 | role: "system", 17 | content: 18 | "Kamu sekarang adalah NekoBot, Bot assisten yang diciptakan oleh Axell_Company", 19 | }, 20 | ], 21 | "gpt-3.5-turbo", 22 | ); 23 | if (!data.choices) 24 | return m.reply("> Gagal mendapatkan response dari ChatGpt"); 25 | m.reply(data.choices[0].message.content.trim()); 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /system/plugins/anime/kuronime.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "kuronime", 3 | alias: [], 4 | category: ["anime"], 5 | settings: { 6 | limit: true, 7 | }, 8 | description: "Cari Anime Terbaru di Kuronime", 9 | async run(m, { sock, Scraper, text, Func, config }) { 10 | let latest = await Scraper.kuronime.latest(); 11 | 12 | let cap = `*– 乂 **Panduan Penggunaan Fitur**:*\n 13 | > 📝 *Masukkan nama anime* untuk mencari anime yang sedang tren\n 14 | > 🔗 *Masukkan URL* untuk mendapatkan data anime lengkap langsung dari Kuronime\n 15 | 16 | *– 乂 **Contoh Penggunaan**:*\n 17 | > ➡️ *${m.prefix + m.command} Toradora*\n 18 | > ➡️ *${m.prefix + m.command} https://kuronime.biz/anime/toradora*\n 19 | 20 | *– 乂 **Anime yang Rilis Hari Ini** (${latest.length} Anime):*\n`; 21 | 22 | cap += latest 23 | .map((a) => 24 | Object.entries(a) 25 | .map(([b, c]) => `> 🔸 *${b.capitalize()}* : ${c}`) 26 | .join("\n"), 27 | ) 28 | .join("\n\n"); 29 | if (!text) throw cap; 30 | if (Func.isUrl(text) && /kuronime./.test(text)) { 31 | if (/anime\//.test(text)) { 32 | let data = await Scraper.kuronime.detail(text); 33 | let cap = `*– 乂 **Detail Anime** - Kuronime*\n 34 | > 🖼️ *Thumbnail*: ${data.metadata.thumbnail}\n`; 35 | 36 | cap += Object.entries(data.metadata) 37 | .map(([a, b]) => `> 🔹 *${a}* : ${b}`) 38 | .join("\n"); 39 | cap += "\n\n*– 乂 **Daftar Episode**:*\n"; 40 | cap += data.episode 41 | .map((a, i) => `> 📺 *${i + 1}.* ${a.title}\n> 🔗 ${a.url}`) 42 | .join("\n\n"); 43 | 44 | m.reply({ 45 | image: { 46 | url: data.metadata.thumbnail, 47 | }, 48 | caption: cap, 49 | }); 50 | } 51 | } else { 52 | let data = await Scraper.kuronime.search(text); 53 | if (data.length === 0) throw "> ❌ *Anime tidak ditemukan*"; 54 | 55 | let cap = "*– 乂 **Hasil Pencarian Anime** - Kuronime*\n"; 56 | cap += data 57 | .map((a) => 58 | Object.entries(a) 59 | .map(([b, c]) => `> 🔸 *${b.capitalize()}* : ${c}`) 60 | .join("\n"), 61 | ) 62 | .join("\n\n"); 63 | 64 | m.reply({ 65 | image: { 66 | url: data[0].thumbnail, 67 | }, 68 | caption: cap, 69 | }); 70 | } 71 | }, 72 | }; 73 | -------------------------------------------------------------------------------- /system/plugins/anime/samehadaku.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "kuronime", 3 | alias: [], 4 | category: ["anime"], 5 | settings: { 6 | limit: true, 7 | }, 8 | description: "Cari Anime Terbaru di Kuronime", 9 | async run(m, { sock, Scraper, text, Func, config }) { 10 | let latest = await Scraper.kuronime.latest(); 11 | 12 | let cap = `*– 乂 **Panduan Penggunaan Fitur**:*\n 13 | > 📝 *Masukkan nama anime* untuk mencari anime yang sedang tren\n 14 | > 🔗 *Masukkan URL* untuk mendapatkan data anime lengkap langsung dari Kuronime\n 15 | 16 | *– 乂 **Contoh Penggunaan**:*\n 17 | > ➡️ *${m.prefix + m.command} Toradora*\n 18 | > ➡️ *${m.prefix + m.command} https://kuronime.biz/anime/toradora*\n 19 | 20 | *– 乂 **Anime yang Rilis Hari Ini** (${latest.length} Anime):*\n`; 21 | 22 | cap += latest 23 | .map((a) => 24 | Object.entries(a) 25 | .map(([b, c]) => `> 🔸 *${b.capitalize()}* : ${c}`) 26 | .join("\n"), 27 | ) 28 | .join("\n\n"); 29 | 30 | if (!text) throw cap; 31 | 32 | if (Func.isUrl(text) && /kuronime./.test(text)) { 33 | if (/anime\//.test(text)) { 34 | let data = await Scraper.kuronime.detail(text); 35 | let cap = `*– 乂 **Detail Anime** - Kuronime*\n 36 | > 🖼️ *Thumbnail*: ${data.metadata.thumbnail}\n`; 37 | 38 | cap += Object.entries(data.metadata) 39 | .map(([a, b]) => `> 🔹 *${a}* : ${b}`) 40 | .join("\n"); 41 | cap += "\n\n*– 乂 **Daftar Episode**:*\n"; 42 | cap += data.episode 43 | .map((a, i) => `> 📺 *${i + 1}.* ${a.title}\n> 🔗 ${a.url}`) 44 | .join("\n\n"); 45 | 46 | m.reply({ 47 | image: { 48 | url: data.metadata.thumbnail, 49 | }, 50 | caption: cap, 51 | }); 52 | } 53 | } else { 54 | let data = await Scraper.kuronime.search(text); 55 | if (data.length === 0) throw "> ❌ *Anime tidak ditemukan*"; 56 | 57 | let cap = "*– 乂 **Hasil Pencarian Anime** - Kuronime*\n"; 58 | cap += data 59 | .map((a) => 60 | Object.entries(a) 61 | .map(([b, c]) => `> 🔸 *${b.capitalize()}* : ${c}`) 62 | .join("\n"), 63 | ) 64 | .join("\n\n"); 65 | 66 | m.reply({ 67 | image: { 68 | url: data[0].thumbnail, 69 | }, 70 | caption: cap, 71 | }); 72 | } 73 | }, 74 | }; 75 | -------------------------------------------------------------------------------- /system/plugins/anime/sokuja.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "sokuja", 3 | alias: [], 4 | category: ["anime"], 5 | settigs: { 6 | limit: true, 7 | }, 8 | description: "Cek Anime terbaru di sokuja", 9 | async run(m, { sock, Scraper, text, Func, config }) { 10 | let latest = await Scraper.sokuja.latest(); 11 | let cap = `*– 乂 Cara penggunaan* 12 | > Masukan query untuk mencari anime 13 | > Masukan link untuk mendapatkan data anime 14 | 15 | *– 乂 Contoh - penggunaan* 16 | > ${m.prefix + m.command} oshi no ko 17 | > ${m.prefix + m.command} https://x1.sokuja.uk/anime/oshi-no-ko-subtitle-indonesia/ 18 | > ${m.prefix + m.command} https://x1.sokuja.uk/end-oshi-no-ko-episode-11-subtitle-indonesia/ 19 | 20 | *– 乂 Berikut ${latest.length} anime yang rilis hari ini* 21 | 22 | ${latest 23 | .map((a) => 24 | Object.entries(a) 25 | .map(([b, c]) => `> *- ${b.capitalize()} :* ${c}`) 26 | .join("\n"), 27 | ) 28 | .join("\n\n")}`; 29 | if (!text) throw cap; 30 | if (Func.isUrl(text) && /sokuja./.test(text)) { 31 | if (/anime\//.test(text)) { 32 | let data = await Scraper.sokuja.detail(text); 33 | let cap = `*– 乂 Sokuja - Detail*\n`; 34 | cap += Object.entries(data.metadata) 35 | .map(([a, b]) => `> *- ${a} :* ${b}`) 36 | .join("\n"); 37 | cap += "\n\n*– 乂 List - Episode*\n"; 38 | cap += data.episode 39 | .map((a, i) => `*${i + 1}.* ${a.title}\n> ${a.url}`) 40 | .join("\n\n"); 41 | m.reply({ 42 | image: { 43 | url: data.metadata.thumbnail, 44 | }, 45 | caption: cap, 46 | }); 47 | } else { 48 | let data = await Scraper.sokuja.episode(text); 49 | let quality = Object.keys(data.downloads); 50 | let cap = "*– 乂 Sokuja - Episode*\n"; 51 | cap += Object.entries(data.metadata) 52 | .map( 53 | ([a, b]) => 54 | `> *- ${a} :* ${typeof b === "object" ? b.join(", ") : b}`, 55 | ) 56 | .join("\n"); 57 | if (quality.length > 1) { 58 | cap += "\n\n*– 乂 Download - Episode*\n"; 59 | for (let i of quality) { 60 | cap += `> *- Download ${i}*\n`; 61 | cap += Object.entries(data.downloads[i]) 62 | .map(([a, b]) => `> *- ${a.capitalize()} :* ${b}`) 63 | .join("\n"); 64 | cap += "\n\n"; 65 | } 66 | } else { 67 | cap += "\n\ntidak ada link download pada episode ini"; 68 | } 69 | m.reply(cap); 70 | if (data.downloads["480p"].url) 71 | return m.reply({ 72 | video: { 73 | url: data.downloads["480p"].url, 74 | }, 75 | }); 76 | } 77 | } else { 78 | let data = await Scraper.sokuja.search(text); 79 | if (data.length === 0) throw "> Anime tidak ditemukan"; 80 | let cap = "*– 乂 Sokuja - Search*\n"; 81 | cap += data 82 | .map((a) => 83 | Object.entries(a) 84 | .map(([b, c]) => `> *- ${b.capitalize()} :* ${c}`) 85 | .join("\n"), 86 | ) 87 | .join("\n\n"); 88 | m.reply(cap); 89 | } 90 | }, 91 | }; 92 | -------------------------------------------------------------------------------- /system/plugins/anime/waifu.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | const cmd = { 4 | command: "waifu", 5 | category: ["anime"], 6 | alias: ["waifu"], 7 | description: "Gambar Random Waifu", 8 | loading: true, 9 | async run(m, { sock, config }) { 10 | try { 11 | let json = await axios.get("https://api.waifu.pics/sfw/waifu"); 12 | let cap = `*– 乂 **Waifu Random**:*\n> 💫 *Gambar Waifu yang Baru* \n> *Ketik ${m.prefix + m.command} lagi untuk mendapatkan gambar baru!*`; 13 | 14 | m.reply({ 15 | image: json.data.url, 16 | caption: cap, 17 | }); 18 | } catch (err) { 19 | m.reply("> ❌ Terjadi kesalahan, coba lagi nanti."); 20 | } 21 | }, 22 | }; 23 | 24 | module.exports = cmd; 25 | -------------------------------------------------------------------------------- /system/plugins/downloader/applemusic.js: -------------------------------------------------------------------------------- 1 | const { 2 | toAudio 3 | } = require(process.cwd() + "/lib/converter.js"); 4 | 5 | class Command { 6 | constructor() { 7 | this.command = "applemusic"; 8 | this.alias = ["aplm", "apple"]; 9 | this.category = ["downloader"]; 10 | this.settings = { 11 | limit: true, 12 | }; 13 | this.description = "🎵 Cari dan download musik dari Apple Music!"; 14 | this.loading = true; 15 | } 16 | run = async (m, { 17 | sock, 18 | Func, 19 | Scraper, 20 | config, 21 | store, 22 | text 23 | }) => { 24 | if (!text) throw "> ❌ *Masukkan pencarian atau link dari Apple Music*"; 25 | 26 | if (Func.isUrl(text)) { 27 | if (!/music.apple.com/.test(text)) 28 | throw "> ❌ *Link yang dimasukkan bukan link Apple Music!*"; 29 | let data = await Scraper.applemusic.download(text); 30 | if (!data.metadata) throw Func.jsonFormat(data); 31 | let anu = await toAudio(await Func.fetchBuffer(data.download), 'mp3'); 32 | let cap = "*🎧 Apple Music Downloader 🎧*\n" 33 | cap += `*✍️ Judul :* ${data.metadata.name}\n` 34 | cap += `*📝 Genre :* ${data.metadata.genre}\n` 35 | cap += `*👦 Artis :* ${data.metadata.artist.name}\n` 36 | cap += `*🕑 Diunggah pada :* ${data.metadata.datePublished}` 37 | sock.sendFile(m.cht, data.metadata.image, null, cap, m); 38 | sock.sendFile( 39 | m.cht, 40 | anu.data, 41 | `${data.metadata.name} | ${data.metadata.artist.name}.mp3`, 42 | `🎧 *Silakan download musik ini dengan menekan tombol di atas*\n\n> *Catatan*: Jika file muncul sebagai , silakan download manual.`, 43 | m, { 44 | mimetype: "audio/mpeg", 45 | jpegThumbnail: await sock.resize(data.metadata.image, 400, 400), 46 | }, 47 | ); 48 | } else { 49 | let data = await Scraper.applemusic.search(text); 50 | if (data.length === 0) throw "> ❌ *Musik tidak ditemukan*"; 51 | 52 | let cap = `*– 乂 Apple Music - Hasil Pencarian*\n> 🎤 *Pilih lagu yang ingin kamu download!*\n\n`; 53 | for (let i of data) { 54 | cap += `> 🎶 *Judul*: ${i.title}\n`; 55 | cap += `> 👨‍🎤 *Artis*: ${i.artist.name}\n`; 56 | cap += `> 🔗 *Link*: ${i.song}\n\n`; 57 | } 58 | m.reply(cap); 59 | } 60 | }; 61 | } 62 | 63 | module.exports = new Command(); -------------------------------------------------------------------------------- /system/plugins/downloader/bstation.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | module.exports = { 4 | command: "bstation", 5 | alias: ["blibili"], 6 | category: ["downloader"], 7 | settings: { 8 | limit: true, 9 | }, 10 | description: "Mencari dan download video dari Bstation", 11 | loading: true, 12 | async run(m, { sock, Func, Scraper, text }) { 13 | if (!text) { 14 | throw `> *– 乂 Panduan Penggunaan Fitur:* 15 | > 📥 Masukkan query untuk mencari video 16 | > 🔗 Masukkan URL untuk mendownload video langsung 17 | 18 | > *– 乂 Contoh Penggunaan:* 19 | > ➡️ ${m.prefix + m.command} Video lucu 20 | > ➡️ ${m.prefix + m.command} https://www.bilibili.tv/id/video/4793262300860416`; 21 | } 22 | 23 | if (Func.isUrl(text)) { 24 | let data = await Scraper.bstation.download(text); 25 | let buffer = await Func.fetchBuffer(data.download.url); 26 | 27 | let size = Func.formatSize(buffer.length); 28 | let limit = Func.sizeLimit(size, db.list().settings.max_upload); 29 | if (limit.oversize) { 30 | throw `⚠️ Ukuran video melebihi batas yang ditentukan (${size}). 31 | Upgrade status ke premium agar dapat download video hingga *1GB*!`; 32 | } 33 | 34 | console.log("Compression completed, sending video..."); 35 | let cap = `*– 乂 Bstation - Downloader:*\n`; 36 | cap += Object.entries(data.metadata) 37 | .map(([a, b]) => `> 🔸 ${a.capitalize()} : ${b}`) 38 | .join("\n"); 39 | 40 | m.reply({ 41 | video: buffer, 42 | caption: cap, 43 | }); 44 | } else { 45 | let data = await Scraper.bstation.search(text); 46 | let cap = `*– 乂 Bstation - Hasil Pencarian:*\n`; 47 | cap += `> Ketikan ${m.prefix + m.command} ${data[0].url} untuk mendownload video yang kamu pilih\n\n`; 48 | cap += data 49 | .map( 50 | (res, index) => 51 | `> *${index + 1}.* ${res.title}\n> 👁️‍🗨️ Penonton: ${res.views}\n> ⏱️ Durasi: ${res.duration}\n> ✍️ Author: ${res.author.name}\n> 🔗 Link: ${res.url}`, 52 | ) 53 | .join("\n\n"); 54 | m.reply(cap); 55 | } 56 | }, 57 | }; 58 | -------------------------------------------------------------------------------- /system/plugins/downloader/doodstream.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "doodstream", 3 | alias: ["dood", "doods"], 4 | category: ["downloader"], 5 | description: "Download dan upload video dari Doodstream dengan mudah", 6 | loading: true, 7 | async run(m, { sock, Func, Uploader, text, Scraper }) { 8 | if (!text) 9 | throw `*– 乂 **Panduan Penggunaan Fitur**:*\n 10 | > 📥 *Gunakan* \`--upload\` *untuk mengupload video ke Doodstream*\n 11 | > 🔗 *Masukkan link Doodstream* (misalnya: https://dood.li/xxx) *untuk mendownload video*\n 12 | 13 | *– 乂 **Contoh Penggunaan**:*\n 14 | > ➡️ *${m.prefix + m.command} --upload*\n 15 | > ➡️ *${m.prefix + m.command} https://dood.li/xxx*\n`; 16 | 17 | if (m.text.includes("--upload")) { 18 | let q = m.quoted ? m.quoted : m; 19 | if (!/video/.test(q.msg.mimetype) || !q.isMedia) 20 | throw `> 📩 *Silahkan reply/kirim video dengan caption* ${m.prefix + m.command} ${text}`; 21 | let buffer = await q.download(); 22 | let hasil = await Uploader.doods(buffer); 23 | let cap = "*– 乂 **Doodstream - Uploader**:*\n"; 24 | cap += `> 📦 *Ukuran Video*: ${Func.formatSize(buffer.length)}\n`; 25 | cap += `> 🔗 *Link Video*: ${hasil.result[0].protected_embed}\n`; 26 | cap += `> 📤 *Silahkan klik link di atas untuk menonton atau mendownload video*`; 27 | m.reply(cap); 28 | } else { 29 | if (!Func.isUrl(text) || !/dood.(li|la|com|ws)/.test(text)) 30 | throw "> ❌ *Masukkan link Doodstream yang valid*"; 31 | 32 | let data = await Scraper.doodstream(text); 33 | if (!data.download) return m.reply(Func.jsonFormat(data)); 34 | let size = await Func.getSize(data.download()); 35 | let limit = Func.sizeLimit(size, db.list().settings.max_upload); 36 | if (limit.oversize) 37 | throw `> 🚫 *Ukuran file terlalu besar* *( ${size} )*, *Upgrade ke Premium* untuk mengunduh video hingga ukuran *1GB*!`; 38 | 39 | let cap = "*– 乂 **Doodstream - Downloader**:*\n"; 40 | cap += `> 🎥 *Judul Video*: ${data.title}\n`; 41 | cap += `> 👁️‍🗨️ *Jumlah Penonton*: ${data.views}\n`; 42 | cap += `> ⏱️ *Durasi Video*: ${data.duration}\n`; 43 | cap += `> 📝 *Deskripsi*: ${data.description || "Tidak tersedia"}\n`; 44 | cap += `> 🔗 *Link Download*: ${data.download.url}\n`; 45 | 46 | m.reply({ 47 | video: { 48 | url: data.download.url, 49 | }, 50 | caption: cap, 51 | }); 52 | } 53 | }, 54 | }; 55 | -------------------------------------------------------------------------------- /system/plugins/downloader/fb.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | module.exports = { 4 | command: "facebook", 5 | alias: ["fb", "fbdl"], 6 | category: ["downloader"], 7 | settings: { 8 | limit: true, 9 | }, 10 | description: "Unduh video dari Facebook", 11 | loading: true, 12 | async run(m, { 13 | sock, 14 | Scraper, 15 | Text, 16 | Func, 17 | text 18 | }) { 19 | if (!/facebook.com|fb.watch/.test(text) || !text) 20 | throw `*– 乂 **Cara Penggunaan** :* 21 | > 📝 *Masukkan URL video dari Facebook yang ingin diunduh* 22 | > 💬 *Contoh :* ${m.prefix + m.command} https://www.facebook.com/watch?v=1234567890 23 | 24 | *– 乂 **Petunjuk Lain** :* 25 | > ✔️ Pastikan video yang dimaksud adalah publik dan dapat diakses. 26 | > ⚠️ Video yang dilindungi hak cipta atau terbatas mungkin tidak dapat diunduh.`; 27 | 28 | let data = await Scraper.facebook(text); 29 | let random = data.media[0]; 30 | let buffer = await fetch(random).then(async (a) => 31 | Buffer.from(await a.arrayBuffer())); 32 | 33 | let size = Func.formatSize(buffer.length); 34 | let limit = await Func.sizeLimit(size, db.list().settings.max_upload); 35 | 36 | if (limit.oversize) 37 | throw `*– 乂 **Ukuran Terlalu Besar** :* 38 | > Video ini memiliki ukuran *( ${size} )* yang melebihi batas yang ditentukan. 39 | > 🔓 *Upgrade ke Premium* untuk mendapatkan batas unduh hingga *1GB*.` 40 | 41 | let cap = `*– 乂 Informasi Video :* 42 | > 🎥 *Judul :* ${data.metadata.title}`; 43 | 44 | sock.sendFile(m.cht, buffer, null, cap, m); 45 | }, 46 | }; 47 | -------------------------------------------------------------------------------- /system/plugins/downloader/gitclone.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | const regex = 4 | /(?:https|git)(?::\/\/|@)github\.com[\/:]([^\/:]+)\/(.+?)(?:[\/]|$)/i; 5 | 6 | module.exports = { 7 | command: "gitclone", 8 | alias: ["gitdl", "githubdl"], 9 | settings: { 10 | limit: true, 11 | }, 12 | description: "Download repository dari github", 13 | loading: true, 14 | async run(m, { sock, Func, text }) { 15 | if (!Func.isUrl(text) && !/github.com/.test(text)) 16 | throw `*– 乂 Cara Penggunaan :* 17 | > 📝 *Masukkan URL repository GitHub yang ingin diunduh* 18 | > 💬 *Contoh :* ${m.prefix + m.command} https://github.com/user/repository 19 | 20 | *– 乂 Petunjuk Lain :* 21 | > ✔️ Pastikan URL yang dimasukkan adalah link valid dari repository GitHub.`; 22 | 23 | let [_, author, repo] = text.match(regex); 24 | if (!author || !repo) 25 | throw "*– 乂 Masukkan Link Repository :*\n> Link repository tidak valid atau tidak ditemukan!"; 26 | 27 | repo.replace(/.git$/, ""); 28 | let api = `https://api.github.com/repos/${author}/${repo}`; 29 | let { data } = await axios.get(api).catch((e) => e.response); 30 | 31 | let cap = `*– 乂 Github Repository Info :*\n`; 32 | cap += `> *- Nama :* ${data.name}\n`; 33 | cap += `> *- Pemilik :* ${data.owner.login}\n`; 34 | cap += `> *- Bahasa Pemrograman :* ${data.language}\n`; 35 | cap += `> *- Total Star :* ${Func.h2k(data.watchers)} ⭐\n`; 36 | cap += `> *- Total Forks :* ${Func.h2k(data.forks)} 🍴\n`; 37 | cap += `> *- Dibuat Pada :* ${Func.ago(data.created_at)}\n`; 38 | cap += `> *- Terakhir Diperbarui :* ${Func.ago(data.updated_at)}\n`; 39 | cap += `\n> 📜 *Deskripsi:* ${data.description || "*Tidak ada deskripsi yang tersedia*"}\n`; 40 | 41 | m.reply({ 42 | document: { 43 | url: api + "/zipball", 44 | }, 45 | caption: cap, 46 | fileName: `${repo}.zip`, 47 | mimetype: "application/zip", 48 | }); 49 | }, 50 | }; 51 | -------------------------------------------------------------------------------- /system/plugins/downloader/instagram.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "Instagram", 3 | alias: ["igdl", "ig", "igvideo", "igreel"], 4 | category: ["downloader"], 5 | settings: { 6 | limit: true, 7 | }, 8 | description: "Mengunduh Reels/postingan Instagram", 9 | loading: true, 10 | async run(m, { sock, Func, text, Scraper }) { 11 | if (!text) 12 | throw `*– 乂 Cara Penggunaan :* 13 | > *Masukkan atau balas pesan dengan link Instagram yang ingin diunduh* 14 | > *Contoh :* ${m.prefix + m.command} https://www.instagram.com/reel/xxxxx/ 15 | 16 | *– 乂 Petunjuk :* 17 | > Link yang valid hanya bisa berupa Postingan atau Reels dari Instagram.`; 18 | 19 | if (!/instagram.com/.test(text)) 20 | throw "*– 乂 Masukkan Link Instagram yang Valid :*\n> Pastikan link yang dimasukkan berasal dari Instagram."; 21 | 22 | let data = await Scraper.Instagram(text); 23 | if (!data) return; 24 | 25 | for (let i of data.url) { 26 | let res = await fetch(i); 27 | let cap = `*– 乂 Instagram Downloader :*\n`; 28 | cap += Object.entries(data.metadata) 29 | .map(([a, b]) => `> *- ${a.capitalize()} :* ${b}`) 30 | .join("\n"); 31 | 32 | sock.sendFile(m.cht, Buffer.from(await res.arrayBuffer()), null, cap, m); 33 | } 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /system/plugins/downloader/mediafire.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "mediafire", 3 | alias: ["mf", "mfdl"], 4 | category: ["downloader"], 5 | settings: { 6 | limit: true, 7 | }, 8 | description: "Unduh file dari MediaFire 🔽", 9 | loading: true, 10 | async run(m, { sock, Scraper, Func, text }) { 11 | if (!Func.isUrl(text) || !/mediafire.com/.test(text) || !text) 12 | throw "> *❌ Masukkan link MediaFire yang valid!*"; 13 | let data = await Scraper.mediafire(text); 14 | let cap = "*– 乂 MediaFire - Downloader 🗂️*\n"; 15 | cap += `> *🔸 Nama File :* ${data.filename}\n`; 16 | cap += `> *🔸 Tipe File :* ${data.mimetype}\n`; 17 | cap += `> *🔸 Ukuran File :* ${Func.formatSize(data.size)}\n`; 18 | cap += `> *🔸 Link Download :* ${data.download}\n`; 19 | 20 | let buffer = await fetch(data.download).then(async (a) => 21 | Buffer.from(await a.arrayBuffer()), 22 | ); 23 | let size = Func.formatSize(buffer.length); 24 | let limit = Func.sizeLimit(data.size, db.list().settings.max_upload); 25 | 26 | if (limit.oversize) 27 | throw `Maaf, ukuran file *( ${size} )* melebihi batas ukuran yang ditentukan. Upgrade status kamu ke premium untuk mendownload file hingga *1GB*!`; 28 | 29 | m.reply({ 30 | document: buffer, 31 | mimetype: data.mimetype, 32 | fileName: data.filename, 33 | caption: cap, 34 | }); 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /system/plugins/downloader/pinterest.js: -------------------------------------------------------------------------------- 1 | let neko = async (m, { sock, Func, Scraper, text, Uploader }) => { 2 | if (!text) throw "> *❌ Masukkan query atau link dari Pinterest!*"; 3 | 4 | if (Func.isUrl(text)) { 5 | if (!/pinterest.com|pin.it/.test(text)) 6 | throw "> *❌ Masukkan link Pinterest yang valid!*"; 7 | let data = await Scraper.pinterest.download(text); 8 | let cap = "*– 乂 Pinterest - Downloader 📌*\n"; 9 | cap += `> *🔹 Judul :* ${data.title}\n`; 10 | cap += `> *🔹 Kata Kunci :* ${data.keyword.join(", ")}\n`; 11 | cap += `> *🔹 Pengarang :* ${data.author.name}\n`; 12 | 13 | sock.sendFile(m.cht, data.download, null, cap, m); 14 | } else { 15 | let data = await Scraper.pinterest.search(text); 16 | let result = data.getRandom(); 17 | let caption = "*– 乂 Pinterest - Pencarian 🔍*\n"; 18 | caption += Object.entries(result) 19 | .map(([a, b]) => `> *🔹 ${a.capitalize()} :* ${b}`) 20 | .join("\n"); 21 | 22 | m.reply({ 23 | image: { 24 | url: result.image, 25 | }, 26 | caption, 27 | }); 28 | } 29 | }; 30 | 31 | neko.command = "pinterest"; 32 | neko.alias = ["pin", "pindl"]; 33 | neko.category = ["downloader", "tools"]; 34 | neko.settings = { 35 | limit: true, 36 | }; 37 | neko.description = "🔎 Mencari atau mengunduh media dari Pinterest!"; 38 | neko.loading = true; 39 | 40 | module.exports = neko; 41 | -------------------------------------------------------------------------------- /system/plugins/downloader/rednote.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "rednote"; 4 | this.alias = ["xiaohongshu"]; 5 | this.category = ["downloader"]; 6 | this.settings = { 7 | limit: true 8 | }; 9 | this.description = "🟥 Download video/slide photo dari rednote"; 10 | this.loading = true; 11 | } 12 | run = async (m, { 13 | sock, 14 | Func, 15 | Scraper, 16 | config, 17 | store, 18 | text 19 | }) => { 20 | if (!text || !Func.isUrl(text) || !/xhslink.com|xiaohongshu.com/.test(text)) throw "*❌ Masukan Input :* Masukan Url dari Xiaohongshu/Rednote" 21 | 22 | let data = await Scraper.rednote(text); 23 | if (!data.metadata) throw "*⁉️⁉️ Media tidak ditemukan*" 24 | let caption = "*Xiaohongshu - Downloader 📩*\n" 25 | caption += `*🔻 Title :* ${data.metadata.title}\n` 26 | caption += `\n*📈 Statistik :*\n` 27 | caption += Object.entries(data.metadata.stats).map(([a, b]) => `- ${a.capitalize()} : ${b}`).join("\n") 28 | caption += `\n\n*👤 Info Pemilik :*\n` 29 | caption += Object.entries(data.metadata.author).map(([a, b]) => `- ${a.capitalize()} : ${b}`).join("\n") 30 | caption += "\n\n*✅ Media Berhasil Diunduh !*\n📨 Nikmati kemudahan mendownload video rednote hanya di NekoBot" 31 | 32 | if (typeof data.download == "object") { 33 | for (let img of data.download) { 34 | sock.sendFile(m.cht, img, null, caption, m); 35 | } 36 | } else { 37 | sock.sendFile(m.cht, data.download, null, caption, m); 38 | } 39 | }; 40 | } 41 | 42 | module.exports = new Command(); -------------------------------------------------------------------------------- /system/plugins/downloader/sfile.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "sfile"; 4 | this.alias = ["sfilemobi"]; 5 | this.category = ["downloader"]; 6 | this.settings = { 7 | limit: true 8 | }; 9 | this.description = "📁 Download file dari sfileMobi !"; 10 | this.loading = true; 11 | } 12 | run = async (m, { 13 | sock, 14 | Func, 15 | Scraper, 16 | config, 17 | store, 18 | text 19 | }) => { 20 | if (!text || !Func.isUrl(text) || !/sfile.mobi/.test(text)) throw "*❌ Input salah :* Masukan url sfileMobi !"; 21 | let data = await Scraper.sfile(text); 22 | if (!data.metadata) throw "*⁉️ Media tidak ditemukan?*"; 23 | let caption = "*SfileMobi - Downloader 📩*\n"; 24 | caption += Object.entries(data.metadata).map(([a, b]) => `- ${a.capitalize()}: ${b}`).join("\n"); 25 | caption += "\n\n*✅ Media Berhasil Diunduh !*\nNikmati kemudahan saat download apapun hanya di NekoBot!"; 26 | sock.sendFile(m.cht, data.download, data.metadata.filename, caption, m, { 27 | mimetype: data.metadata.mimetype 28 | }); 29 | }; 30 | } 31 | 32 | module.exports = new Command(); -------------------------------------------------------------------------------- /system/plugins/downloader/snackvideo.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "snackvideo"; 4 | this.alias = []; 5 | this.category = ["downloader"]; 6 | this.settings = { 7 | limit: true, 8 | }; 9 | this.description = "🔍 Mencari atau mengunduh video dari SnackVideo!"; 10 | this.loading = true; 11 | } 12 | run = async (m, { sock, Func, Scraper, config, store, text }) => { 13 | if (!text) 14 | throw ( 15 | `*– 乂 Cara Penggunaan 🍿*\n\n` + 16 | `> Masukkan **query** untuk mencari video\n` + 17 | `> Masukkan **URL** dari SnackVideo untuk mengunduh\n\n` + 18 | `*– 乂 Contoh Penggunaan 📋*\n` + 19 | `> ${m.prefix}snackvideo Anime\n` + 20 | `> ${m.prefix}snackvideo https://www.snackvideo.com/@ALBAN_105/video/5221792395456439006` 21 | ); 22 | 23 | if (Func.isUrl(text)) { 24 | if (!/snackvideo.com/.test(text)) 25 | throw `> *❌ Masukkan URL dari SnackVideo yang valid!*`; 26 | 27 | let data = await Scraper.snackvideo.download(text); 28 | let caption = `*– 乂 SnackVideo - Downloader 📥*\n\n`; 29 | caption += Object.entries(data.metadata) 30 | .map(([a, b]) => `> *🔹 ${a.capitalize()} :* ${b}`) 31 | .join("\n"); 32 | 33 | sock.sendFile(m.cht, data.download, null, caption, m); 34 | } else { 35 | let data = await Scraper.snackvideo.search(text); 36 | if (data.length === 0) throw `> *❌ Video tidak ditemukan!*`; 37 | 38 | let caption = `*– 乂 SnackVideo - Pencarian 🔎*\n\n`; 39 | caption += data 40 | .map( 41 | (a) => 42 | `> *🎥 Judul :* ${a.title}\n` + 43 | `> *📅 Diunggah :* ${a.uploaded}\n` + 44 | `> *👤 Pengarang :* ${a.author.name}\n` + 45 | `> *🔗 URL :* ${a.url}`, 46 | ) 47 | .join("\n\n"); 48 | 49 | m.reply(caption); 50 | } 51 | }; 52 | } 53 | 54 | module.exports = new Command(); 55 | -------------------------------------------------------------------------------- /system/plugins/downloader/soundcloud.js: -------------------------------------------------------------------------------- 1 | const { 2 | fetch 3 | } = require("undici"); 4 | 5 | class Command { 6 | constructor() { 7 | this.command = "soundcloud"; 8 | this.alias = ["sound", "scloud"]; 9 | this.category = ["downloader"]; 10 | this.settings = { 11 | limit: true, 12 | }; 13 | this.description = "🎵 Mencari dan mengunduh musik dari SoundCloud!"; 14 | this.loading = true; 15 | } 16 | run = async (m, { 17 | sock, 18 | Func, 19 | Scraper, 20 | config, 21 | store, 22 | text 23 | }) => { 24 | if (!text) 25 | throw ( 26 | `*– 乂 Cara Penggunaan 🎶*\n\n` + 27 | `> Masukkan kata kunci untuk mencari musik\n` + 28 | `> Masukkan URL SoundCloud untuk mengunduh musik\n\n` + 29 | `*– 乂 Contoh Penggunaan 📋*\n` + 30 | `> ${m.prefix}soundcloud Imagine Dragons\n` + 31 | `> ${m.prefix}soundcloud https://soundcloud.com/artist-name/track-name` 32 | ); 33 | 34 | if (Func.isUrl(text)) { 35 | if (!/soundcloud.com/.test(text)) 36 | throw `> *❌ Masukkan URL SoundCloud yang valid!*`; 37 | 38 | let data = await Scraper.soundcloud.download(text); 39 | if (!data.download) throw Func.jsonFormat(data); 40 | let buffer = await fetch(data.download); 41 | let cap = `*– 乂 SoundCloud - Downloader 🎵*\n\n`; 42 | cap += Object.entries(data) 43 | .map(([a, b]) => `> *🎧 ${a.capitalize()} :* ${b}`) 44 | .join("\n"); 45 | 46 | sock.sendMessage(m.cht, { 47 | image: { 48 | url: data.thumbnail 49 | }, 50 | caption: cap 51 | }, { 52 | quoted: m 53 | }).then((msg) => { 54 | setTimeout(() => { 55 | sock.sendMessage(m.cht, { 56 | audio: { 57 | url: data.download 58 | }, 59 | mimetype: "audio/mpeg", 60 | }, { 61 | quoted: msg 62 | }); 63 | }, 4000); 64 | }) 65 | } else { 66 | let data = await Scraper.soundcloud.search(text); 67 | if (data.length === 0) throw `> *❌ Musik tidak ditemukan!*`; 68 | 69 | let cap = 70 | `*– 乂 SoundCloud - Pencarian 🔎*\n\n` + 71 | `> Pilih lagu yang ingin kamu unduh!\n\n`; 72 | cap += data 73 | .map((i) => `> *🎵 Judul :* ${i.title}\n` + `> *🔗 URL :* ${i.url}`) 74 | .join("\n\n"); 75 | 76 | m.reply(cap); 77 | } 78 | }; 79 | } 80 | 81 | module.exports = new Command(); -------------------------------------------------------------------------------- /system/plugins/downloader/spotify.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | module.exports = { 4 | command: "spotify", 5 | alias: [], 6 | category: ["downloader"], 7 | settings: { 8 | limit: true, 9 | }, 10 | description: "🎵 Mencari atau mengunduh musik dari Spotify!", 11 | loading: true, 12 | async run(m, { sock, Func, Scraper, text }) { 13 | if (!text) 14 | throw ( 15 | `*– 乂 Cara Penggunaan 🎶*\n\n` + 16 | `> *🔍 Masukkan kata kunci* untuk mencari musik\n` + 17 | `> *🔗 Masukkan URL Spotify* untuk mengunduh musik\n\n` + 18 | `*– 乂 Contoh Penggunaan 📋*\n` + 19 | `> *${m.prefix + m.command} Imagine Dragons*\n` + 20 | `> *${m.prefix + m.command} https://open.spotify.com/track/examplelink*` 21 | ); 22 | 23 | if (/open.spotify.com/.test(text)) { 24 | let data = await Scraper.spotify.download(text); 25 | let cap = `*– 乂 Spotify - Downloader 🎵*\n\n`; 26 | cap += Object.entries(data) 27 | .map(([a, b]) => `> *🎧 ${a.capitalize()} :* ${b}`) 28 | .join("\n"); 29 | 30 | m.reply(cap).then(() => { 31 | m.reply({ 32 | audio: { 33 | url: data.download, 34 | }, 35 | mimetype: "audio/mpeg", 36 | }); 37 | }); 38 | } else { 39 | let data = await Scraper.spotify.search(text); 40 | if (!data || data.length === 0) throw `> *❌ Musik tidak ditemukan!*`; 41 | 42 | let cap = 43 | `*– 乂 Spotify - Pencarian 🔎*\n\n` + 44 | `> Ketik *${m.prefix + m.command} [URL]* untuk mengunduh musik pilihanmu 🎶\n\n`; 45 | cap += data 46 | .map((a) => 47 | Object.entries(a) 48 | .map(([b, c]) => `> *🎵 ${b.capitalize()} :* ${c}`) 49 | .join("\n"), 50 | ) 51 | .join("\n\n"); 52 | 53 | m.reply(cap); 54 | } 55 | }, 56 | }; 57 | -------------------------------------------------------------------------------- /system/plugins/downloader/tiktok.js: -------------------------------------------------------------------------------- 1 | let neko = async ( 2 | m, 3 | { sock, Func, Scraper, Uploader, store, text, config }, 4 | ) => { 5 | if (!text.includes("tiktok")) 6 | return m.reply( 7 | "❌ *Link TikTok tidak ditemukan! Masukkan link yang valid.*", 8 | ); 9 | 10 | await Scraper.ttsave.video(text).then(async (a) => { 11 | const caption = `*– 乂 TikTok - Downloader 🎥*\n`; 12 | caption += `> 📛 *Nama:* ${a.nickname}\n`; 13 | caption += `> 🧑‍💻 *Username:* ${a.username}\n`; 14 | caption += `> 🆔 *Username ID:* ${a.uniqueId}\n`; 15 | caption += `> 👁️ *Views:* ${a.stats.plays}\n`; 16 | caption += `> ❤️ *Likes:* ${a.stats.likes}\n`; 17 | caption += `> 💬 *Komentar:* ${a.stats.comments}\n`; 18 | caption += `> 🔄 *Bagikan:* ${a.stats.shares}\n`; 19 | caption += `⏤͟͟͞͞╳`; 20 | 21 | sock.sendMessage( 22 | m.cht, 23 | { 24 | image: { 25 | url: a.profilePic, 26 | }, 27 | caption, 28 | }, 29 | { 30 | quoted: m, 31 | }, 32 | ); 33 | 34 | if (a.dlink.nowm) { 35 | await sock.sendMessage( 36 | m.cht, 37 | { 38 | video: { 39 | url: a.dlink.nowm, 40 | }, 41 | caption, 42 | }, 43 | { 44 | quoted: m, 45 | }, 46 | ); 47 | } else if (a.slides) { 48 | for (let i of a.slides) { 49 | await sock.sendMessage( 50 | m.cht, 51 | { 52 | image: { 53 | url: i.url, 54 | }, 55 | caption, 56 | }, 57 | { 58 | quoted: m, 59 | }, 60 | ); 61 | } 62 | } 63 | }); 64 | 65 | Scraper.ttsave.mp3(text).then(async (u) => { 66 | const contextInfo = { 67 | mentionedJid: [m.sender], 68 | isForwarded: true, 69 | forwardingScore: 127, 70 | externalAdReply: { 71 | title: `${Func.Styles(`${u.songTitle}`)}`, 72 | body: `${Func.Styles(`${u.username}`)}`, 73 | mediaType: 1, 74 | thumbnailUrl: u.coverUrl, 75 | sourceUrl: u.audioUrl, 76 | renderLargerThumbnail: true, 77 | }, 78 | }; 79 | 80 | await sock.sendMessage( 81 | m.cht, 82 | { 83 | audio: { 84 | url: u.audioUrl, 85 | }, 86 | mimetype: "audio/mpeg", 87 | contextInfo, 88 | }, 89 | { 90 | quoted: m, 91 | }, 92 | ); 93 | }); 94 | }; 95 | 96 | neko.command = "tiktok"; 97 | neko.alias = ["tt", "ttdl", "tiktokdl"]; 98 | neko.category = ["downloader"]; 99 | neko.settings = { 100 | limit: true, 101 | }; 102 | neko.description = "📥 Download video atau slide dari TikTok."; 103 | neko.loading = true; 104 | 105 | module.exports = neko; 106 | -------------------------------------------------------------------------------- /system/plugins/downloader/ttsearch.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "tiktoksearch", 3 | alias: ["ttsearch"], 4 | category: ["downloader"], 5 | settings: { 6 | limit: true, 7 | }, 8 | description: "🔍 Cari video menarik dari TikTok berdasarkan kata kunci", 9 | loading: true, 10 | async run(m, { sock, Func, text, Scraper, config }) { 11 | if (!text) 12 | throw `❌ *– Kesalahan Penggunaan!*\n\n📌 *Cara Penggunaan:*\n1. Masukkan kata kunci untuk mencari video dari TikTok.\n2. Bot akan memberikan video yang relevan.\n\n📖 *Contoh:*\n> *${m.prefix}${m.command} kucing lucu*\n> *${m.prefix}${m.command} tutorial masak*`; 13 | 14 | let data = await Scraper.tiktok.search(text); 15 | if (!data || data.length === 0) 16 | throw `❌ *– Pencarian Gagal!*\n\n⚠️ Tidak ada hasil ditemukan untuk kata kunci: *${text}*.\n\n🔎 *Tips:*\n- Gunakan kata kunci yang lebih spesifik.\n- Pastikan ejaan kata kunci benar.\n\n📖 *Contoh:*\n> *${m.prefix}${m.command} video lucu*`; 17 | 18 | let json = data.getRandom(); 19 | let caption = `*– 乂 TikTok - Pencarian 🔍*\n\n`; 20 | caption += Object.entries(json.metadata) 21 | .map(([a, b]) => `- *📊 ${a.capitalize()}:* ${b}`) 22 | .join("\n"); 23 | 24 | await sock.sendMessage( 25 | m.cht, 26 | { 27 | video: { 28 | url: json.media.no_watermark || "Tidak tersedia", 29 | }, 30 | caption, 31 | }, 32 | { 33 | quoted: m, 34 | }, 35 | ); 36 | }, 37 | }; 38 | -------------------------------------------------------------------------------- /system/plugins/downloader/videy-dl.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "videy", 3 | alias: [], 4 | category: ["downloader"], 5 | description: "Download dan upload video dari Videy", 6 | loading: true, 7 | async run(m, { sock, Func, Uploader, text }) { 8 | if (!text) 9 | throw `╭──[❌ *Cara Penggunaan*]\n᎒⊸ *\`--upload\`* Untuk upload video ke Videy\n᎒⊸ *\`https://videy.co/xxx\`* Untuk download video dari Videy\n╰────────────•`; 10 | 11 | if (text.includes("--upload")) { 12 | let q = m.quoted ? m.quoted : m; 13 | if (!/video/.test(q.msg.mimetype) || !q.isMedia) 14 | throw `> Reply/kirim video dengan caption *${m.prefix + m.command} ${text}*`; 15 | 16 | let buffer = await q.download(); 17 | let hasil = await Uploader.videy(buffer); 18 | 19 | let cap = `╭──[📤 *Videy - Uploader*]\n᎒⊸ *Ukuran :* ${Func.formatSize(buffer.length)}\n᎒⊸ *Link :* ${hasil}\n╰────────────•`; 20 | m.reply(cap); 21 | } else { 22 | if (!Func.isUrl(text) || !/videy.co/.test(text)) 23 | throw "> Masukkan link Videy yang valid!"; 24 | 25 | let id = text.split("id=")[1]; 26 | if (!id) throw "> Link tidak memiliki ID, coba gunakan link lain."; 27 | 28 | let hasil = `https://cdn.videy.co/${id}.mp4`; 29 | let size = await Func.getSize(hasil); 30 | let limit = Func.sizeLimit(size, db.list().settings.max_upload); 31 | 32 | if (limit.oversize) 33 | throw `Ukuran file terlalu besar *( ${size} )*. Upgrade ke premium untuk mendownload video hingga ukuran *1GB*!`; 34 | 35 | let cap = `╭──[📥 *Videy - Downloader*]\n᎒⊸ *Ukuran Video :* ${size}\n╰────────────•`; 36 | m.reply({ 37 | video: { url: hasil }, 38 | caption: cap, 39 | }); 40 | } 41 | }, 42 | }; 43 | -------------------------------------------------------------------------------- /system/plugins/events/_alias-msg.js: -------------------------------------------------------------------------------- 1 | const { 2 | generateWAMessage, 3 | areJidsSameUser, 4 | proto 5 | } = require("baileys"); 6 | 7 | async function events(m, { 8 | sock 9 | }) { 10 | sock.sendAliasMessage = async (jid, mess = {}, alias = {}, quoted = null) => { 11 | function check(arr) { 12 | if (!Array.isArray(arr)) { 13 | return false; 14 | } 15 | if (!arr.length) { 16 | return false; 17 | } 18 | for (let i = 0; i < arr.length; i++) { 19 | const item = arr[i]; 20 | if (typeof item !== "object" || item === null) { 21 | return false; 22 | } 23 | if (!Object.prototype.hasOwnProperty.call(item, "alias")) { 24 | return false; 25 | } 26 | if (!Array.isArray(item.alias) && typeof item.alias !== "string") { 27 | return false; 28 | } 29 | if ( 30 | Object.prototype.hasOwnProperty.call(item, "response") && 31 | typeof item.response !== "string" 32 | ) { 33 | return false; 34 | } 35 | if ( 36 | Object.prototype.hasOwnProperty.call(item, "eval") && 37 | typeof item.eval !== "string" 38 | ) { 39 | return false; 40 | } 41 | } 42 | return true; 43 | } 44 | if (!check(alias)) return "Alias format is not valid!"; 45 | let message = await sock.sendMessage(jid, mess, { 46 | quoted: quoted 47 | }); 48 | if (typeof sock.alias[jid] === "undefined") 49 | sock.alias[jid] = {}; 50 | sock.alias[jid][message.key.id] = { 51 | chat: jid, 52 | id: message.key.id, 53 | alias, 54 | }; 55 | return message; 56 | }; 57 | sock.sendInputMessage = async ( 58 | jid, 59 | mess = {}, 60 | target = "all", 61 | timeout = 60000, 62 | quoted = null, 63 | ) => { 64 | let time = Date.now(); 65 | let message = await sock.sendMessage(jid, mess, { 66 | quoted: quoted 67 | }); 68 | if (typeof sock.input[jid] === "undefined") 69 | sock.input[jid] = {}; 70 | sock.input[jid][message.key.id] = { 71 | chat: jid, 72 | id: message.key.id, 73 | target, 74 | }; 75 | 76 | while ( 77 | Date.now() - time < timeout && 78 | !sock.input[jid][message.key.id].hasOwnProperty("input") 79 | ) 80 | await sock.delay(500); 81 | 82 | return sock.input[jid][message.key.id].input; 83 | }; 84 | 85 | if (typeof sock.alias === "undefined") 86 | sock.alias = {}; 87 | if (typeof sock.input === "undefined") 88 | sock.input = {}; 89 | 90 | if (m.quoted) { 91 | const quotedId = m.quoted.id; 92 | if ( 93 | sock.input[m.cht]?.[quotedId]?.target === "all" || 94 | sock.input[m.cht]?.[quotedId]?.target === m.sender 95 | ) { 96 | sock.input[m.cht][quotedId].input = m.body; 97 | } 98 | if (sock.alias.hasOwnProperty(m.cht)) { 99 | if (sock.alias[m.cht].hasOwnProperty(quotedId)) { 100 | for (const aliasObj of sock.alias[m.cht][quotedId].alias) { 101 | if ( 102 | Array.isArray(aliasObj.alias) && 103 | !aliasObj.alias 104 | .map((v) => v.toLowerCase()) 105 | .includes(m.body.toLowerCase()) 106 | ) 107 | continue; 108 | else if (aliasObj.alias.toLowerCase() !== m.body.toLowerCase()) 109 | continue; 110 | else { 111 | if (aliasObj.response) 112 | await m.emit(aliasObj.response); 113 | if (aliasObj.eval) await eval(aliasObj.eval); 114 | } 115 | } 116 | } 117 | } 118 | } 119 | }; 120 | 121 | module.exports = { 122 | events 123 | }; -------------------------------------------------------------------------------- /system/plugins/events/_button-resp.js: -------------------------------------------------------------------------------- 1 | async function events(m, { sock }) { 2 | if (m.type === "interactiveResponseMessage" && m.quoted.fromMe) { 3 | sock.appendTextMessage( 4 | m, 5 | JSON.parse(m.msg.nativeFlowResponseMessage.paramsJson).id, 6 | m, 7 | ); 8 | } 9 | if (m.type === "templateButtonReplyMessage" && m.quoted.fromMe) { 10 | sock.appendTextMessage(m, m.msg.selectedId, m); 11 | } 12 | } 13 | 14 | module.exports = { 15 | events, 16 | }; 17 | -------------------------------------------------------------------------------- /system/plugins/events/_eval.js: -------------------------------------------------------------------------------- 1 | const { exec } = require("child_process"); 2 | const util = require("node:util"); 3 | 4 | async function events( 5 | m, 6 | { 7 | sock, 8 | config, 9 | text, 10 | plugins, 11 | Func, 12 | Scraper, 13 | Uploader, 14 | store, 15 | isAdmin, 16 | botAdmin, 17 | isPrems, 18 | isBanned, 19 | }, 20 | ) { 21 | if ( 22 | [">", "eval", "=>"].some((a) => m.command.toLowerCase().startsWith(a)) && 23 | m.isOwner 24 | ) { 25 | let evalCmd = ""; 26 | try { 27 | evalCmd = /await/i.test(m.text) 28 | ? eval("(async() => { " + m.text + " })()") 29 | : eval(m.text); 30 | } catch (e) { 31 | evalCmd = e; 32 | } 33 | new Promise((resolve, reject) => { 34 | try { 35 | resolve(evalCmd); 36 | } catch (err) { 37 | reject(err); 38 | } 39 | }) 40 | ?.then((res) => m.reply(util.format(res))) 41 | ?.catch((err) => m.reply(util.format(err))); 42 | } 43 | if ( 44 | ["$", "exec"].some((a) => m.command.toLowerCase().startsWith(a)) && 45 | m.isOwner 46 | ) { 47 | try { 48 | exec(m.text, async (err, stdout) => { 49 | if (err) return m.reply(util.format(err)); 50 | if (stdout) return m.reply(util.format(stdout)); 51 | }); 52 | } catch (e) { 53 | await m.reply(util.format(e)); 54 | } 55 | } 56 | } 57 | 58 | module.exports = { 59 | events, 60 | }; 61 | -------------------------------------------------------------------------------- /system/plugins/events/antilink.js: -------------------------------------------------------------------------------- 1 | const { getUrlInfo } = require("baileys"); 2 | 3 | async function events(m, { sock, Func }) { 4 | if (!m.isGroup) return; 5 | let group = db.list().group[m.cht]; 6 | if (Func.isUrl(m.body) && /chat.whatsapp.com/.test(m.body)) { 7 | if (!m.isBotAdmin || m.isAdmin) return; 8 | let msg = `*🚫 Link Grup Terdeteksi!*\n\n`; 9 | msg += m.isAdmin 10 | ? `> Anda aman karena Anda adalah admin dari grup *${m.metadata.subject}*.\n\nTerima kasih telah mematuhi aturan grup! 😊` 11 | : `> Maaf, mengirim link grup lain tidak diperbolehkan di grup *${m.metadata.subject}*.\n\nPesan Anda akan dihapus untuk menjaga keamanan dan kenyamanan bersama. Terima kasih atas pengertiannya! 🙏`; 12 | 13 | await m.reply(msg); 14 | await sock.sendMessage(m.cht, { delete: m.key }); 15 | } 16 | } 17 | 18 | module.exports = { 19 | events, 20 | }; 21 | -------------------------------------------------------------------------------- /system/plugins/group/add.js: -------------------------------------------------------------------------------- 1 | const bail = require("baileys"); 2 | const { generateWAMessageFromContent, proto, toNumber } = bail; 3 | 4 | module.exports = { 5 | command: "add", 6 | alias: [], 7 | category: ["group"], 8 | settings: { 9 | group: true, 10 | admin: true, 11 | botAdmin: true, 12 | }, 13 | description: "Menambahkan anggota ke grup", 14 | async run(m, { sock, text, Func }) { 15 | const input = text ? text : m.quoted ? m.quoted.sender : m.mentions[0] 16 | if (!input) { 17 | throw "❗ *Format Salah*\nKirim perintah ini dengan format:\n> Ketik nomor pengguna yang ingin ditambahkan\n> Atau reply pesan pengguna dengan perintah ini."; 18 | } 19 | 20 | const p = await sock.onWhatsApp(input.trim()); 21 | console.log(p); 22 | if (!p[0].exists) throw "⚠️ Pengguna tidak terdaftar di WhatsApp" 23 | const jid = p[0].jid 24 | const member = m.metadata.participants.find((u) => u.id === jid); 25 | if (member) { 26 | return m.reply("⚠️ Pengguna tersebut sudah menjadi anggota grup ini."); 27 | } 28 | 29 | const resp = await sock.groupParticipantsUpdate(m.cht, [jid], "add"); 30 | for (let res of resp) { 31 | if (res.status === 421) { 32 | m.reply( 33 | "⚠️ Tidak dapat menambahkan pengguna tersebut. Mereka telah membatasi undangan ke grup.", 34 | ); 35 | } else if (res.status === 408) { 36 | await m.reply( 37 | `✅ Undangan grup berhasil dikirim ke @${parseInt(res.jid)} karena pengguna baru saja keluar dari grup.`, 38 | ); 39 | await sock.sendMessage(res.jid, { 40 | text: 41 | "✨ Anda diundang kembali ke grup ini: https://chat.whatsapp.com/" + 42 | (await sock.groupInviteCode(m.cht)), 43 | }); 44 | } else if (res.status === 403) { 45 | await m.reply( 46 | `✅ Undangan grup berhasil dikirim ke @${parseInt(res.jid)}.`, 47 | ); 48 | const { code, expiration } = res.content.content[0].attrs; 49 | const pp = await sock.profilePictureUrl(m.cht).catch(() => null); 50 | const gp = await Func.fetchBuffer(pp); 51 | 52 | const msgs = generateWAMessageFromContent( 53 | res.jid, 54 | proto.Message.fromObject({ 55 | groupInviteMessage: { 56 | groupJid: m.cht, 57 | inviteCode: code, 58 | inviteExpiration: toNumber(expiration), 59 | groupName: m.metadata.subject, 60 | jpegThumbnail: gp || null, 61 | caption: `🌟 Hai @${res.jid.split("@")[0]}!\nAnda telah diundang oleh salah satu admin grup *${m.metadata.subject}*. Klik tombol di bawah untuk bergabung kembali!`, 62 | }, 63 | }), 64 | { userJid: sock.user.jid }, 65 | ); 66 | 67 | await sock.copyNForward(jid, msgs); 68 | } 69 | } 70 | }, 71 | }; 72 | -------------------------------------------------------------------------------- /system/plugins/group/demote.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "demote", 3 | alias: ["jadimember"], 4 | category: ["group"], 5 | settings: { 6 | group: true, 7 | admin: true, 8 | botAdmin: true, 9 | }, 10 | description: "🔻 Menurunkan admin menjadi anggota biasa di grup", 11 | async run(m, { sock, text }) { 12 | let who = m.quoted 13 | ? m.quoted.sender 14 | : m.mentions.length > 0 15 | ? m.mentions[0] 16 | : false; 17 | 18 | if (!who) { 19 | throw `*⚠️ Perintah Tidak Lengkap!*\n\n> *Gunakan salah satu cara berikut:*\n • Tag member dengan: @username\n • Balas pesan member yang ingin diturunkan.\n\n📌 _Pastikan kamu memiliki hak sebagai admin grup._`; 20 | } 21 | 22 | let user = await sock.onWhatsApp(who); 23 | if (!user[0].exists) { 24 | throw `*❌ Member Tidak Ditemukan!*\n\n> Akun WhatsApp ini tidak terdaftar atau sudah tidak aktif.`; 25 | } 26 | 27 | await sock 28 | .groupParticipantsUpdate(m.cht, [who], "demote") 29 | .then(() => { 30 | m.reply( 31 | `*✅ Berhasil!* 🎉\n\n> Jabatan @${who.split("@")[0]} telah diturunkan menjadi anggota biasa.\n\n📌 _Gunakan perintah ini dengan bijak untuk menjaga keharmonisan grup._`, 32 | ); 33 | }) 34 | .catch((err) => { 35 | m.reply( 36 | `*❌ Gagal!*\n\n> Tidak dapat menurunkan jabatan admin untuk @${who.split("@")[0]}.\n📌 _Pastikan bot memiliki hak admin untuk melakukan perubahan ini._`, 37 | ); 38 | }); 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /system/plugins/group/hidetag.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxellNetwork/NekoBot/272a81353642d5bc00b59da02f1c91fdf5bb7ff2/system/plugins/group/hidetag.js -------------------------------------------------------------------------------- /system/plugins/group/kick.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "kick", 3 | alias: ["kik", "dor", "tendang"], 4 | category: ["group"], 5 | settings: { 6 | group: true, 7 | admin: true, 8 | botAdmin: true, 9 | }, 10 | description: "🔴 Mengeluarkan anggota dari grup", 11 | async run(m, { sock, text }) { 12 | let who = m.quoted 13 | ? m.quoted.sender 14 | : m.mentions.length > 0 15 | ? m.mentions[0] 16 | : false; 17 | 18 | if (!who) { 19 | throw `*⚠️ Perintah Tidak Lengkap!*\n\n> *Gunakan salah satu cara berikut:*\n • Tag anggota dengan: @username\n • Balas pesan anggota yang ingin dikeluarkan.\n\n📌 _Pastikan kamu memiliki hak sebagai admin grup._`; 20 | } 21 | 22 | let user = await sock.onWhatsApp(who); 23 | if (!user[0].exists) { 24 | throw `*❌ Anggota Tidak Ditemukan!*\n\n> Akun WhatsApp ini tidak terdaftar atau sudah tidak aktif.`; 25 | } 26 | 27 | await sock 28 | .groupParticipantsUpdate(m.cht, [who], "remove") 29 | .then(() => { 30 | m.reply( 31 | `*✅ Berhasil!* 🥾\n\n> @${who.split("@")[0]} telah dikeluarkan dari grup.\n\n📌 _Gunakan fitur ini untuk menjaga kenyamanan grup._`, 32 | ); 33 | }) 34 | .catch((err) => { 35 | m.reply( 36 | `*❌ Gagal!*\n\n> Tidak dapat mengeluarkan @${who.split("@")[0]} dari grup.\n📌 _Pastikan bot memiliki hak admin untuk melakukan perubahan ini._`, 37 | ); 38 | }); 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /system/plugins/group/linkgc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "link", 3 | alias: ["linkgc"], 4 | category: ["group"], 5 | settings: { 6 | group: true, 7 | botAdmin: true, 8 | }, 9 | description: "🔗 Mendapatkan tautan undangan grup", 10 | async run(m, { sock }) { 11 | try { 12 | let link = 13 | "https://chat.whatsapp.com/" + (await sock.groupInviteCode(m.cht)); 14 | let caption = `*– 乂 Informasi Tautan Grup*\n\n`; 15 | caption += `> *- Nama Grup :* ${m.metadata.subject}\n`; 16 | caption += `> *- Tautan :* ${link}\n\n`; 17 | caption += `📌 _Gunakan tautan ini dengan bijak untuk menjaga keamanan grup._`; 18 | 19 | m.reply(caption); 20 | } catch (error) { 21 | m.reply( 22 | `*❌ Gagal Mendapatkan Link!*\n\n> Pastikan bot memiliki hak admin untuk membuat tautan grup.`, 23 | ); 24 | } 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /system/plugins/group/promote.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "promote", 3 | alias: ["jadiadmin", "newking"], 4 | category: ["group"], 5 | settings: { 6 | group: true, 7 | admin: true, 8 | botAdmin: true, 9 | }, 10 | description: "👑 Menjadikan member sebagai admin grup", 11 | async run(m, { sock, text }) { 12 | let who = m.quoted 13 | ? m.quoted.sender 14 | : m.mentions.length > 0 15 | ? m.mentions[0] 16 | : false; 17 | 18 | if (!who) 19 | throw `*🚫 Perintah Gagal!*\n\n> Tag atau balas pesan member yang ingin dijadikan admin.`; 20 | 21 | let user = await sock.onWhatsApp(who); 22 | if (!user[0].exists) 23 | throw `*❌ Error!*\n\n> Nomor tersebut tidak terdaftar di WhatsApp.`; 24 | 25 | await sock 26 | .groupParticipantsUpdate(m.cht, [who], "promote") 27 | .then(() => { 28 | let name = who.split("@")[0]; 29 | m.reply( 30 | `*✅ Promosi Berhasil!*\n\n> 🎉 Selamat kepada *@${name}* karena telah menjadi admin grup!\n\n📌 _Gunakan jabatan ini dengan bijak._`, 31 | { mentions: [who] }, 32 | ); 33 | }) 34 | .catch(() => { 35 | m.reply( 36 | `*❌ Gagal Memproses!*\n\n> Pastikan bot memiliki hak admin untuk melakukan perubahan ini.`, 37 | ); 38 | }); 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /system/plugins/group/revoke.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "resetlink", 3 | alias: ["revoke"], 4 | category: ["group"], 5 | settings: { 6 | group: true, 7 | admin: true, 8 | botAdmin: true, 9 | }, 10 | description: "🔗 Mereset ulang link undangan grup", 11 | async run(m, { sock }) { 12 | try { 13 | const newLink = await sock.groupRevokeInvite(m.cht); 14 | m.reply( 15 | `*✅ Link Grup Berhasil Direset!*\n\n> 🔗 *Link Baru:* https://chat.whatsapp.com/${newLink}\n\n📌 _Silakan bagikan link ini kepada anggota baru._`, 16 | ); 17 | } catch (err) { 18 | m.reply( 19 | `*❌ Gagal Mereset Link!*\n\n> Pastikan bot memiliki hak admin untuk melakukan perubahan ini.`, 20 | ); 21 | } 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /system/plugins/group/setdesc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "setdeskripsi", 3 | alias: ["setdesc"], 4 | category: ["group"], 5 | settings: { 6 | group: true, 7 | admin: true, 8 | botAdmin: true, 9 | }, 10 | description: "📝 Mengganti deskripsi grup dengan teks baru", 11 | async run(m, { sock, text }) { 12 | if (!text) 13 | throw "⚠️ *Silakan masukkan deskripsi grup baru!*\n\n💡 Contoh: setdesc Grup Diskusi Seru."; 14 | if (text.length > 200) 15 | throw "❌ *Deskripsi terlalu panjang!*\nMaksimal 200 karakter."; 16 | 17 | await sock.groupUpdateDescription(m.cht, text.trim()); 18 | m.reply( 19 | `✅ *Deskripsi Grup Berhasil Diperbarui!*\n\n📝 *Deskripsi Baru:*\n${text.trim()}`, 20 | ); 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /system/plugins/group/setnamegc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "setnamegroup", 3 | alias: ["setnamegc"], 4 | category: ["group"], 5 | settings: { 6 | group: true, 7 | admin: true, 8 | botAdmin: true, 9 | }, 10 | description: "📝 Mengubah nama grup ke nama yang baru", 11 | async run(m, { sock, text }) { 12 | if (!text) 13 | throw "⚠️ *Silakan masukkan nama grup baru!*\n\n💡 Contoh: setnamegc Grup Santai."; 14 | if (text.length > 20) 15 | throw "❌ *Nama grup terlalu panjang!*\nMaksimal 20 karakter."; 16 | 17 | await sock.groupUpdateSubject(m.cht, text.trim()); 18 | m.reply( 19 | `✅ *Nama grup berhasil diubah!* \n\n📝 *Nama Grup Baru:*\n${text.trim()}`, 20 | ); 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /system/plugins/group/setpp.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "setppgroup", 3 | alias: ["setppgc"], 4 | category: ["group"], 5 | settings: { 6 | group: true, 7 | admin: true, 8 | botAdmin: true, 9 | }, 10 | description: "📸 Mengubah foto profil grup", 11 | async run(m, { sock }) { 12 | let q = m.quoted ? m.quoted : m; 13 | if (!q.isMedia) 14 | throw "⚠️ *Silakan kirim atau reply foto yang ingin dijadikan foto profil grup!*"; 15 | 16 | let buffer = await q.download(); 17 | await sock 18 | .updateProfilePicture(m.cht, buffer) 19 | .then(() => m.reply("> ✅ *Foto profil grup berhasil diperbarui!*")); 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /system/plugins/group/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "gcsetting", 3 | alias: ["groupsetting", "settingc"], 4 | category: ["group"], 5 | settings: { 6 | group: true, 7 | admin: true, 8 | botAdmin: true, 9 | }, 10 | description: "🔒 Mengatur Akses Grup: Membuka/Tutup Grup", 11 | loading: true, 12 | async run(m, { sock, text }) { 13 | if (!text) 14 | throw `*– 乂 Cara Penggunaan:*\n 15 | > *🔓* Gunakan \`open\` untuk membuka grup. Member dapat mengirim pesan dan berinteraksi dengan bebas.\n 16 | > *🔒* Gunakan \`close\` untuk menutup grup. Hanya admin yang dapat mengirim pesan, member akan dibatasi.\n\n 17 | *– 乂 Contoh Penggunaan:*\n 18 | > *-* *${m.prefix + m.command} open* - Untuk membuka grup\n 19 | > *-* *${m.prefix + m.command} close* - Untuk menutup grup\n\n 20 | *– 乂 Penting!*\n 21 | > *📌* Jika grup dibuka, semua member dapat berinteraksi.\n 22 | > *📌* Jika grup ditutup, hanya admin yang dapat mengirim pesan.`; 23 | 24 | await sock 25 | .groupSettingUpdate( 26 | m.cht, 27 | text === "open" ? "not_announcement" : "announcement", 28 | ) 29 | .then(() => 30 | m.reply( 31 | `> ✅ *Berhasil ${text === "open" ? "membuka" : "menutup"} grup!* ${text === "open" ? "Sekarang member bisa mengirim pesan." : "Hanya admin yang dapat mengirim pesan sekarang."}`, 32 | ), 33 | ); 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /system/plugins/info/ci.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "cinfo", 3 | alias: ["channelinfo", "ci"], 4 | category: ["info"], 5 | description: 6 | "ℹ️ Dapatkan informasi lengkap tentang saluran WhatsApp melalui tautan", 7 | loading: true, 8 | 9 | async run(m, { sock, Func, text, config }) { 10 | if (!text || !Func.isUrl(text) || !/whatsapp.com\/channel/.test(text)) { 11 | return m.reply( 12 | "> ❌ *Kirim atau balas tautan saluran WhatsApp yang valid!*\n\n" + 13 | "*Contoh Penggunaan:*\n" + 14 | "> _${m.prefix}cinfo https://whatsapp.com/channel/example_", 15 | ); 16 | } 17 | 18 | try { 19 | m.reply(config.messages.wait); 20 | 21 | let id = text 22 | .replace(/https:\/\/(www\.)?whatsapp\.com\/channel\//, "") 23 | .split("/")[0]; 24 | let metadata = await sock.newsletterMetadata("invite", id); 25 | 26 | if (!metadata) { 27 | return m.reply( 28 | "> ❌ *Gagal mendapatkan metadata saluran.*\nPastikan tautan yang diberikan benar.", 29 | ); 30 | } 31 | 32 | let cap = `*✨ Informasi Saluran WhatsApp*\n\n`; 33 | cap += `📌 *ID Saluran:* ${metadata.id}\n`; 34 | cap += `📛 *Nama Saluran:* ${metadata.name}\n`; 35 | cap += `👥 *Pengikut:* ${Func.h2k(metadata.subscribers)}\n`; 36 | cap += `⏳ *Dibuat Pada:* ${new Date(metadata.creation_time * 1000).toLocaleString("id-ID")}\n`; 37 | 38 | if (metadata.preview) { 39 | m.reply({ 40 | image: { url: "https://pps.whatsapp.net" + metadata.preview }, 41 | caption: cap, 42 | }); 43 | } else { 44 | m.reply(cap); 45 | } 46 | } catch (error) { 47 | console.error("Error:", error); 48 | m.reply( 49 | "> ❌ *Terjadi kesalahan saat mengambil informasi saluran.*\n" + 50 | "Silakan coba lagi nanti.", 51 | ); 52 | } 53 | }, 54 | }; 55 | -------------------------------------------------------------------------------- /system/plugins/info/listgroup.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "listgroup", 3 | alias: ["gcl", "listgroup"], 4 | category: ["info"], 5 | settings: { 6 | limit: true, 7 | owner: true, 8 | }, 9 | description: "📋 Menampilkan daftar grup yang dikelola oleh bot", 10 | async run(m, { sock, Func, store }) { 11 | let data = Object.values(store.groupMetadata); 12 | let cap = "*– 乂 Daftar Group Bot*\n\n"; 13 | cap += `> 📊 *Total Grup:* ${data.length}\n\n`; 14 | 15 | if (data.length === 0) { 16 | return m.reply("> ❌ *Tidak ada grup yang terdaftar di bot ini.*"); 17 | } 18 | 19 | cap += data 20 | .sort((a, b) => b.creation - a.creation) 21 | .map((a, i) => { 22 | let owner = a.owner ? "@" + a.owner.split("@")[0] : "Tidak ada pemilik"; 23 | return ( 24 | `> *${i + 1}.* ${a.subject}\n` + 25 | `> ⏳ *Dibuat:* ${Func.ago(a.creation * 1000)}\n` + 26 | `> 👥 *Jumlah Member:* ${a.size}\n` + 27 | `> 👑 *Pemilik:* ${owner}` 28 | ); 29 | }) 30 | .join("\n\n"); 31 | 32 | m.reply(cap); 33 | }, 34 | }; 35 | -------------------------------------------------------------------------------- /system/plugins/info/script.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | module.exports = { 4 | command: "script", 5 | alias: ["sc", "scbot"], 6 | category: ["info"], 7 | description: "📜 Dapatkan Script Bot Secara Gratis", 8 | async run(m, { sock, Func }) { 9 | let data = await axios 10 | .get("https://api.github.com/repos/AxellNetwork/NekoBot") 11 | .then((a) => a.data); 12 | 13 | let cap = "*– 乂 Informasi - Script Bot*\n\n"; 14 | cap += `> 🧩 *Nama:* ${data.name}\n`; 15 | cap += `> 👤 *Pemilik:* ${data.owner.login}\n`; 16 | cap += `> ⭐ *Star:* ${data.stargazers_count}\n`; 17 | cap += `> 🍴 *Forks:* ${data.forks}\n`; 18 | cap += `> 📅 *Dibuat sejak:* ${Func.ago(data.created_at)}\n`; 19 | cap += `> 🔄 *Terakhir Update:* ${Func.ago(data.updated_at)}\n`; 20 | cap += `> 🔄 *Terakhir Publish:* ${Func.ago(data.pushed_at)}\n`; 21 | cap += `> 🔗 *Link Repository:* ${data.html_url}\n\n`; 22 | cap += 23 | "🔧 *Fitur Utama Script Bot:*\n" + 24 | "> ✅ *Support Case x Plugins*\n" + 25 | "> ✅ *Ukuran Script Ringan*\n" + 26 | "> ✅ *100% Menggunakan Scrape*\n" + 27 | "> ✅ *Respon Polling & Edit*\n" + 28 | "> ✅ *Auto Reload File Scrape*\n" + 29 | "> ✅ *Support Run Di Mana Saja*\n\n"; 30 | cap += 31 | "Script ini gratis, boleh kalian recode dan jual asal jangan hapus credit original dari kami!"; 32 | 33 | m.reply(cap); 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /system/plugins/info/tqto.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "tqto", 3 | alias: ["credit"], 4 | category: ["info"], 5 | description: "📜 Daftar Kontributor Bot Ini", 6 | async run(m) { 7 | let cap = `*– 乂 Terima Kasih Kepada*\n\n`; 8 | cap += `> 🙌 *Bang_syaii*\n`; 9 | cap += `> 🛠️ *Peran:* Pembuat Script & Scraper Bot\n`; 10 | cap += `> 🔗 *Telegram:* [Klik di sini](https://t.me/this_syaii)\n\n`; 11 | cap += `> 🙌 *AxellNetwork*\n`; 12 | cap += `> 🛠️ *Peran:* Pengembang Script & Scraper Bot\n`; 13 | cap += `> 🔗 *GitHub:* [Klik di sini](https://github.com/AxellNetwork)\n\n`; 14 | cap += `> 🙌 *Pengguna Script*\n`; 15 | cap += `> ❤️ Kalian semua yang sudah mendukung dan menggunakan script ini!\n\n`; 16 | cap += `📜 *Ucapan Terima Kasih*\n`; 17 | cap += `Terima kasih telah menggunakan script ini. Semoga bermanfaat bagi Anda, baik yang menggunakan maupun tidak menggunakan.\n\n`; 18 | cap += `🌟 *Dukung Proyek Kami Lainnya:*\n`; 19 | cap += `🔗 [GitHub AxellNetwork](https://github.com/AxellNetwork)\n\n`; 20 | cap += `*– Forum & Komunitas*\n`; 21 | cap += `> 📢 [Forum Update](https://whatsapp.com/channel/0029VauJgduEwEjwwVwLnw37)\n`; 22 | cap += `> 💬 [Join Grup](https://chat.whatsapp.com/BsZHPiZoisT5GdVgiEufJK)`; 23 | 24 | m.reply(cap); 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /system/plugins/islam/alif.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const cheerio = require("cheerio"); 3 | 4 | async function alifSearch(query) { 5 | try { 6 | const { data } = await axios.get("https://alif.id/?s=" + query); 7 | const $ = cheerio.load(data); 8 | const results = []; 9 | 10 | $(".post.style3").each((index, element) => { 11 | const title = $(element).find(".post-title h5 a span").text().trim(); 12 | const link = $(element).find(".post-title h5 a").attr("href"); 13 | const author = $(element).find(".post-author a").text().trim(); 14 | const authorLink = $(element).find(".post-author a").attr("href"); 15 | const date = $(element).find(".post-date").text().trim(); 16 | const category = 17 | $(element).find(".post-category a").text().trim() || 18 | "Tidak ada kategori"; 19 | const categoryLink = 20 | $(element).find(".post-category a").attr("href") || 21 | "Tidak ada link kategori"; 22 | const image = 23 | $(element).find("figure.post-gallery img").attr("data-src") || 24 | "Tidak ada gambar"; 25 | 26 | results.push({ 27 | title, 28 | link, 29 | author, 30 | authorLink, 31 | date, 32 | category, 33 | categoryLink, 34 | image, 35 | }); 36 | }); 37 | 38 | return results.length > 0 ? results : null; 39 | } catch (error) { 40 | throw new Error( 41 | "Gagal mengambil data dari Alif.id. Pastikan koneksi Anda stabil.", 42 | ); 43 | } 44 | } 45 | 46 | class Command { 47 | constructor() { 48 | this.command = "alif"; 49 | this.alias = []; 50 | this.category = ["islam"]; 51 | this.settings = { limit: true }; 52 | this.description = "🔍 Cari informasi Islami dari Alif.id"; 53 | this.loading = true; 54 | } 55 | 56 | run = async (m, { text }) => { 57 | if (!text) throw "> Masukkan kata kunci untuk pencarian."; 58 | try { 59 | let data = await alifSearch(text); 60 | if (!data) throw "> Tidak ada hasil ditemukan untuk pencarian Anda."; 61 | 62 | let caption = `*– 乂 Alif - Pencarian*\n\n`; 63 | caption += data 64 | .map( 65 | (item, index) => 66 | `*${index + 1}. ${item.title}*\n> 🔗 *Link:* ${item.link}\n> ✍️ *Penulis:* [${item.author}](${item.authorLink})\n> 📅 *Tanggal:* ${item.date}\n> 🗂️ *Kategori:* [${item.category}](${item.categoryLink})\n> 🖼️ *Gambar:* ${item.image}`, 67 | ) 68 | .join("\n\n"); 69 | 70 | m.reply(caption); 71 | } catch (error) { 72 | m.reply(`> Terjadi kesalahan:\n${error.message}`); 73 | } 74 | }; 75 | } 76 | 77 | module.exports = new Command(); 78 | -------------------------------------------------------------------------------- /system/plugins/owner/backup.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const { exec } = require("child_process"); 3 | const cp = require("child_process"); 4 | const { promisify } = require("util"); 5 | let exec_ = promisify(exec).bind(cp); 6 | 7 | module.exports = { 8 | command: "backup", 9 | alias: [], 10 | category: ["owner"], 11 | settings: { 12 | owner: true, 13 | }, 14 | description: "Backup script bot Neko", 15 | async run(m, { sock, text }) { 16 | try { 17 | let zipFileName = `Backup.zip`; 18 | 19 | m.reply("Sedang memulai proses backup. Harap tunggu..."); 20 | 21 | setTimeout(() => { 22 | let zipCommand = `zip -r ${zipFileName} * -x "node_modules/*"`; 23 | exec_(zipCommand, (err, stdout) => { 24 | if (err) { 25 | m.reply("Terjadi kesalahan saat membuat file zip."); 26 | console.error(err); 27 | return; 28 | } 29 | 30 | setTimeout(() => { 31 | if (fs.existsSync(zipFileName)) { 32 | const file = fs.readFileSync(zipFileName); 33 | sock.sendMessage( 34 | m.sender, 35 | { 36 | document: file, 37 | mimetype: "application/zip", 38 | fileName: zipFileName, 39 | caption: "Backup selesai. Silakan unduh file backup.", 40 | }, 41 | { quoted: m } 42 | ); 43 | 44 | setTimeout(() => { 45 | fs.unlinkSync(zipFileName); 46 | m.reply("File backup telah dihapus."); 47 | }, 5000); 48 | } else { 49 | m.reply("File zip tidak ditemukan."); 50 | } 51 | }, 60000); // Wait for 1 minute to ensure the zip file is created 52 | }); 53 | }, 1000); 54 | } catch (error) { 55 | m.reply("Terjadi kesalahan saat melakukan backup."); 56 | console.error(error); 57 | } 58 | }, 59 | }; 60 | -------------------------------------------------------------------------------- /system/plugins/owner/broadcast.js: -------------------------------------------------------------------------------- 1 | const { 2 | delay 3 | } = require("baileys"); 4 | const DELAY = 10000; 5 | 6 | module.exports = { 7 | command: "broadcast", 8 | alias: ["bc"], 9 | settings: { 10 | owner: true 11 | }, 12 | description: "Mengirim pesan ke semua kontak atau grup", 13 | async run(m, { 14 | sock, 15 | store, 16 | text 17 | }) { 18 | if (!text) { 19 | throw `*╭──[ 📝 BROADCAST - USAGE ]* 20 | ᎒⊸ Masukkan pesan yang ingin di-broadcast. 21 | ᎒⊸ Reply media jika ingin mengirim pesan dengan media. 22 | ᎒⊸ Gunakan *\`--group\`* untuk mengirim pesan ke semua grup. 23 | *╰────────────•*`; 24 | } 25 | 26 | const MSG = Object.keys(store.messages); 27 | const groupChats = MSG.filter((id) => id.endsWith("@g.us")); 28 | const privateChats = MSG.filter((id) => id.endsWith("@s.whatsapp.net")); 29 | 30 | if (text.includes("--group")) { 31 | let input = text.replace("--group", "").trim(); 32 | if (!groupChats.length) 33 | throw "*❌ Tidak ada grup ditemukan untuk broadcast.*"; 34 | let q = m.quoted || m; 35 | let Msg = sock.cMod(m.cht, q, input); 36 | 37 | let successCount = 0; 38 | for (let groupId of groupChats) { 39 | try { 40 | await sock.copyNForward(groupId, Msg, true); 41 | successCount++; 42 | } catch (error) { 43 | console.error(`❌ Gagal mengirim ke grup ${groupId}:`, error.message); 44 | } 45 | } 46 | m.reply( 47 | `*╭──[ 乂 BROADCAST - GRUP ]* 48 | ᎒⊸ Total Grup: *${groupChats.length}* 49 | ᎒⊸ Berhasil Terkirim: *${successCount}* 50 | *╰────────────•*`, 51 | ); 52 | } else { 53 | if (!privateChats.length) 54 | throw "*❌ Tidak ada kontak ditemukan untuk broadcast.*"; 55 | let q = m.quoted || m; 56 | let Msg = sock.cMod(m.cht, q, text); 57 | 58 | let successCount = 0; 59 | for (let contactId of privateChats) { 60 | try { 61 | await sock.copyNForward(contactId, Msg, true); 62 | successCount++; 63 | } catch (error) { 64 | console.error( 65 | `❌ Gagal mengirim ke kontak ${contactId}:`, 66 | error.message, 67 | ); 68 | } 69 | } 70 | m.reply( 71 | `*╭──[ 乂 BROADCAST - USER ]* 72 | ᎒⊸ Total Kontak: *${privateChats.length}* 73 | ᎒⊸ Berhasil Terkirim: *${successCount}* 74 | *╰────────────•*`, 75 | ); 76 | } 77 | }, 78 | }; -------------------------------------------------------------------------------- /system/plugins/owner/clearchat.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "clearchat"; 4 | this.alias = []; 5 | this.category = ["owner"]; 6 | this.settings = { owner: true }; 7 | this.description = "Membersihkan semua pesan di grup"; 8 | this.loading = true; 9 | } 10 | 11 | run = async (m, { sock, store }) => { 12 | const groupIds = Object.keys(store.groupMetadata); 13 | if (groupIds.length === 0) { 14 | throw `*❌ Tidak ada grup ditemukan untuk membersihkan pesan.*`; 15 | } 16 | let successCount = 0; 17 | for (let id of groupIds) { 18 | try { 19 | await sock.clearMessage(id, m.key, m.timestamps); 20 | successCount++; 21 | } catch (err) { 22 | console.error(`❌ Gagal membersihkan chat grup ${id}:`, err.message); 23 | } 24 | } 25 | 26 | m.reply( 27 | `*╭──[ 乂 CLEAR CHAT - GRUP ]* 28 | ᎒⊸ Total Grup: *${groupIds.length}* 29 | ᎒⊸ Berhasil Dibersihkan: *${successCount}* 30 | *✔️ Semua pesan di grup berhasil dibersihkan!* 31 | *╰────────────•*`, 32 | ); 33 | }; 34 | } 35 | 36 | module.exports = new Command(); 37 | -------------------------------------------------------------------------------- /system/plugins/owner/example.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "example", 3 | alias: ["exp"], 4 | settings: { 5 | owner: true, 6 | }, 7 | description: "Fitur Contoh Bot", 8 | async run(m, { text }) { 9 | const title = `*╭──[ 乂 Example - Code ]*`; 10 | const message = `${title}\n᎒⊸ Pilih tipe *1* atau *2* sesuai kebutuhan Anda.\n╰────────────•`; 11 | 12 | if (!text) { 13 | return m.reply({ 14 | poll: { 15 | name: message, 16 | values: [`${m.prefix + m.command} 1`, `${m.prefix + m.command} 2`], 17 | selectableCount: 1, 18 | }, 19 | }); 20 | } 21 | 22 | // Validasi input 23 | const option = Number(text); 24 | if (option === 1) { 25 | const code = ` 26 | class Command { 27 | constructor() { 28 | this.command = ""; 29 | this.alias = []; 30 | this.category = []; 31 | this.settings = {}; 32 | this.description = ""; 33 | this.loading = true; 34 | } 35 | run = async (m, { sock, Func, Scraper, config, store }) => { 36 | // Lakukan sesuatu di sini 37 | }; 38 | } 39 | 40 | module.exports = new Command();`; 41 | return m.reply(`*– 乂 Tipe 1 - Code*\n\`\`\`${code}\`\`\``); 42 | } else if (option === 2) { 43 | const code = ` 44 | module.exports = { 45 | command: "", 46 | alias: [], 47 | category: [], 48 | settings: {}, 49 | description: "", 50 | loading: true, 51 | async run(m, { sock, Func, Scraper, Uploader, store, text, config }) { 52 | // Lakukan sesuatu di sini 53 | }, 54 | };`; 55 | return m.reply(`*– 乂 Tipe 2 - Code*\n\`\`\`${code}\`\`\``); 56 | } else { 57 | return m.reply({ 58 | poll: { 59 | name: `${message}\n\n> ❌ Pilihan tidak valid, silakan pilih antara 1 atau 2.`, 60 | values: [`${m.prefix + m.command} 1`, `${m.prefix + m.command} 2`], 61 | selectableCount: 1, 62 | }, 63 | }); 64 | } 65 | }, 66 | }; 67 | -------------------------------------------------------------------------------- /system/plugins/owner/join.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "join", 3 | alias: [], 4 | category: ["owner"], 5 | settings: { 6 | owner: true, 7 | }, 8 | description: "Memasukkan bot ke dalam grup menggunakan tautan undangan.", 9 | async run(m, { sock, text, Func }) { 10 | const errorMsg = `╭──[ 乂 Invalid - Link ]\n᎒⊸ Masukkan tautan grup yang valid!\n╰────────────•`; 11 | p; 12 | if (!text || !Func.isUrl(text) || !/chat\.whatsapp\.com\/\S+/i.test(text)) { 13 | throw errorMsg; 14 | } 15 | const groupId = text.split("chat.whatsapp.com/")[1]; 16 | if (!groupId) throw errorMsg; 17 | 18 | try { 19 | const result = await sock.groupAcceptInvite(groupId); 20 | const successMsg = `╭──[ 乂 Success - Join ]\n᎒⊸ Bot berhasil bergabung ke dalam grup!\n╰────────────•`; 21 | const pendingMsg = `╭──[ 乂 Pending - Request ]\n᎒⊸ Permintaan bergabung sedang diproses oleh admin grup.\n╰────────────•`; 22 | 23 | m.reply(result ? successMsg : pendingMsg); 24 | } catch (error) { 25 | const errorMsg = `╭──[ 乂 Error - Join ]\n᎒⊸ Terjadi kesalahan saat mencoba bergabung:\n${error.message}\n╰────────────•`; 26 | m.reply(errorMsg); 27 | } 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /system/plugins/owner/plugins.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const jsBeautify = require("js-beautify"); 3 | 4 | module.exports = { 5 | command: "plugins", 6 | alias: ["plugin"], 7 | category: ["owner"], 8 | settings: { 9 | owner: true, 10 | }, 11 | description: "Pengelolaan dan Pengaturan Plugins Bot dengan Mudah", 12 | async run(m, { text }) { 13 | let src = pg.plugins; 14 | 15 | if (!text) 16 | throw `> *– 乂 Panduan Penggunaan Perintah* 💡\n 17 | > 1. Gunakan *\`--get\`* untuk mengambil plugin\n 18 | > 2. Gunakan *\`--add\`* untuk menambahkan plugin baru\n 19 | > 3. Gunakan *\`--delete\`* untuk menghapus plugin\n\n 20 | > *– 乂 Daftar Plugin yang Tersedia :*\n 21 | ${Object.keys(src) 22 | .map((a, i) => `> *${i + 1}.* ${a.split("/plugins/")[1]}`) 23 | .join("\n")}`; 24 | 25 | if (text.includes("--get")) { 26 | let input = text.replace("--get", "").trim(); 27 | if (!input) 28 | throw `> Mohon pilih plugin dengan menyertakan nomor atau nama plugin.`; 29 | 30 | let list = Object.keys(src).map((a) => a.split("/plugins/")[1]); 31 | let file = isNaN(input) 32 | ? `${pg.directory}/${input}.js` 33 | : `${pg.directory}/${list[parseInt(input) - 1]}`; 34 | 35 | try { 36 | m.reply(fs.readFileSync(file.trim()).toString()); 37 | } catch (e) { 38 | m.reply( 39 | `> *Plugin ${input} tidak ditemukan.* Pastikan plugin yang kamu cari tersedia.`, 40 | ); 41 | } 42 | } else if (text.includes("--add")) { 43 | if (!m.quoted || !m.quoted.body) 44 | throw `> *– 乂 Mohon balas pesan berisi kode plugin yang ingin kamu simpan.*\n 45 | > Harap pastikan bahwa kode plugin yang kamu kirim valid dan lengkap!`; 46 | 47 | let input = text.replace("--add", "").trim(); 48 | if (!input) throw `> Masukkan nama plugin yang ingin kamu tambahkan.`; 49 | 50 | try { 51 | let file = `${pg.directory}/${input}.js`; 52 | fs.writeFileSync(file.trim(), jsBeautify(m.quoted.body)); 53 | m.reply(`> 🎉 *Plugin ${input} berhasil disimpan!*`); 54 | } catch (e) { 55 | m.reply( 56 | `> *Terjadi kesalahan saat menyimpan plugin.* Coba periksa kode plugin atau coba lagi nanti.`, 57 | ); 58 | } 59 | } else if (text.includes("--delete")) { 60 | let input = text.replace("--delete", "").trim(); 61 | if (!input) 62 | throw `> Silakan masukkan nama atau nomor plugin yang ingin kamu hapus.`; 63 | 64 | let list = Object.keys(src).map((a) => a.split("/plugins/")[1]); 65 | let file = isNaN(input) 66 | ? `${pg.directory}/${input}.js` 67 | : `${pg.directory}/${list[parseInt(input) - 1]}`; 68 | 69 | try { 70 | fs.unlinkSync(file.trim()); 71 | m.reply(`> 🗑️ *Plugin ${input} berhasil dihapus dari daftar plugin.*`); 72 | } catch (e) { 73 | m.reply( 74 | `> *Plugin ${input} tidak ditemukan.* Pastikan nama plugin yang kamu masukkan benar.`, 75 | ); 76 | } 77 | } else { 78 | throw `> *– 乂 Panduan Penggunaan Perintah* 💡\n 79 | > 1. Gunakan *\`--get\`* untuk mengambil plugin\n 80 | > 2. Gunakan *\`--add\`* untuk menambahkan plugin baru\n 81 | > 3. Gunakan *\`--delete\`* untuk menghapus plugin\n\n 82 | > *– 乂 Daftar Plugin yang Tersedia :*\n 83 | ${Object.keys(src) 84 | .map((a, i) => `> *${i + 1}.* ${a.split("/plugins/")[1]}`) 85 | .join("\n")}`; 86 | } 87 | }, 88 | }; 89 | -------------------------------------------------------------------------------- /system/plugins/owner/scrape.js: -------------------------------------------------------------------------------- 1 | const fs = require("node:fs"); 2 | const beauty = require("js-beautify"); 3 | 4 | module.exports = { 5 | command: "scrape", 6 | alias: ["skrep", "scraper"], 7 | category: ["owner"], 8 | settings: { 9 | owner: true, 10 | }, 11 | description: "⚙️ *Pengelolaan Scraper Bot* 📈", 12 | async run(m, { sock, Func, text, config }) { 13 | let src = await scraper.list(); 14 | 15 | if (!text) 16 | throw `> *- 乂 Cara Penggunaan Scraper Bot*\n\n> 📝 *\`--get\`* - Untuk mengambil scraper yang ada\n> ➕ *\`--add\`* - Untuk menambahkan scraper baru\n> ❌ *\`--delete\`* - Untuk menghapus scraper yang ada\n\n> *- 乂 Daftar Scrapers yang tersedia :*\n${Object.keys( 17 | src, 18 | ) 19 | .map((a, i) => `> *${i + 1}.* ${a}`) 20 | .join("\n")}`; 21 | 22 | if (text.includes("--get")) { 23 | let input = text.replace("--get", "").trim(); 24 | if (!isNaN(input)) { 25 | let list = Object.keys(src); 26 | try { 27 | let file = scraper.dir + "/" + list[parseInt(input) - 1] + ".js"; 28 | m.reply(fs.readFileSync(file.trim()).toString()); 29 | } catch (e) { 30 | m.reply( 31 | `> ⚠️ *Scrape* ${list[parseInt(input) - 1]} *tidak ditemukan*, pastikan cek kembali list Scrape yang kamu simpan!`, 32 | ); 33 | } 34 | } else { 35 | try { 36 | let file = scraper.dir + "/" + input + ".js"; 37 | m.reply(fs.readFileSync(file.trim()).toString()); 38 | } catch (e) { 39 | m.reply( 40 | `> ⚠️ *Scrape* ${input} *tidak ditemukan*, pastikan cek kembali list Scrape yang kamu simpan!`, 41 | ); 42 | } 43 | } 44 | } else if (m.text.includes("--add")) { 45 | if (!m.quoted) 46 | throw "> 📩 *Balas pesan yang berisi scraper yang ingin disimpan*"; 47 | let input = m.text.replace("--add", "").trim(); 48 | try { 49 | let file = scraper.dir + "/" + input + ".js"; 50 | fs.writeFileSync(file.trim(), await beauty(m.quoted.body)); 51 | m.reply("> ✅ *Berhasil menyimpan scraper:* " + input); 52 | } catch (e) { 53 | m.reply(`> ❌ *Gagal menyimpan scraper*, coba lagi.`); 54 | } 55 | } else if (text.includes("--delete")) { 56 | let input = text.replace("--delete", "").trim(); 57 | if (!isNaN(input)) { 58 | let list = Object.keys(src); 59 | try { 60 | let file = scraper.dir + "/" + list[parseInt(input) - 1] + ".js"; 61 | fs.unlinkSync(file.trim()); 62 | m.reply("> 🗑️ *Scraper berhasil dihapus*."); 63 | } catch (e) { 64 | m.reply( 65 | `> ⚠️ *Scrape* ${list[parseInt(input) - 1]} *tidak ditemukan*, pastikan cek kembali list Scrape yang kamu simpan!`, 66 | ); 67 | } 68 | } else { 69 | try { 70 | let file = scraper.dir + "/" + input + ".js"; 71 | fs.unlinkSync(file.trim()); 72 | m.reply("> 🗑️ *Scraper berhasil dihapus*."); 73 | } catch (e) { 74 | m.reply( 75 | `> ⚠️ *Scrape* ${input} *tidak ditemukan*, pastikan cek kembali list Scrape yang kamu simpan!`, 76 | ); 77 | } 78 | } 79 | } 80 | }, 81 | }; 82 | -------------------------------------------------------------------------------- /system/plugins/owner/self.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "self", 3 | alias: [], 4 | category: ["owner"], 5 | settings: { 6 | owner: true, 7 | }, 8 | description: "🔇 Ubah bot menjadi mode senyap (Self Mode)", 9 | async run(m, { sock, text }) { 10 | if (!text) 11 | return m.reply({ 12 | poll: { 13 | name: `*– 乂 *Cara Penggunaan Fitur Mode Senyap (Self Mode)*\n\n> *\`0\`* - Untuk mematikan fitur self mode (Bot aktif di grup)\n> *\`1\`* - Untuk menghidupkan fitur self mode (Bot hanya aktif di private chat)`, 14 | values: [`${m.prefix}self 0`, `${m.prefix}self 1`], 15 | selectableCount: 1, 16 | }, 17 | }); 18 | 19 | let settings = db.list().settings; 20 | settings.self = parseInt(text) > 0 ? true : false; 21 | 22 | m.reply( 23 | `> ✅ Fitur *Self Mode* berhasil ${text < 1 ? "dimatikan" : "diaktifkan"}. Bot akan ${text < 1 ? "kembali bergabung ke grup" : "hanya dapat digunakan melalui pesan pribadi"}.`, 24 | ); 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /system/plugins/owner/setpp.js: -------------------------------------------------------------------------------- 1 | const Jimp = require("jimp"); 2 | 3 | class Command { 4 | constructor() { 5 | this.command = "setppbot"; 6 | this.alias = ["setpp", "setppbotwa"]; 7 | this.category = ["owner"]; 8 | this.settings = { 9 | owner: true, 10 | }; 11 | this.description = "📸 *Mengubah Foto Profil Bot* 💬"; 12 | this.loading = true; 13 | } 14 | 15 | run = async (m, { sock, Func, Scraper, config, store }) => { 16 | let q = m.quoted ? m.quoted : m; 17 | let mime = (q.msg || q).mimetype || q.mediaType || ""; 18 | 19 | if (/image/g.test(mime) && !/webp/g.test(mime)) { 20 | let media = await q.download(); 21 | let { img } = await pepe(media); 22 | await sock.updateProfilePicture(sock.decodeJid(sock.user.id), img); 23 | m.reply( 24 | "> 🎉 *Berhasil mengubah profile picture bot!* 🎉\n> *Foto profil bot telah diperbarui.*", 25 | ); 26 | } else { 27 | m.reply( 28 | "> ⚠️ *Balas/Kirim gambar yang ingin dijadikan profile picture bot.*\n> Pastikan gambar yang dikirim tidak dalam format webp.", 29 | ); 30 | } 31 | }; 32 | } 33 | module.exports = new Command(); 34 | 35 | async function pepe(media) { 36 | const jimp = await Jimp.read(media), 37 | min = jimp.getWidth(), 38 | max = jimp.getHeight(), 39 | cropped = jimp.crop(0, 0, min, max); 40 | 41 | return { 42 | img: await cropped.scaleToFit(720, 720).getBufferAsync(Jimp.MIME_JPEG), 43 | preview: await cropped.normalize().getBufferAsync(Jimp.MIME_JPEG), 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /system/plugins/owner/upsw.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "upsw"; 4 | this.alias = []; 5 | this.category = ["owner"]; 6 | this.settings = { 7 | owner: true 8 | }; 9 | this.description = "Upload mdia mu ke Status WhatsApp"; 10 | this.loading = true; 11 | } 12 | run = async (m, { 13 | sock, 14 | Func, 15 | Scraper, 16 | config, 17 | store 18 | }) => { 19 | let teks; 20 | if (m.args.length >= 1) { 21 | teks = m.args.slice(0).join(" "); 22 | } else if (m.quoted && m.quoted.body) { 23 | teks = m.quoted.body; 24 | } 25 | 26 | if (m.quoted && m.quoted.type) { 27 | const mtype = m.quoted.type; 28 | let type; 29 | 30 | if (mtype === "audioMessage") { 31 | type = "vn"; 32 | } else if (mtype === "videoMessage") { 33 | type = "vid"; 34 | } else if (mtype === "imageMessage") { 35 | type = "img"; 36 | } else if (mtype === "extendedTextMessage") { 37 | type = "txt"; 38 | } else { 39 | throw "❌ Media type tidak valid!"; 40 | } 41 | 42 | const doc = {}; 43 | 44 | if (type === "vn") { 45 | const link = await m.quoted.download() 46 | doc.mimetype = m.quoted.msg.mimetype; 47 | doc.audio = link 48 | 49 | } else if (type === "vid") { 50 | const link = await m.quoted.download(); 51 | doc.mimetype = m.quoted.msg.mimetype; 52 | doc.caption = teks; 53 | doc.video = link 54 | } else if (type === "img") { 55 | const link = await m.quoted.download(); 56 | doc.mimetype = m.quoted.msg.mimetype; 57 | doc.caption = teks; 58 | doc.image = link 59 | } else if (type === "txt") { 60 | doc.text = teks; 61 | } 62 | if (m.isGroup) return sock.sendStatus(doc, [m.cht]) 63 | await sock.sendMessage("status@broadcast", doc, { 64 | backgroundColor: getRandomHexColor(), 65 | font: Math.floor(Math.random() * 9), 66 | statusJidList: Object.keys(store.contacts), 67 | }) 68 | .then((res) => { 69 | m.reply(`Sukses upload ${type}`); 70 | }) 71 | .catch(() => { 72 | m.reply(`Gagal upload ${type}`); 73 | }); 74 | } else { 75 | throw "❌ Tidak ada media yang diberikan!"; 76 | } 77 | }; 78 | } 79 | 80 | module.exports = new Command(); -------------------------------------------------------------------------------- /system/plugins/ping.js: -------------------------------------------------------------------------------- 1 | const os = require("node:os"); 2 | const fs = require("node:fs"); 3 | 4 | module.exports = { 5 | command: "ping", 6 | alias: ["ping", "p"], 7 | category: ["main"], 8 | description: "Periksa Status bot", 9 | loading: true, 10 | async run(m, { sock, config, Func }) { 11 | let start = performance.now(), 12 | node = process.memoryUsage(), 13 | info = await fetch("https://ipwho.is").then((a) => a.json()), 14 | cap = ` 15 | ╭──[ *Informasi Bot* ] 16 | ᎒⊸ 🖥️ *Berjalan Di* : ${process.env.username === "root" ? "VPS" : process.env.username === "container" ? "HOSTING ( PANEL )" : process.env.username} 17 | ᎒⊸ ⏱️ *Uptime* : ${Func.toDate(process.uptime() * 1000)} 18 | ᎒⊸ 🏠 *Direktori Rumah* : ${os.homedir} 19 | ᎒⊸ 📂 *Direktori Tmp* : ${os.tmpdir()} *( ${fs.readdirSync(process.cwd() + os.tmpdir).length} Berkas )* 20 | ᎒⊸ 🖥️ *Hostname* : ${os.hostname()} 21 | ᎒⊸ ⚙️ *Versi Node* : ${process.version} 22 | ᎒⊸ 🌍 *Cwd* : ${process.cwd()} 23 | 24 | ╭──[ *Informasi Provider* ] 25 | ᎒⊸ 🌐 *ISP* : ${info.connection.isp} 26 | ᎒⊸ 🏢 *Organisasi* : ${info.connection.org} 27 | ᎒⊸ 🌎 *Negara* : ${info.country} 28 | ᎒⊸ 🏙️ *Kota* : ${info.city} 29 | ᎒⊸ 🚩 *Bendera* : ${info.flag.emoji} 30 | ᎒⊸ ⏰ *Zona Waktu* : ${info.timezone.id} 31 | ╰────────────• 32 | 33 | ╭──[ *Informasi Server Asal* ] 34 | ᎒⊸ 🚀 *Kecepatan* : ${(performance.now() - start).toFixed(3)} ms 35 | ᎒⊸ ⏳ *Uptime* : ${Func.toDate(os.uptime() * 1000)} 36 | ᎒⊸ 🧠 *Total Memori* : ${Func.formatSize(os.totalmem() - os.freemem())} / ${Func.formatSize(os.totalmem())} 37 | ᎒⊸ 🖥️ *CPU* : ${os.cpus()[0].model} ( ${os.cpus().length} CORE ) 38 | ᎒⊸ 📦 *Rilis* : ${os.release()} 39 | ᎒⊸ 🖧 *Tipe* : ${os.type()} 40 | ╰────────────• 41 | 42 | ╭──[ *Penggunaan Memori Nodejs* ] 43 | ${Object.entries(node) 44 | .map(([a, b]) => `᎒⊸ 💾 *${a.capitalize()}* : ${Func.formatSize(b)}`) 45 | .join("\n")} 46 | ╰────────────•`; 47 | 48 | m.reply(cap); 49 | }, 50 | }; 51 | -------------------------------------------------------------------------------- /system/plugins/rpg/bank.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "bank", 3 | alias: ["wallet", "atm", "banking"], 4 | category: ["rpg"], 5 | settings: {}, 6 | loading: true, 7 | 8 | async run(m, { text, sock }) { 9 | let user = db.list().user[m.sender]; 10 | if (!user.bank) user.bank = 0; 11 | 12 | const formatMoney = (amount) => amount.toLocaleString("id-ID"); 13 | 14 | if (!text) { 15 | return m.reply(`╭═══❯ 🏦 ᴠ-ʙᴀɴᴋ ❮═══╗ 16 | │ 17 | │ 👤 ᴀᴄᴄᴏᴜɴᴛ ɪɴꜰᴏ 18 | │ ──────────────── 19 | │ 📝 ɴᴀᴍᴇ: ${user.name} 20 | │ 📊 ʟᴇᴠᴇʟ: ${user.level} 21 | │ 🎫 ʟɪᴍɪᴛ: ${user.limit} 22 | │ 23 | │ 💰 ʙᴀʟᴀɴᴄᴇ ɪɴꜰᴏ 24 | │ ──────────────── 25 | │ 💳 ʙᴀɴᴋ: ʀᴘ ${formatMoney(user.bank)} 26 | │ 💵 ᴄᴀꜱʜ: ʀᴘ ${formatMoney(user.rpg.money)} 27 | │ 28 | │ 📋 ᴄᴏᴍᴍᴀɴᴅꜱ 29 | │ ──────────────── 30 | │ 💸 ${m.prefix}bank deposit 31 | │ 💰 ${m.prefix}bank pull 32 | │ 33 | ╰═══════════════════╯`); 34 | } 35 | 36 | const [command, amountText] = text.split(" "); 37 | const amount = parseInt(amountText); 38 | 39 | if (!amount) return m.reply(`❌ ᴍᴀꜱᴜᴋᴋᴀɴ ɴᴏᴍɪɴᴀʟ`); 40 | if (isNaN(amount)) return m.reply(`❌ ɴᴏᴍɪɴᴀʟ ʜᴀʀᴜꜱ ʙᴇʀᴜᴘᴀ ᴀɴɢᴋᴀ`); 41 | if (amount < 1000) return m.reply(`❌ ᴍɪɴɪᴍᴀʟ ᴛʀᴀɴꜱᴀᴋꜱɪ ʀᴘ 1,000`); 42 | 43 | switch (command.toLowerCase()) { 44 | case "deposit": { 45 | if (user.rpg.money < amount) 46 | return m.reply(`╭═══❯ ❌ ꜰᴀɪʟᴇᴅ ❮═══╗ 47 | │ 48 | │ 💵 ᴜᴀɴɢ ᴛᴜɴᴀɪ ᴛɪᴅᴀᴋ ᴄᴜᴋᴜᴘ 49 | │ 💳 ᴀɴᴅᴀ ʙᴜᴛᴜʜ: ʀᴘ ${formatMoney(amount)} 50 | │ 💰 ᴅᴏᴍᴘᴇᴛ ᴀɴᴅᴀ: ʀᴘ ${formatMoney(user.rpg.money)} 51 | │ 52 | ╰═══════════════════╯`); 53 | 54 | await m.reply(`💳 ᴍᴇᴍᴘʀᴏꜱᴇꜱ ᴅᴇᴘᴏꜱɪᴛ...`); 55 | await new Promise((resolve) => setTimeout(resolve, 1500)); 56 | 57 | user.rpg.money -= amount; 58 | user.bank += amount; 59 | 60 | return m.reply(`╭═══❯ 🏦 ᴅᴇᴘᴏꜱɪᴛ ❮═══╗ 61 | │ 62 | │ ✅ ᴅᴇᴘᴏꜱɪᴛ ʙᴇʀʜᴀꜱɪʟ! 63 | │ 💸 ᴊᴜᴍʟᴀʜ: ʀᴘ ${formatMoney(amount)} 64 | │ 65 | │ 📊 ꜱᴀʟᴅᴏ ᴛᴇʀʙᴀʀᴜ 66 | │ ──────────────── 67 | │ 💳 ʙᴀɴᴋ: ʀᴘ ${formatMoney(user.bank)} 68 | │ 💵 ᴄᴀꜱʜ: ʀᴘ ${formatMoney(user.rpg.money)} 69 | │ 70 | ╰═══════════════════╯`); 71 | } 72 | 73 | case "pull": { 74 | if (user.bank < amount) 75 | return m.reply(`╭═══❯ ❌ ꜰᴀɪʟᴇᴅ ❮═══╗ 76 | │ 77 | │ 💳 ꜱᴀʟᴅᴏ ᴛɪᴅᴀᴋ ᴄᴜᴋᴜᴘ 78 | │ 💰 ᴀɴᴅᴀ ʙᴜᴛᴜʜ: ʀᴘ ${formatMoney(amount)} 79 | │ 💵 ꜱᴀʟᴅᴏ ᴀɴᴀ: ʀᴘ ${formatMoney(user.bank)} 80 | │ 81 | ╰═══════════════════╯`); 82 | 83 | await m.reply(`💳 ᴍᴇᴍᴘʀᴏꜱᴇꜱ ᴘᴇɴᴀʀɪᴋᴀɴ...`); 84 | await new Promise((resolve) => setTimeout(resolve, 1500)); 85 | 86 | user.bank -= amount; 87 | user.rpg.money += amount; 88 | 89 | return m.reply(`╭═══❯ 🏦 ᴘᴇɴᴀʀɪᴋᴀɴ ❮═══╗ 90 | │ 91 | │ ✅ ᴘᴇɴᴀʀɪᴋᴀɴ ʙᴇʀʜᴀꜱɪʟ! 92 | │ 💸 ᴊᴜᴍʟᴀʜ: ʀᴘ ${formatMoney(amount)} 93 | │ 94 | │ 📊 ꜱᴀʟᴅᴏ ᴛᴇʀʙᴀʀᴜ 95 | │ ──────────────── 96 | │ 💳 ʙᴀɴᴋ: ʀᴘ ${formatMoney(user.bank)} 97 | │ 💵 ᴄᴀꜱʜ: ʀᴘ ${formatMoney(user.rpg.money)} 98 | │ 99 | ╰═══════════════════╯`); 100 | } 101 | 102 | default: 103 | return m.reply(`❌ ᴄᴏᴍᴍᴀɴᴅ ᴛɪᴅᴀᴋ ᴠᴀʟɪᴅ!`); 104 | } 105 | }, 106 | }; 107 | -------------------------------------------------------------------------------- /system/plugins/rpg/bansos.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "bansos", 3 | alias: ["bantuan", "assistance"], 4 | category: ["rpg"], 5 | settings: { 6 | owner: false, 7 | }, 8 | async run(m, { sock, Func }) { 9 | const user = db.list().user[m.sender]; 10 | 11 | if (!user) return m.reply("❌ User tidak terdaftar dalam database"); 12 | 13 | let time = new Date().getTime(); 14 | let cooldown = 86400000; // 24 jam 15 | let lastBansos = user.lastbansos || 0; 16 | 17 | if (time - lastBansos < cooldown) { 18 | let remaining = cooldown - (time - lastBansos); 19 | let hours = Math.floor(remaining / 3600000); 20 | let minutes = Math.floor((remaining % 3600000) / 60000); 21 | 22 | return m.reply( 23 | ` 24 | ╔══════════════════════ 25 | ║ 🕐 *COOLDOWN BANSOS* 26 | ╠══════════════════════ 27 | ║ ⏰ Tunggu *${hours} jam ${minutes} menit* 28 | ║ 📝 Sebelum mengambil bansos lagi 29 | ╚══════════════════════`.trim(), 30 | ); 31 | } 32 | const isPremium = user.premium.status || false; 33 | const chance = Math.random() * 100; 34 | 35 | const successChance = isPremium ? 75 : 25; 36 | 37 | if (chance > successChance) { 38 | let gagalText = ` 39 | ╔═══════════════════════ 40 | ║ 📢 *BANSOS GAGAL* 41 | ╠═══════════════════════ 42 | ║ 😔 Anda gagal mendapatkan bansos 43 | ║ ${isPremium ? "👑 Coba lagi besok!" : "⭐ Tingkatkan ke Premium\n║ untuk peluang lebih besar!"} 44 | ╚═══════════════════════`; 45 | return m.reply({ 46 | image: { 47 | url: "https://telegra.ph/file/afcf9a7f4e713591080b5.jpg", 48 | }, 49 | caption: gagalText, 50 | footer: "Yahaha Kalah😂", 51 | buttons: [ 52 | { 53 | buttonId: ".owner", 54 | buttonText: { 55 | displayText: "GANTENG", 56 | }, 57 | }, 58 | ], 59 | viewOnce: true, 60 | headerType: 6, 61 | }); 62 | let moneyReward, coinReward; 63 | 64 | if (isPremium) { 65 | moneyReward = 66 | Math.floor(Math.random() * (5000000 - 3000000 + 1)) + 3000000; 67 | coinReward = Math.floor(Math.random() * (100 - 50 + 1)) + 50; 68 | } else { 69 | moneyReward = 70 | Math.floor(Math.random() * (2000000 - 1000000 + 1)) + 1000000; 71 | coinReward = Math.floor(Math.random() * (50 - 30 + 1)) + 30; 72 | } 73 | 74 | user.money = (user.money || 0) + moneyReward; 75 | user.coin = (user.coin || 0) + coinReward; 76 | user.lastbansos = time; 77 | 78 | const rewardText = ` 79 | ╔════════════════════════ 80 | ║ 🎊 *BANSOS BERHASIL* 🎊 81 | ╠════════════════════════ 82 | ║ 👤 *Status:* ${isPremium ? "👑 Premium" : "⭐ Regular"} 83 | ║ 84 | ║ 💰 *Reward Money:* 85 | ║ └─ Rp ${Func.h2k(moneyReward)} 86 | ║ 87 | ║ 🪙 *Reward Coin:* 88 | ║ └─ ${Func.h2k(coinReward)} coins 89 | ║ 90 | ║ 📊 *Total Sekarang:* 91 | ║ ├─ 💵 Rp ${Func.h2k(user.money)} 92 | ║ └─ 🪙 ${Func.h2k(user.coin)} coins 93 | ║ 94 | ║ ${isPremium ? "👑 Bonus Premium!" : "⭐ Upgrade ke Premium\n║ untuk reward lebih besar!"} 95 | ╠════════════════════════ 96 | ║ ⏰ Kembali lagi dalam 24 jam! 97 | ╚════════════════════════`.trim(); 98 | 99 | return m.reply({ 100 | image: { 101 | url: "https://telegra.ph/file/d31fcc46b09ce7bf236a7.jpg", 102 | }, 103 | caption: rewardText, 104 | footer: "Horee Menang 🎉", 105 | buttons: [ 106 | { 107 | buttonId: ".owner", 108 | buttonText: { 109 | displayText: "GANTENG", 110 | }, 111 | }, 112 | ], 113 | viewOnce: true, 114 | headerType: 6, 115 | }); 116 | } 117 | }, 118 | }; 119 | -------------------------------------------------------------------------------- /system/plugins/rpg/gajian.js: -------------------------------------------------------------------------------- 1 | let money = 50000; 2 | let exp = 5000; 3 | let cooldown = 7 * 60 * 60 * 1000; 4 | 5 | module.exports = { 6 | command: "gajian", 7 | alias: ["gaji"], 8 | category: ["rpg"], 9 | settings: {}, 10 | async run(m, { sock }) { 11 | let user = db.list().user[m.sender]; 12 | let now = Date.now(); 13 | 14 | if (user.rpg.lastGajian && now - user.rpg.lastGajian < cooldown) { 15 | let remaining = cooldown - (now - user.rpg.lastGajian); 16 | let hours = Math.floor(remaining / (60 * 60 * 1000)); 17 | let minutes = Math.floor((remaining % (60 * 60 * 1000)) / (60 * 1000)); 18 | let timeLeft = `${hours} jam ${minutes} menit`; 19 | 20 | return m.reply( 21 | `Sabar njir, gaji lu masih pending!\nTunggu ${timeLeft} lagi.`, 22 | ); 23 | } 24 | 25 | user.rpg.money += money; 26 | user.rpg.exp += exp; 27 | user.rpg.lastGajian = now; 28 | 29 | let nextClaim = new Date(now + cooldown).toLocaleTimeString("id-ID", { 30 | hour: "2-digit", 31 | minute: "2-digit", 32 | }); 33 | let cap = `Nih Gaji Lu Njir, Minta Mulu\n> 💵 + 50000 Money\n> 🎁 + 5000 Exp\n\nLu bisa gajian lagi jam: ${nextClaim}`; 34 | 35 | m.reply({ 36 | text: cap, 37 | footer: "Back To Menu", 38 | buttons: [ 39 | { 40 | buttonId: ".menu", 41 | buttonText: { 42 | displayText: "Menu", 43 | }, 44 | }, 45 | ], 46 | viewOnce: true, 47 | headerType: 6, 48 | }); 49 | }, 50 | }; 51 | -------------------------------------------------------------------------------- /system/plugins/rpg/levelup.js: -------------------------------------------------------------------------------- 1 | let path = require("path"); 2 | let dataPath = path.join(process.cwd(), "lib", "leveling.js"); 3 | let levelling = require(dataPath); 4 | 5 | module.exports = { 6 | command: "levelup", 7 | alias: ["uplevel"], 8 | category: ["rpg"], 9 | settings: {}, 10 | loading: true, 11 | async run(m, { sock }) { 12 | let user = db.list().user[m.sender].rpg; 13 | let userr = db.list().user[m.sender]; 14 | if (!levelling.canLevelUp(userr.level, user.exp, global.multiplier)) { 15 | let { min, xp, max } = levelling.xpRange(userr.level, global.multiplier); 16 | throw ` 17 | Level *${userr.level} (${user.exp - min}/${xp})* 18 | Kurang *${max - user.exp}* lagi! 19 | `.trim(); 20 | } 21 | let before = userr.level * 1; 22 | while (levelling.canLevelUp(userr.level, user.exp, global.multiplier)) 23 | userr.level++; 24 | if (before !== userr.level) { 25 | m.reply( 26 | ` 27 | Selamat, anda telah naik level! 28 | *${before}* -> *${userr.level}* 29 | `.trim(), 30 | ); 31 | } 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /system/plugins/rpg/mulung.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "mulung", 3 | alias: ["mungut"], 4 | category: ["rpg"], 5 | settings: {}, 6 | async run(m, { sock }) { 7 | let user = db.list().user[m.sender].rpg; 8 | let cool = 4 * 60 * 60 * 1000; 9 | if (user.lastMulung && Date.now() - user.lastMulung < cool) { 10 | let remaining = cool - (Date.now() - user.lastMulung); 11 | let minutes = Math.floor(remaining / (60 * 1000)); 12 | let seconds = Math.floor((remaining % (60 * 1000)) / 1000); 13 | return m.reply( 14 | `⏳ Mohon tunggu *${minutes} menit ${seconds} detik* sebelum mulung kembali!`, 15 | ); 16 | } 17 | let items = { 18 | kaleng: ["🥫", Math.floor(Math.random() * 450) + 50], 19 | kardus: ["📦", Math.floor(Math.random() * 450) + 50], 20 | plastik: ["💳", Math.floor(Math.random() * 450) + 50], 21 | botol: ["🍾", Math.floor(Math.random() * 450) + 50], 22 | sampah: ["🗑️", Math.floor(Math.random() * 450) + 50], 23 | kayu: ["🪵", Math.floor(Math.random() * 450) + 50], 24 | iron: ["⛓️", Math.floor(Math.random() * 450) + 50], 25 | gelas: ["🥤", Math.floor(Math.random() * 450) + 50], 26 | }; 27 | let resultText = `*🔍 Hasil Mulung:*\n`; 28 | for (let [item, [emote, amount]] of Object.entries(items)) { 29 | user[item] = (user[item] || 0) + amount; 30 | resultText += `${emote} ${item}: +${amount}\n`; 31 | } 32 | user.lastMulung = Date.now(); 33 | return m.reply(` 34 | ${resultText} 35 | 36 | > *Tunggu 4 Jam Untuk Memulung Lagi* 37 | `); 38 | }, 39 | }; 40 | -------------------------------------------------------------------------------- /system/plugins/rpg/profile.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "profile", 3 | alias: ["me"], 4 | category: ["rpg"], 5 | settings: {}, 6 | async run(m, { sock }) { 7 | let usr = db.list().user[m.sender]; 8 | let rpg = usr.rpg; 9 | 10 | const formatNumber = (num) => 11 | num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); 12 | 13 | const getTimeLeft = (expired) => { 14 | const now = Date.now(); 15 | const timeLeft = expired - now; 16 | if (timeLeft <= 0) return "Expired"; 17 | const days = Math.floor(timeLeft / (1000 * 60 * 60 * 24)); 18 | const hours = Math.floor( 19 | (timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60), 20 | ); 21 | return `${days}d ${hours}h`; 22 | }; 23 | 24 | let profile = `╭━━━「 *PROFILE* 」━━━⊷\n`; 25 | profile += `┃ ⬡ *Name:* ${usr.name}\n`; 26 | profile += `┃ ⬡ *Level:* ${usr.level} ✨\n`; 27 | profile += `┃ ⬡ *Status:* ${usr.premium.status ? "Premium 👑" : "Free User 👤"}\n`; 28 | profile += `┃ ⬡ *Banned:* ${usr.banned.status ? "Yes ⛔" : "No ✅"}\n`; 29 | profile += `┃ ⬡ *Limit:* ${formatNumber(usr.limit)} 🎯\n`; 30 | profile += `┃ ⬡ *Registered:* ${usr.register ? "Yes ✅" : "No ❌"}\n`; 31 | profile += `╰━━━━━━━━━━━━━━━⊷\n\n`; 32 | 33 | profile += `╭━━━「 *BALANCE* 」━━━⊷\n`; 34 | profile += `┃ ⬡ *Money:* $${formatNumber(rpg.money)} 💵\n`; 35 | profile += `┃ ⬡ *Bank:* $${formatNumber(usr.bank)} 🏦\n`; 36 | profile += `┃ ⬡ *Coin:* ${formatNumber(usr.coin)} 🪙\n`; 37 | profile += `┃ ⬡ *XP:* ${formatNumber(rpg.exp)} ✨\n`; 38 | profile += `╰━━━━━━━━━━━━━━━⊷\n\n`; 39 | 40 | profile += `╭━━━「 *INVENTORY* 」━━━⊷\n`; 41 | profile += `┃ ⬡ *Sampah:* ${formatNumber(rpg.sampah)} 🗑️\n`; 42 | profile += `┃ ⬡ *Botol:* ${formatNumber(rpg.botol)} 🧊\n`; 43 | profile += `┃ ⬡ *Kardus:* ${formatNumber(rpg.kardus)} 📦\n`; 44 | profile += `┃ ⬡ *Iron:* ${formatNumber(rpg.iron)} ⚔️\n`; 45 | profile += `┃ ⬡ *Kayu:* ${formatNumber(rpg.kayu)} 🪵\n`; 46 | profile += `┃ ⬡ *Kaleng:* ${formatNumber(rpg.kaleng)} 🥫\n`; 47 | profile += `┃ ⬡ *Gelas:* ${formatNumber(rpg.gelas)} 🥛\n`; 48 | profile += `┃ ⬡ *Plastik:* ${formatNumber(rpg.plastik)} ♻️\n`; 49 | profile += `╰━━━━━━━━━━━━━━━⊷\n\n`; 50 | 51 | const now = Date.now(); 52 | const gajianCD = rpg.lastGajian + 3600 * 1000 - now; 53 | const mulungCD = rpg.lastMulung + 3600 * 1000 - now; 54 | const taxyCD = rpg.lastTaxy + 3600 * 1000 - now; 55 | 56 | profile += `╭━━━「 *COOLDOWNS* 」━━━⊷\n`; 57 | profile += `┃ ⬡ *Gajian:* ${gajianCD > 0 ? Math.floor(gajianCD / 1000) + "s" : "Ready!"} ⏰\n`; 58 | profile += `┃ ⬡ *Mulung:* ${mulungCD > 0 ? Math.floor(mulungCD / 1000) + "s" : "Ready!"} ⏰\n`; 59 | profile += `┃ ⬡ *Taxy:* ${taxyCD > 0 ? Math.floor(taxyCD / 1000) + "s" : "Ready!"} ⏰\n`; 60 | profile += `╰━━━━━━━━━━━━━━━⊷\n\n`; 61 | 62 | if (usr.premium.status) { 63 | profile += `╭━━━「 *PREMIUM* 」━━━⊷\n`; 64 | profile += `┃ ⬡ *Expired:* ${getTimeLeft(usr.premium.expired)} ⌛\n`; 65 | profile += `╰━━━━━━━━━━━━━━━⊷`; 66 | } 67 | let urlPic = await sock.profilePictureUrl(m.sender, "image"); 68 | 69 | await m.reply({ 70 | image: { 71 | url: urlPic, 72 | }, 73 | caption: profile, 74 | footer: "ᴛʜᴀɴᴋs ғᴏʀ ᴜsɪɴɢ ɴᴇᴋᴏʙᴏᴛ", 75 | buttons: [ 76 | { 77 | buttonId: ".menu", 78 | buttonText: { 79 | displayText: "Back To Menu", 80 | }, 81 | }, 82 | ], 83 | viewOnce: true, 84 | headerType: 6, 85 | }); 86 | }, 87 | }; 88 | -------------------------------------------------------------------------------- /system/plugins/rpg/taxy.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "taxy", 3 | alias: ["taksi"], 4 | category: ["rpg"], 5 | settings: {}, 6 | async run(m, { sock }) { 7 | let usr = db.list().user[m.sender]; 8 | if (!usr || !usr.rpg) { 9 | return m.reply( 10 | "Data RPG tidak ditemukan. Silakan mulai permainan terlebih dahulu.", 11 | ); 12 | } 13 | 14 | let rpg = usr.rpg; 15 | 16 | let lastTaxy = rpg.lastTaxy || 0; 17 | let now = Date.now(); 18 | let cooldown = 14400000; 19 | 20 | if (now - lastTaxy < cooldown) { 21 | let timeLeft = Math.ceil((cooldown - (now - lastTaxy)) / 1000); 22 | return m.reply( 23 | `Tunggu ${timeLeft} detik sebelum kamu dapat menggunakan taksi lagi.`, 24 | ); 25 | } 26 | 27 | let prosesTaksi = [ 28 | "🚗 Sedang Mencari Penumpang", 29 | "🚗 Menemukan Penumpang 👨", 30 | "🚗 Berangkat Ke Tujuan", 31 | "👨 Menerima Gaji Dari Penumpang 💸", 32 | ]; 33 | for (let txt of prosesTaksi) { 34 | await m.reply(txt); 35 | await sleep(7000); 36 | } 37 | 38 | let random = Math.floor(Math.random() * (500000 - 100000 + 1)) + 100000; 39 | let randomExp = Math.floor(Math.random() * 50000) + 1; 40 | let dapatMoney = random; 41 | let dapatExp = randomExp; 42 | rpg.money += dapatMoney; 43 | rpg.exp += dapatExp; 44 | 45 | let hasilNyaTxt = ` 46 | 💼 *Perjalanan Selesai!* 47 | ━━━━━━━━━━━━━━━━━ 48 | 💵 *Gaji Diterima:* +${dapatMoney.toLocaleString()} uang 49 | 🎯 *Pengalaman:* +${dapatExp.toLocaleString()} exp 50 | ━━━━━━━━━━━━━━━━━ 51 | 🚀 Teruslah bekerja keras dan kumpulkan lebih banyak gaji! 52 | `.trim(); 53 | 54 | rpg.lastTaxy = now; 55 | 56 | return m.reply({ 57 | image: { 58 | url: "https://files.catbox.moe/rz9br7.jpg", 59 | }, 60 | caption: hasilNyaTxt, 61 | footer: "ᴛʜᴀɴᴋs ғᴏʀ ᴜsɪɴɢ ɴᴇᴋᴏʙᴏᴛ", 62 | buttons: [ 63 | { 64 | buttonId: ".menu", 65 | buttonText: { 66 | displayText: "Back To Menu", 67 | }, 68 | }, 69 | ], 70 | viewOnce: true, 71 | headerType: 4, 72 | }); 73 | }, 74 | }; 75 | 76 | function sleep(ms) { 77 | return new Promise((resolve) => { 78 | setTimeout(resolve, ms); 79 | }); 80 | } 81 | -------------------------------------------------------------------------------- /system/plugins/say.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "say", 3 | alias: ["say"], 4 | category: ["tools"], 5 | description: "Tools Kirim text", 6 | loading: true, 7 | async run(m, { sock }) { 8 | if (!m.text) return m.reply("Masukan Text nya"); 9 | m.reply(m.text); 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /system/plugins/tools/enc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "enc", 3 | alias: ["encrip"], 4 | category: ["owner"], 5 | settings: { 6 | limit: true, 7 | }, 8 | description: "🔒 Enkripsi pesan yang dibalas untuk meningkatkan keamanan", 9 | async run(m, { sock }) { 10 | if (!m.quoted) throw "> ❌ Balas pesan yang ingin dienkripsi"; 11 | let encryptedMessage = encrypt(m.quoted.body); 12 | m.reply( 13 | `> 🔐 Pesan berhasil dienkripsi: \n\n\`\`\`${encryptedMessage}\`\`\``, 14 | ); 15 | }, 16 | }; 17 | 18 | let data = require("javascript-obfuscator"); 19 | 20 | function encrypt(message) { 21 | let result = data.obfuscate(message, { 22 | compact: true, 23 | controlFlowFlattening: true, 24 | controlFlowFlatteningThreshold: 1, 25 | numbersToExpressions: true, 26 | simplify: true, 27 | stringArrayShuffle: true, 28 | splitStrings: true, 29 | stringArrayThreshold: 1, 30 | }); 31 | return result.getObfuscatedCode(); 32 | } 33 | -------------------------------------------------------------------------------- /system/plugins/tools/forward.js: -------------------------------------------------------------------------------- 1 | const path = require("node:path"); 2 | const serialize = require(path.resolve("./lib/serialize.js")); 3 | 4 | module.exports = { 5 | command: "quoted", 6 | alias: ["q"], 7 | category: ["tools"], 8 | settings: { 9 | limit: true, 10 | }, 11 | description: "🔁 Meneruskan pesan yang dibalas oleh pengguna", 12 | async run(m, { sock, store }) { 13 | if (!m.quoted) throw "> ❌ Balas pesan yang ingin diteruskan"; 14 | 15 | let loadMsg = await store.loadMessage(m.cht, m.quoted.id); 16 | if (!loadMsg?.message) throw "> ❌ Tidak ada pesan yang diteruskan"; 17 | 18 | let data = await serialize(loadMsg, sock, store); 19 | if (!data?.quoted) throw "> ❌ Tidak ada pesan yang diteruskan"; 20 | 21 | sock.copyNForward(m.sender, data.quoted, true); 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /system/plugins/tools/get.js: -------------------------------------------------------------------------------- 1 | const undici = require("undici"); 2 | const { html } = require("js-beautify"); 3 | const { extension } = require("mime-types"); 4 | 5 | module.exports = { 6 | command: "get", 7 | alias: ["fetch"], 8 | category: ["tools"], 9 | description: "🔍 Mendapatkan data dari URL yang diberikan", 10 | loading: true, 11 | async run(m, { sock, Func, text, config }) { 12 | if (!text) 13 | throw "> ❌ Masukan atau reply URL yang ingin kamu ambil datanya"; 14 | 15 | const urls = isUrl(text); 16 | if (!urls) 17 | throw "> ❌ Format URL tidak valid, pastikan URL yang dimasukkan benar"; 18 | 19 | for (const url of urls) { 20 | try { 21 | const response = await undici.fetch(url); 22 | if (!response.ok) { 23 | throw new Error(`HTTP error! status: ${response.status}`); 24 | } 25 | 26 | const mime = response.headers.get("content-type").split(";")[0]; 27 | const cap = `*– 乂 Fetch - Url*\n> *- Request :* ${url}`; 28 | let body; 29 | 30 | if (/\html/gi.test(mime)) { 31 | body = await response.text(); 32 | await sock.sendMessage( 33 | m.cht, 34 | { 35 | document: Buffer.from(html(body)), 36 | caption: cap, 37 | fileName: "result.html", 38 | mimetype: mime, 39 | }, 40 | { quoted: m }, 41 | ); 42 | } else if (/\json/gi.test(mime)) { 43 | body = await response.json(); 44 | m.reply(JSON.stringify(body, null, 2)); 45 | } else if (/image/gi.test(mime)) { 46 | body = await response.arrayBuffer(); 47 | sock.sendFile( 48 | m.cht, 49 | Buffer.from(body), 50 | `result.${extension(mime)}`, 51 | cap, 52 | m, 53 | ); 54 | } else if (/video/gi.test(mime)) { 55 | body = await response.arrayBuffer(); 56 | sock.sendFile( 57 | m.cht, 58 | Buffer.from(body), 59 | `result.${extension(mime)}`, 60 | cap, 61 | m, 62 | ); 63 | } else if (/audio/gi.test(mime)) { 64 | body = await response.arrayBuffer(); 65 | sock.sendFile( 66 | m.cht, 67 | Buffer.from(body), 68 | `result.${extension(mime)}`, 69 | cap, 70 | m, 71 | { mimetype: mime }, 72 | ); 73 | } else { 74 | body = await response.text(); 75 | m.reply(Func.jsonFormat(body)); 76 | } 77 | } catch (error) { 78 | console.error("Error fetching URL:", error); 79 | m.reply(`> ❌ Terjadi kesalahan saat mengambil URL: ${error.message}`); 80 | } 81 | } 82 | }, 83 | }; 84 | 85 | function isUrl(string) { 86 | let urlRegex = 87 | /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/g; 88 | let result = string.match(urlRegex); 89 | return result; 90 | } 91 | -------------------------------------------------------------------------------- /system/plugins/tools/hikagen.js: -------------------------------------------------------------------------------- 1 | const { writeExif } = require(process.cwd() + "/lib/sticker.js"); 2 | 3 | module.exports = { 4 | command: "furbrat", 5 | alias: ["hikagen"], 6 | category: ["tools"], 7 | settings: { 8 | limit: true, 9 | }, 10 | description: "🐾 Membuat Brat versi furry :v", 11 | loading: true, 12 | async run(m, { sock, text, Func, config }) { 13 | if (!text) 14 | throw "> ❌ *Masukan teks yang ingin kamu ubah menjadi furry brat!*"; 15 | 16 | let random = Math.floor(Math.random() * 7); 17 | let API = `https://fastrestapis.fasturl.link/tool/furbrat?text=${text}&style=${random}&mode=center`; 18 | 19 | try { 20 | let buffer = await Func.fetchBuffer(API); 21 | let sticker = await writeExif( 22 | { 23 | mimetype: "image", 24 | data: buffer, 25 | }, 26 | { 27 | packName: config.sticker.packname, 28 | packPublish: config.sticker.author, 29 | }, 30 | ); 31 | 32 | m.reply({ 33 | sticker, 34 | }); 35 | m.reply("> ✅ *Brat versi furry berhasil dibuat!*"); 36 | } catch (error) { 37 | console.error("Error fetching furry brat:", error); 38 | m.reply("> ❌ *Terjadi kesalahan saat membuat furry brat, coba lagi.*"); 39 | } 40 | }, 41 | }; 42 | -------------------------------------------------------------------------------- /system/plugins/tools/kalender.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "kalender"; 4 | this.alias = ["calendar", "libur"]; 5 | this.category = ["tools"]; 6 | this.settings = { 7 | limit: true, 8 | }; 9 | this.description = "Cek Hari libur tahun ini"; 10 | this.loading = true; 11 | } 12 | 13 | run = async (m, { sock, Func, Scraper, config, store }) => { 14 | let array = [ 15 | "January", 16 | "February", 17 | "March", 18 | "April", 19 | "May", 20 | "June", 21 | "July", 22 | "August", 23 | "September", 24 | "October", 25 | "November", 26 | "December", 27 | ]; 28 | let now = new Date(); 29 | let day = now.getDate(); 30 | let month = array[now.getMonth()]; 31 | let year = now.getFullYear(); 32 | 33 | let data = await Scraper.libur(year); 34 | let image = `https://s.wincalendar.net/img/en/calendar/${day}-${month}-${year}.png`; 35 | 36 | let cap = `*– 乂 Hari Libur Tahun ${year}* 📅\n`; 37 | if (data && data.length > 0) { 38 | cap += data 39 | .map((a, i) => 40 | Object.entries(a) 41 | .map(([a, b]) => `> *- ${a.capitalize()} :* ${b}`) 42 | .join("\n"), 43 | ) 44 | .join("\n\n"); 45 | } else { 46 | cap += "> ❌ *Tidak ada data libur yang ditemukan.*"; 47 | } 48 | 49 | m.reply({ 50 | image: { url: image }, 51 | caption: cap, 52 | }); 53 | }; 54 | } 55 | 56 | module.exports = new Command(); 57 | -------------------------------------------------------------------------------- /system/plugins/tools/npm.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "npm"; 4 | this.alias = ["npmjs", "package"]; 5 | this.category = ["tools"]; 6 | this.settings = { 7 | limit: true, 8 | }; 9 | this.description = "🔍 Mencari Package dari NPM"; 10 | this.loading = true; 11 | } 12 | 13 | run = async (m, { sock, Func, text, config }) => { 14 | if (!text) throw "> ❌ *Masukkan Nama Package yang ingin dicari*"; 15 | 16 | try { 17 | let data = await Func.fetchJson( 18 | `https://registry.npmjs.com/-/v1/search?text=${encodeURIComponent(text)}`, 19 | ); 20 | 21 | if (!data.objects || data.objects.length === 0) { 22 | return m.reply( 23 | "> ❌ *Package tidak ditemukan. Coba kata kunci lain atau periksa kembali nama package-nya!*", 24 | ); 25 | } 26 | 27 | let cap = "*– 乂 Hasil Pencarian NPMJS - Package Info*\n\n"; 28 | for (let i of data.objects.slice(0, 20)) { 29 | cap += `🔹 *Nama Package:* ${i.package.name}@^${i.package.version}\n`; 30 | cap += `📈 *Mingguan:* ${Func.h2k(i.downloads.weekly)} | *Bulanan:* ${Func.h2k(i.downloads.monthly)}\n`; 31 | cap += `👤 *Pembuat:* ${i.package.publisher.username}\n`; 32 | cap += `🕒 *Diperbarui:* ${Func.ago(i.package.date)}\n`; 33 | cap += Object.entries(i.package.links) 34 | .map(([a, b]) => `🔗 *${a.capitalize()}:* ${b}`) 35 | .join("\n"); 36 | cap += "\n\n"; 37 | } 38 | 39 | cap += `> © ${config.name}\n*– 乂 Terimakasih telah menggunakan bot kami!*`; 40 | m.reply(cap); 41 | } catch (error) { 42 | console.error("Error fetching npm package:", error); 43 | m.reply( 44 | "> ❌ *Terjadi kesalahan saat mencari package, coba lagi nanti.*", 45 | ); 46 | } 47 | }; 48 | } 49 | 50 | module.exports = new Command(); 51 | -------------------------------------------------------------------------------- /system/plugins/tools/pixiv.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "pixiv"; 4 | this.alias = []; 5 | this.category = ["tools"]; 6 | this.settings = { 7 | premium: true, 8 | }; 9 | this.description = "🔍 Mencari gambar dari Pixiv"; 10 | this.loading = true; 11 | } 12 | 13 | run = async (m, { sock, Func, Scraper, config, store, text }) => { 14 | if (!text) throw "> ❌ *Masukkan pencarian gambar yang kamu inginkan!*"; 15 | 16 | try { 17 | let { data } = await Func.fetchJson( 18 | `https://api.lolicon.app/setu/v1?r18=${text.includes("--r18") ? 1 : 0}&keyword=${text.replace("--r18", "").trim()}&limit=20`, 19 | ); 20 | 21 | if (!data[0]?.title) 22 | throw "> ❌ *Gambar tidak ditemukan! Coba kata kunci lain.*"; 23 | 24 | let cap = "*– 乂 Hasil Pencarian Pixiv - Gambar*\n\n"; 25 | cap += `🎨 *Judul:* ${data[0]?.title}\n`; 26 | cap += `🔞 *R18:* ${data[0]?.r18 ? "✓ Ya" : "❌ Tidak"}\n`; 27 | cap += `👤 *Penulis:* ${data[0]?.author}\n`; 28 | cap += `🏷️ *Tags:* ${data[0]?.tags.join(", ")}\n`; 29 | 30 | m.reply({ 31 | image: { 32 | url: data[0].url, 33 | }, 34 | caption: cap, 35 | }); 36 | m.reply("> ✅ *Gambar berhasil ditemukan!*"); 37 | } catch (error) { 38 | console.error("Error fetching Pixiv image:", error); 39 | m.reply("> ❌ *Terjadi kesalahan, coba lagi nanti.*"); 40 | } 41 | }; 42 | } 43 | 44 | module.exports = new Command(); 45 | -------------------------------------------------------------------------------- /system/plugins/tools/qc.js: -------------------------------------------------------------------------------- 1 | const { writeExif } = require(process.cwd() + "/lib/sticker"); 2 | const axios = require("axios"); 3 | 4 | class Command { 5 | constructor() { 6 | this.command = "qc"; 7 | this.alias = []; 8 | this.category = ["tools"]; 9 | this.settings = { 10 | limit: true, 11 | }; 12 | this.description = "Membuat bubble chat"; 13 | this.loading = true; 14 | } 15 | 16 | run = async (m, { sock, Func, Scraper, config, store, Uploader }) => { 17 | const q = m.quoted ? m.quoted : m; 18 | const mime = (q.msg || q).mimetype || ""; 19 | let reply; 20 | if (!m.quoted) { 21 | reply = {}; 22 | } else if (!q.sender === q.sender) { 23 | reply = { 24 | name: q.name, 25 | text: q.text || "", 26 | chatId: q.cht.split("@")[0], 27 | }; 28 | } 29 | let text; 30 | if (m.args.length >= 1) { 31 | text = m.args.join(" "); 32 | } else if (m.quoted) { 33 | text = m.quoted.text || ""; 34 | } else { 35 | throw "> Masukan pesan nya"; 36 | } 37 | 38 | const img = await q.download?.(); 39 | const pp = await sock 40 | .profilePictureUrl(q.sender, "image") 41 | .catch((_) => "https://telegra.ph/file/320b066dc81928b782c7b.png") 42 | .then(async (a) => await Func.fetchBuffer(a)); 43 | 44 | if (mime) { 45 | const obj = { 46 | type: "quote", 47 | format: "png", 48 | backgroundColor: "#161616", 49 | width: 512, 50 | height: 768, 51 | scale: 2, 52 | messages: [ 53 | { 54 | entities: [], 55 | media: { 56 | url: await Uploader.Uguu(img), 57 | }, 58 | avatar: true, 59 | from: { 60 | id: m.key.remoteJid.split("@")[0], 61 | name: q.pushName, 62 | photo: { 63 | url: await Uploader.catbox(pp), 64 | }, 65 | }, 66 | text: text || "", 67 | replyMessage: reply, 68 | }, 69 | ], 70 | }; 71 | 72 | const json = await axios.post( 73 | "https://quotly.netorare.codes/generate", 74 | obj, 75 | { 76 | headers: { 77 | "Content-Type": "application/json", 78 | }, 79 | }, 80 | ); 81 | const buffer = Buffer.from(json.data.result.image, "base64"); 82 | const sticker = await writeExif( 83 | { 84 | mimetype: "image", 85 | data: buffer, 86 | }, 87 | { 88 | packName: config.sticker.packname, 89 | packPublish: config.sticker.author, 90 | }, 91 | ); 92 | m.reply({ 93 | sticker, 94 | }); 95 | } else { 96 | const obj = { 97 | type: "quote", 98 | format: "png", 99 | backgroundColor: "#161616", 100 | width: 512, 101 | height: 768, 102 | scale: 2, 103 | messages: [ 104 | { 105 | entities: [], 106 | avatar: true, 107 | from: { 108 | id: m.key.remoteJid.split("@")[0], 109 | name: q.pushName, 110 | photo: { 111 | url: await Uploader.catbox(pp), 112 | }, 113 | }, 114 | text: text || "", 115 | replyMessage: reply, 116 | }, 117 | ], 118 | }; 119 | 120 | const json = await axios.post( 121 | "https://quotly.netorare.codes/generate", 122 | obj, 123 | { 124 | headers: { 125 | "Content-Type": "application/json", 126 | }, 127 | }, 128 | ); 129 | const buffer = Buffer.from(json.data.result.image, "base64"); 130 | const sticker = await writeExif( 131 | { 132 | mimetype: "image", 133 | data: buffer, 134 | }, 135 | { 136 | packName: config.sticker.packname, 137 | packPublish: config.sticker.author, 138 | }, 139 | ); 140 | m.reply({ 141 | sticker, 142 | }); 143 | } 144 | }; 145 | } 146 | 147 | module.exports = new Command(); 148 | -------------------------------------------------------------------------------- /system/plugins/tools/remini.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | command: "remini", 3 | alias: ["hdr", "hd"], 4 | category: ["tools"], 5 | settings: { 6 | limit: true, 7 | }, 8 | description: "Jernihkan dan tingkatkan kualitas foto favoritmu dengan mudah!", 9 | loading: true, 10 | async run(m, { Scraper, Func }) { 11 | let target = m.quoted ? m.quoted : m; 12 | if (!/image/.test(target.msg.mimetype) || !target.isMedia) 13 | throw "⚠️ *Oops!* Harap kirim atau balas sebuah foto yang ingin dijernihkan."; 14 | 15 | let buffer = await target.download(); 16 | let enhancedImage = await Scraper.remini(buffer); 17 | let size = Func.formatSize(enhancedImage.length); 18 | 19 | m.reply({ 20 | image: enhancedImage, 21 | caption: `✨ *Remini - Photo Enhancer* ✨\n\n🖼️ *Foto telah berhasil dijernihkan!*\n📂 *Ukuran file hasil:* ${size}\n\n💡 *Tips:* Gunakan foto dengan kualitas dasar yang cukup baik untuk hasil terbaik.`, 22 | }); 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /system/plugins/tools/removebg.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "removebg"; 4 | this.alias = ["rembg", "hapuslatar"]; 5 | this.category = ["tools"]; 6 | this.settings = { 7 | limit: true, 8 | }; 9 | this.description = 10 | "Hapus latar belakang foto secara otomatis dengan mudah!"; 11 | this.loading = true; 12 | } 13 | 14 | run = async (m, { Func, Scraper }) => { 15 | let target = m.quoted ? m.quoted : m; 16 | if (!/image/.test(target.msg.mimetype)) 17 | throw "⚠️ *Oops!* Harap kirim atau balas foto yang ingin dihapus latarnya."; 18 | 19 | let buffer = await target.download(); 20 | let processedImage = await Scraper.removebg(buffer); 21 | 22 | let caption = `✨ *Remove Background Tool* ✨\n\n`; 23 | caption += `📂 *Ukuran asli:* ${Func.formatSize(buffer.length)}\n`; 24 | caption += `🎉 *Hasil telah diproses dengan sukses!*\n\n`; 25 | caption += `💡 *Tips:* Pastikan foto memiliki latar belakang yang kontras untuk hasil terbaik.`; 26 | 27 | m.reply({ 28 | image: { url: processedImage }, 29 | caption, 30 | }); 31 | }; 32 | } 33 | 34 | module.exports = new Command(); 35 | -------------------------------------------------------------------------------- /system/plugins/tools/tourl.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "tourl"; 4 | this.alias = ["upload"]; 5 | this.category = ["tools"]; 6 | this.settings = { 7 | limit: true, 8 | }; 9 | this.description = "Ubah media menjadi link dengan cepat dan mudah!"; 10 | this.loading = true; 11 | } 12 | 13 | run = async (m, { 14 | Uploader, 15 | Func 16 | }) => { 17 | let target = m.quoted ? m.quoted : m; 18 | if (!target.msg.mimetype) 19 | throw "⚠️ *Oops!* Harap kirim atau balas media (gambar/video) yang ingin diubah menjadi tautan."; 20 | 21 | let buffer = await target.download(); 22 | let url = await Uploader.catbox(buffer); 23 | 24 | let caption = `✨ *Media to URL Uploader* ✨\n\n`; 25 | caption += `📂 *Ukuran media:* ${Func.formatSize(buffer.length)}\n`; 26 | caption += `🔗 *Tautan hasil:* ${url}\n\n`; 27 | caption += `💡 *Tips:* Gunakan fitur ini untuk berbagi media dengan lebih mudah tanpa perlu mengunggah ulang.`; 28 | 29 | m.reply(caption); 30 | }; 31 | } 32 | 33 | module.exports = new Command(); -------------------------------------------------------------------------------- /system/plugins/tools/whatmusic.js: -------------------------------------------------------------------------------- 1 | class Command { 2 | constructor() { 3 | this.command = "whatmusic"; 4 | this.alias = []; 5 | this.category = ["tools"]; 6 | this.settings = { 7 | limit: true, 8 | }; 9 | this.description = 10 | "Cari judul lagu berdasarkan media audio yang kamu kirimkan!"; 11 | this.loading = true; 12 | } 13 | 14 | run = async (m, { Func }) => { 15 | let target = m.quoted ? m.quoted : m; 16 | if (!/audio/.test(target.msg.mimetype)) 17 | throw "⚠️ *Oops!* Harap balas pesan audio yang ingin dicari judul lagunya."; 18 | 19 | let buffer = await target.download(); 20 | let data = await whatmusic(buffer); 21 | 22 | if (!data || data.length === 0) 23 | throw "❌ *Maaf!* Tidak dapat menemukan informasi lagu dari audio tersebut."; 24 | 25 | let caption = `🎵 *What Music - Finder* 🎵\n\n`; 26 | for (let result of data) { 27 | caption += `🎶 *Judul:* ${result.title}\n`; 28 | caption += `🎤 *Artis:* ${result.artist}\n`; 29 | caption += `⏱️ *Durasi:* ${result.duration}\n`; 30 | caption += `🔗 *Sumber:* ${result.url.filter((x) => x).join("\n") || "Tidak ditemukan"}\n\n`; 31 | } 32 | 33 | caption += `💡 *Tips:* Kirim audio dengan kualitas yang jelas untuk hasil terbaik.`; 34 | m.reply(caption); 35 | }; 36 | } 37 | 38 | module.exports = new Command(); 39 | 40 | const acrcloud = require("acrcloud"); 41 | 42 | const acr = new acrcloud({ 43 | host: "identify-ap-southeast-1.acrcloud.com", 44 | access_key: "ee1b81b47cf98cd73a0072a761558ab1", 45 | access_secret: "ya9OPe8onFAnNkyf9xMTK8qRyMGmsghfuHrIMmUI", 46 | }); 47 | 48 | async function whatmusic(buffer) { 49 | let response = await acr.identify(buffer); 50 | let metadata = response.metadata; 51 | if (!metadata || !metadata.music) return []; 52 | 53 | return metadata.music.map((song) => ({ 54 | title: song.title, 55 | artist: song.artists.map((a) => a.name)[0], 56 | score: song.score, 57 | release: new Date(song.release_date).toLocaleDateString("id-ID"), 58 | duration: toTime(song.duration_ms), 59 | url: Object.keys(song.external_metadata) 60 | .map((key) => 61 | key === "youtube" 62 | ? "https://youtu.be/" + song.external_metadata[key].vid 63 | : key === "deezer" 64 | ? "https://www.deezer.com/us/track/" + 65 | song.external_metadata[key].track.id 66 | : key === "spotify" 67 | ? "https://open.spotify.com/track/" + 68 | song.external_metadata[key].track.id 69 | : "", 70 | ) 71 | .filter(Boolean), 72 | })); 73 | } 74 | 75 | function toTime(ms) { 76 | let minutes = Math.floor(ms / 60000) % 60; 77 | let seconds = Math.floor(ms / 1000) % 60; 78 | return [minutes, seconds].map((v) => v.toString().padStart(2, "0")).join(":"); 79 | } 80 | -------------------------------------------------------------------------------- /tmp/NekoHost.json: -------------------------------------------------------------------------------- 1 | { 2 | "msg": "Ayo beli server Nekohost 🚀" 3 | } --------------------------------------------------------------------------------