├── lib ├── rpg │ ├── healt.json │ ├── histori.json │ ├── judinya.json │ ├── potion.json │ ├── inventori.json │ ├── leveluser.json │ └── dungeon.js ├── binary.js ├── levelling.js ├── converter.js ├── lvlfunction.js ├── tictactoe.js ├── uploader.js ├── y2mate.js ├── exif.js ├── scraper.js └── myfunc.js ├── database ├── antilink.json └── language.json ├── media ├── fake.jpg ├── menu.jpg └── zaki.jpg ├── Procfile ├── Dockerfile ├── app.json ├── README.md ├── LICENSE ├── src ├── math.js └── database.json ├── package.json ├── config.js └── index.js /lib/rpg/healt.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /lib/rpg/histori.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /lib/rpg/judinya.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /lib/rpg/potion.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /database/antilink.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /database/language.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /lib/rpg/inventori.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /media/fake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KiZakiXD/Chitanda-Public/HEAD/media/fake.jpg -------------------------------------------------------------------------------- /media/menu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KiZakiXD/Chitanda-Public/HEAD/media/menu.jpg -------------------------------------------------------------------------------- /media/zaki.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KiZakiXD/Chitanda-Public/HEAD/media/zaki.jpg -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: npm i -g typescript && npm i -g pm2 && pm2 start index.js && pm2 save && pm2 logs 2 | -------------------------------------------------------------------------------- /lib/rpg/leveluser.json: -------------------------------------------------------------------------------- 1 | [{"id":"6283127014833@s.whatsapp.net","xp":1,"level":1},{"id":"6281365814200@s.whatsapp.net","xp":6374,"level":2}] -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-buster 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y \ 5 | ffmpeg \ 6 | imagemagick \ 7 | webp && \ 8 | apt-get upgrade -y && \ 9 | rm -rf /var/lib/apt/lists/* 10 | 11 | COPY package.json . 12 | 13 | RUN npm install 14 | 15 | COPY . . 16 | 17 | CMD ["node", "."] 18 | -------------------------------------------------------------------------------- /lib/binary.js: -------------------------------------------------------------------------------- 1 | async function dBinary(str) { 2 | var newBin = str.split(" ") 3 | var binCode = [] 4 | for (i = 0; i < newBin.length; i++) { 5 | binCode.push(String.fromCharCode(parseInt(newBin[i], 2))) 6 | } 7 | return binCode.join("") 8 | } 9 | 10 | async function eBinary(str = ''){ 11 | let res = '' 12 | res = str.split('').map(char => { 13 | return char.charCodeAt(0).toString(2); 14 | }).join(' ') 15 | return res 16 | } 17 | 18 | module.exports = { dBinary, eBinary } -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Chitanda - MD", 3 | "keywords": ["nodejs", "bot", "whatsapp bot", "whatsapp automation", "multi device"], 4 | "buildpacks": [ 5 | { 6 | "url": "heroku/nodejs" 7 | }, 8 | { 9 | "url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest" 10 | }, 11 | { 12 | "url": "https://github.com/DuckyTeam/heroku-buildpack-imagemagick" 13 | }, 14 | { 15 | "url": "https://github.com/clhuang/heroku-buildpack-webp-binaries.git" 16 | } 17 | ], 18 | "formation": { 19 | "worker": { 20 | "quantity": 1, 21 | "size": "free" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NOTE : SC JANGAN DIPERJUAL BELIKAN 2 | REUPLOAD ? BOLEH 3 | RECODE ? BOLEH 4 | JUAL ? MATI AJA LU SUU 5 | 6 | [ Teruntuk Manik Official Mohon Jangan Lagi Diperjual Belikan ] 7 | 8 | //━━━━━━━━━━━━━━━[ ᴄᴏᴍᴍᴀɴᴅ ᴛᴇʀᴍᴜx ]━━━━━━━━━━━━━━━\\ 9 | $ pkg upgrade && pkg update 10 | $ pkg install nodejs 11 | $ pkg install yarn 12 | $ pkg install git 13 | $ pkg install libwebp 14 | $ pkg install ffmpeg 15 | $ pkg install imagemagick 16 | $ termux-setup-storage 17 | $ cd /sdcard 18 | $ cp -r zakstore /$HOME 19 | $ cd 20 | $ cd zakstore 21 | $ npm install 22 | $ npm start 23 | 24 | //━━━━━━━━━━━━━━━[ ᴜᴘʟᴏᴀᴅ ᴛᴏ ʜᴇʀᴏᴋᴜ ]━━━━━━━━━━━━━━━\\ 25 | $ apt update 26 | $ apt upgrade 27 | $ pkg update 28 | $ pkg upgrade 29 | $ pkg install yarn 30 | $ pkg install git 31 | $ termux-setup-storage 32 | $ cd /sdcard 33 | $ cd chitanda-public 34 | $ yarn add heroku 35 | $ npm i -g heroku 36 | 37 | [ Next Command Cek Heroku ] 38 | 39 | //━━━━━━━━━━━━━━━[ ɴᴏᴛᴇ ]━━━━━━━━━━━━━━━\\ 40 | NOTE : Jika Mau Tanya Sesuatu Gausah Spam Jika Tidak Mau Di Block 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Dika Ardnt. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/levelling.js: -------------------------------------------------------------------------------- 1 | export const growth = Math.pow(Math.PI / Math.E, 1.618) * Math.E * .75 2 | export function xpRange(level, multiplier = global.multiplier || 1) { 3 | if (level < 0) 4 | throw new TypeError('level cannot be negative value') 5 | level = Math.floor(level) 6 | let min = level === 0 ? 0 : Math.round(Math.pow(level, growth) * multiplier) + 1 7 | let max = Math.round(Math.pow(++level, growth) * multiplier) 8 | return { 9 | min, 10 | max, 11 | xp: max - min 12 | } 13 | } 14 | export function findLevel(xp, multiplier = global.multiplier || 1) { 15 | if (xp === Infinity) 16 | return Infinity 17 | if (isNaN(xp)) 18 | return NaN 19 | if (xp <= 0) 20 | return -1 21 | let level = 0 22 | do 23 | level++ 24 | while (xpRange(level, multiplier).min <= xp) 25 | return --level 26 | } 27 | export function canLevelUp(level, xp, multiplier = global.multiplier || 1) { 28 | if (level < 0) 29 | return false 30 | if (xp === Infinity) 31 | return true 32 | if (isNaN(xp)) 33 | return false 34 | if (xp <= 0) 35 | return false 36 | return level < findLevel(xp, multiplier) 37 | } -------------------------------------------------------------------------------- /src/math.js: -------------------------------------------------------------------------------- 1 | let modes = { 2 | noob: [-3, 3,-3, 3, '+-', 15000, 10], 3 | easy: [-10, 10, -10, 10, '*/+-', 20000, 40], 4 | medium: [-40, 40, -20, 20, '*/+-', 40000, 150], 5 | hard: [-100, 100, -70, 70, '*/+-', 60000, 350], 6 | extreme: [-999999, 999999, -999999, 999999, '*/', 99999, 9999], 7 | impossible: [-99999999999, 99999999999, -99999999999, 999999999999, '*/', 30000, 35000], 8 | impossible2: [-999999999999999, 999999999999999, -999, 999, '/', 30000, 50000] 9 | } 10 | 11 | let operators = { 12 | '+': '+', 13 | '-': '-', 14 | '*': '×', 15 | '/': '÷' 16 | } 17 | 18 | function randomInt(from, to) { 19 | if (from > to) [from, to] = [to, from] 20 | from = Math.floor(from) 21 | to = Math.floor(to) 22 | return Math.floor((to - from) * Math.random() + from) 23 | } 24 | 25 | function pickRandom(list) { 26 | return list[Math.floor(Math.random() * list.length)] 27 | } 28 | 29 | function genMath(mode) { 30 | return new Promise((resolve, reject) => { 31 | let [a1, a2, b1, b2, ops, time, bonus] = modes[mode] 32 | let a = randomInt(a1, a2) 33 | let b = randomInt(b1, b2) 34 | let op = pickRandom([...ops]) 35 | let result = (new Function(`return ${a} ${op.replace('/', '*')} ${b < 0 ? `(${b})` : b}`))() 36 | if (op == '/') [a, result] = [result, a] 37 | hasil = { 38 | soal: `${a} ${operators[op]} ${b}`, 39 | mode: mode, 40 | waktu: time, 41 | hadiah: bonus, 42 | jawaban: result 43 | } 44 | resolve(hasil) 45 | }) 46 | } 47 | 48 | module.exports = { modes, operators, randomInt, pickRandom, genMath } 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chitanda-md", 3 | "version": "1.0.0", 4 | "description": "No Description", 5 | "main": "index.js", 6 | "type": "commonjs", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "keywords": [ 11 | "termux", 12 | "whatsapp", 13 | "2021", 14 | "wabase-md", 15 | "noenc", 16 | "baileys-md", 17 | "kizakixd", 18 | "bot-md", 19 | "multi-device" 20 | ], 21 | "author": "Xeon", 22 | "license": "MIT", 23 | "dependencies": { 24 | "@adiwajshing/baileys": "^4.0.1", 25 | "@adiwajshing/keyed-db": "^0.2.4", 26 | "awesome-phonenumber": "^2.64.0", 27 | "axios": "^0.24.0", 28 | "chalk": "^4.1.2", 29 | "cheerio": "^1.0.0-rc.10", 30 | "child_process": "^1.0.2", 31 | "crypto": "^1.0.1", 32 | "file-type": "^16.5.3", 33 | "fluent-ffmpeg": "^2.1.2", 34 | "fs": "0.0.1-security", 35 | "got": "^11.8.3", 36 | "g-i-s": "^2.1.6", 37 | "google-it": "^1.6.2", 38 | "human-readable": "^0.2.1", 39 | "xfarr-api": "^1.0.0", 40 | "hxz-api": "^1.0.1", 41 | "jimp": "^0.16.1", 42 | "jsdom": "^16.4.0", 43 | "moment-timezone": "^0.5.34", 44 | "node-cron": "^3.0.0", 45 | "node-fetch": "^2.6.1", 46 | "node-webpmux": "^3.1.0", 47 | "os": "^0.1.2", 48 | "path": "^0.12.7", 49 | "perf_hooks": "0.0.1", 50 | "pino": "^7.0.5", 51 | "qrcode-terminal": "^0.12.0", 52 | "request": "^2.88.2", 53 | "remove.bg": "^1.3.0", 54 | "scrape-primbon": "^1.1.0", 55 | "util": "^0.12.4", 56 | "yargs": "^17.2.1", 57 | "yt-search": "^2.10.2" 58 | }, 59 | "directories": { 60 | "lib": "lib", 61 | "src": "src" 62 | }, 63 | "devDependencies": {}, 64 | "repository": { 65 | "type": "git", 66 | "url": "git+https://github.com/KiZakiXD/Chitanda-Public.git" 67 | }, 68 | "bugs": { 69 | "url": "https://github.com/KiZakiXD/Chitanda-Public/issues" 70 | }, 71 | "homepage": "https://github.com/KiZakiXD/Chitanda-Public#readme" 72 | } 73 | -------------------------------------------------------------------------------- /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 = path.join(__dirname, '../src', + new Date + '.' + ext) 9 | let out = tmp + '.' + ext2 10 | await fs.promises.writeFile(tmp, buffer) 11 | spawn('ffmpeg', [ 12 | '-y', 13 | '-i', tmp, 14 | ...args, 15 | out 16 | ]) 17 | .on('error', reject) 18 | .on('close', async (code) => { 19 | try { 20 | await fs.promises.unlink(tmp) 21 | if (code !== 0) return reject(code) 22 | resolve(await fs.promises.readFile(out)) 23 | await fs.promises.unlink(out) 24 | } catch (e) { 25 | reject(e) 26 | } 27 | }) 28 | } catch (e) { 29 | reject(e) 30 | } 31 | }) 32 | } 33 | 34 | /** 35 | * Convert Audio to Playable WhatsApp Audio 36 | * @param {Buffer} buffer Audio Buffer 37 | * @param {String} ext File Extension 38 | */ 39 | function toAudio(buffer, ext) { 40 | return ffmpeg(buffer, [ 41 | '-vn', 42 | '-ac', '2', 43 | '-b:a', '128k', 44 | '-ar', '44100', 45 | '-f', 'mp3' 46 | ], ext, 'mp3') 47 | } 48 | 49 | /** 50 | * Convert Audio to Playable WhatsApp PTT 51 | * @param {Buffer} buffer Audio Buffer 52 | * @param {String} ext File Extension 53 | */ 54 | function toPTT(buffer, ext) { 55 | return ffmpeg(buffer, [ 56 | '-vn', 57 | '-c:a', 'libopus', 58 | '-b:a', '128k', 59 | '-vbr', 'on', 60 | '-compression_level', '10' 61 | ], ext, 'opus') 62 | } 63 | 64 | /** 65 | * Convert Audio to Playable WhatsApp Video 66 | * @param {Buffer} buffer Video Buffer 67 | * @param {String} ext File Extension 68 | */ 69 | function toVideo(buffer, ext) { 70 | return ffmpeg(buffer, [ 71 | '-c:v', 'libx264', 72 | '-c:a', 'aac', 73 | '-ab', '128k', 74 | '-ar', '44100', 75 | '-crf', '32', 76 | '-preset', 'slow' 77 | ], ext, 'mp4') 78 | } 79 | 80 | module.exports = { 81 | toAudio, 82 | toPTT, 83 | toVideo, 84 | ffmpeg, 85 | } 86 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | //═══════[ THANKS 2K SUBSCRIBER ]════════\\ 2 | /* 3 | • SCRIPT FULL NO ENC 4 | • APIKEY PREMIUM 5 | */ 6 | const fs = require('fs') 7 | const chalk = require('chalk') 8 | 9 | global.APIs = { 10 | zenz: 'https://zenzapis.xyz', 11 | } 12 | global.APIKeys = { 13 | 'https://zenzapi.xyz': '805a6c3fa9', //Apikey Premium 14 | } 15 | global.Prefix = 'Multi' 16 | global.meki = '6285860486479' 17 | global.ownerNumber = '6285860486479' 18 | global.botname = 'Chitanda - MD' 19 | global.ownername = '𝙸 𝙰𝚖 𝙺𝚒𝚉𝚊𝚔𝚒𝚇𝙳' 20 | global.owner = ['6285860486479'] 21 | global.pemilik = ['6285860486479'] 22 | global.premium = ['6285860486479'] 23 | global.pengguna = 'syamsul fajri' 24 | global.botnma = 'Riski BOTZ' 25 | global.ownernma = 'Syamsul fajri' 26 | global.packname = 'Syamsul fajri' 27 | global.author = 'Chitanda - MD' 28 | global.sessionName = 'rizki bot' 29 | global.prefa = ['#','!','/',''] 30 | global.sp = '» ' 31 | global.mess = { 32 | success: 'Berhasil.', 33 | admin: 'Fitur Khusus Admin Group!', 34 | botAdmin: 'Bot Harus Menjadi Admin Terlebih Dahulu!', 35 | owner: 'Fitur Khusus Owner Bot', 36 | group: 'Fitur Digunakan Hanya Untuk Group!', 37 | private: 'Fitur Digunakan Hanya Untuk Private Chat!', 38 | bot: 'Fitur Khusus Pengguna Nomor Bot', 39 | wait: 'Loading...', 40 | done: 'Done', 41 | endLimit: 'Limit Harian Anda Telah Habis, Limit Akan Direset Setiap Jam 12', 42 | wrongFormat: 'Perintah Salah!!\nSertakan Link setelah Command..', 43 | example1: 'Welcome @user Di Group @subject Jangan Lupa Baca Rules @desc\n\nNote :\n1. @user (Mention User Join)\n2. @subject (Group Name)\n3. @tanggal (Date Now)\n4. @desc (Get Description Group)' 44 | , 45 | example2: 'Good Bye @user Di Group @subject Jangan Lupa Baca Rules @desc\n\nNote :\n1. @user (Mention User Join)\n2. @subject (Group Name)\n3. @tanggal (Date Now)\n4. @desc (Get Description Group)' 46 | } 47 | global.limitawal = { 48 | premium: "Infinity", 49 | free: 100 50 | } 51 | 52 | global.thumb = fs.readFileSync('./media/zaki.jpg') 53 | global.fakeImg = fs.readFileSync('./media/fake.jpg') 54 | 55 | let file = require.resolve(__filename) 56 | fs.watchFile(file, () => { 57 | fs.unwatchFile(file) 58 | console.log(chalk.redBright(`Update'${__filename}'`)) 59 | delete require.cache[file] 60 | require(file) 61 | }) 62 | -------------------------------------------------------------------------------- /lib/rpg/dungeon.js: -------------------------------------------------------------------------------- 1 | [{"result": "https://captain.ph/wp-content/uploads/elementor/thumbs/02BW053T1-full-orhl5ufhf1xjxg7jvzfgbp958hpu76oye7paovzb5q.png"}, 2 | {"result": "https://i.ibb.co/9vqRLxg/3e12eb3f4b36e34a82d12de594105509.jpg"}, 3 | {"result": "https://i.ibb.co/8PNzkDg/d752ce600f6bbf1766aaad0edd184c95.jpg"}, 4 | {"result": "https://i.ibb.co/bsXfR0G/b38c234a1d05b14259fc48434830df72.jpg"}, 5 | {"result": "https://i.ibb.co/qF4KQBP/18f6ec4f59b6bd373a08df977b0001cf.jpg"}, 6 | {"result": "https://i.ibb.co/S61nW0y/fe50010ee76fe9b1e196bcc0144e7e8c.jpg"}, 7 | {"result": "https://i.ibb.co/zSLf7k6/a615370161a49003d96a9501c989f50d.jpg"}, 8 | {"result": "https://i.ibb.co/PwyzGm0/40354fdd2078127a8a070ac53f41b375.jpg"}, 9 | {"result": "https://i.ibb.co/yYgxnT8/dbf7c42c247ca6a46a6fc9f457ebd426.jpg"}, 10 | {"result": "https://i.ibb.co/M9nmhjd/b2587af0dd56fc4ec4043fe4bd0bb08b.jpg"}, 11 | {"result": "https://i.ibb.co/12kjHBw/4fb43d5685a55304266ffb380b13511b.jpg"}, 12 | {"result": "https://i.ibb.co/BnSQCHM/fbad11adbad4b01ce06730c8736bd6cd.jpg"}, 13 | {"result": "https://i.ibb.co/0QtYNjL/2fc5a6299b7af23a09aa8e87e878ff2b.jpg"}, 14 | {"result": "https://i.ibb.co/BLrgSyz/a25fe0233461b92b7e3be3b801d1963c.jpg"}, 15 | {"result": "https://i.ibb.co/cyXShW7/affbb1aa3fbe454f02246f1caf34cc71.jpg"}, 16 | {"result": "https://i.ibb.co/dGKXSz5/8f6ef6cb64eca372c8e9e50b7f83be1e.jpg"}, 17 | {"result": "https://i.ibb.co/9pKDV3C/072ab52b8430e4b8e71d2e13047ec81c.jpg"}, 18 | {"result": "https://i.ibb.co/fFqWPSN/9c2446a43e0406bfaa88b858b5af2b71.jpg"}, 19 | {"result": "https://i.ibb.co/bm1N9S6/0b85fd508fe76a7e06d0c285657e5700.jpg"}, 20 | {"result": "https://i.ibb.co/3yzhzdy/138655764fe4c350751c3d6a19b32d6e.jpg"}, 21 | {"result": "https://i.ibb.co/MNt4Twv/54d533aa1d0575ceb06c333dc2f6792c.jpg"}, 22 | {"result": "https://i.ibb.co/wcyCGRt/368e980738474028e1c51885c996bc42.jpg"}, 23 | {"result": "https://i.ibb.co/Scxq9KP/9141293b902071dece21a2fa08c92793.jpg"}, 24 | {"result": "https://i.ibb.co/MstjyJf/bc4c1b3796c70215b2e4fc498442c878.jpg"}, 25 | {"result": "https://i.ibb.co/hyX6P8C/1b8a923dbaa16cc909f60fd02d3bc0c1.jpg"}, 26 | {"result": "https://i.ibb.co/pLGLXgy/c351093ace6c8012f7bb270d19eab06e.jpg"}, 27 | {"result": "https://i.ibb.co/bWyQmP9/6a0538e61abc583ebfd77c9f0afcf144.jpg"}, 28 | {"result": "https://i.ibb.co/8xMtczB/b0f1219d622546aac56c6c532f117cb5.jpg"}, 29 | {"result": "https://i.ibb.co/YthC5Vm/fc50206cc9fa552b057852d5a5b626af.jpg"}, 30 | {"result": "https://i.ibb.co/dWJFDHw/1a5e7e4cb65c318866f83dfa9dc95f94.jpg"}, 31 | {"result": "https://i.ibb.co/mSnKN0t/e325358236b5a117512f639f52ee7cdf.jpg"} 32 | ] -------------------------------------------------------------------------------- /lib/lvlfunction.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | let _level = JSON.parse(fs.readFileSync('./lib/rpg/leveluser.json')) 3 | 4 | 5 | const getLevelingXp = (sender) => { 6 | let position = false 7 | Object.keys(_level).forEach((i) => { 8 | if (_level[i].id === sender) { 9 | position = i 10 | } 11 | }) 12 | if (position !== false) { 13 | return _level[position].xp 14 | } 15 | } 16 | 17 | const getLevelingLevel = (sender) => { 18 | let position = false 19 | Object.keys(_level).forEach((i) => { 20 | if (_level[i].id === sender) { 21 | position = i 22 | } 23 | }) 24 | if (position !== false) { 25 | return _level[position].level 26 | } 27 | } 28 | 29 | const getLevelingId = (sender) => { 30 | let position = false 31 | Object.keys(_level).forEach((i) => { 32 | if (_level[i].id === sender) { 33 | position = i 34 | } 35 | }) 36 | if (position !== false) { 37 | return _level[position].id 38 | } 39 | } 40 | 41 | const addLevelingXp = (sender, amount) => { 42 | let position = false 43 | Object.keys(_level).forEach((i) => { 44 | if (_level[i].id === sender) { 45 | position = i 46 | } 47 | }) 48 | if (position !== false) { 49 | _level[position].xp += amount 50 | fs.writeFileSync('./lib/rpg/leveluser.json', JSON.stringify(_level)) 51 | } 52 | } 53 | 54 | const addLevelingLevel = (sender, amount) => { 55 | let position = false 56 | Object.keys(_level).forEach((i) => { 57 | if (_level[i].id === sender) { 58 | position = i 59 | } 60 | }) 61 | if (position !== false) { 62 | _level[position].level += amount 63 | fs.writeFileSync('./lib/rpg/leveluser.json', JSON.stringify(_level)) 64 | } 65 | } 66 | 67 | const addLevelingId = (sender) => { 68 | const obj = {id: sender, xp: 1, level: 1} 69 | _level.push(obj) 70 | fs.writeFileSync('./lib/rpg/leveluser.json', JSON.stringify(_level)) 71 | } 72 | 73 | module.exports = { addLevelingId, addLevelingLevel, addLevelingXp, getLevelingId, getLevelingLevel, getLevelingXp } -------------------------------------------------------------------------------- /lib/tictactoe.js: -------------------------------------------------------------------------------- 1 | class TicTacToe { 2 | constructor(playerX = 'x', playerO = 'o') { 3 | this.playerX = playerX 4 | this.playerO = playerO 5 | this._currentTurn = false 6 | this._x = 0 7 | this._o = 0 8 | this.turns = 0 9 | } 10 | 11 | get board() { 12 | return this._x | this._o 13 | } 14 | 15 | get currentTurn() { 16 | return this._currentTurn ? this.playerO : this.playerX 17 | } 18 | 19 | get enemyTurn() { 20 | return this._currentTurn ? this.playerX : this.playerO 21 | } 22 | 23 | static check(state) { 24 | for (let combo of [7, 56, 73, 84, 146, 273, 292, 448]) 25 | if ((state & combo) === combo) 26 | return !0 27 | return !1 28 | } 29 | 30 | /** 31 | * ```js 32 | * TicTacToe.toBinary(1, 2) // 0b010000000 33 | * ``` 34 | */ 35 | static toBinary(x = 0, y = 0) { 36 | if (x < 0 || x > 2 || y < 0 || y > 2) throw new Error('invalid position') 37 | return 1 << x + (3 * y) 38 | } 39 | 40 | /** 41 | * @param player `0` is `X`, `1` is `O` 42 | * 43 | * - `-3` `Game Ended` 44 | * - `-2` `Invalid` 45 | * - `-1` `Invalid Position` 46 | * - ` 0` `Position Occupied` 47 | * - ` 1` `Sucess` 48 | * @returns {-3|-2|-1|0|1} 49 | */ 50 | turn(player = 0, x = 0, y) { 51 | if (this.board === 511) return -3 52 | let pos = 0 53 | if (y == null) { 54 | if (x < 0 || x > 8) return -1 55 | pos = 1 << x 56 | } else { 57 | if (x < 0 || x > 2 || y < 0 || y > 2) return -1 58 | pos = TicTacToe.toBinary(x, y) 59 | } 60 | if (this._currentTurn ^ player) return -2 61 | if (this.board & pos) return 0 62 | this[this._currentTurn ? '_o' : '_x'] |= pos 63 | this._currentTurn = !this._currentTurn 64 | this.turns++ 65 | return 1 66 | } 67 | 68 | /** 69 | * @returns {('X'|'O'|1|2|3|4|5|6|7|8|9)[]} 70 | */ 71 | static render(boardX = 0, boardO = 0) { 72 | let x = parseInt(boardX.toString(2), 4) 73 | let y = parseInt(boardO.toString(2), 4) * 2 74 | return [...(x + y).toString(4).padStart(9, '0')].reverse().map((value, index) => value == 1 ? 'X' : value == 2 ? 'O' : ++index) 75 | } 76 | 77 | /** 78 | * @returns {('X'|'O'|1|2|3|4|5|6|7|8|9)[]} 79 | */ 80 | render() { 81 | return TicTacToe.render(this._x, this._o) 82 | } 83 | 84 | get winner() { 85 | let x = TicTacToe.check(this._x) 86 | let o = TicTacToe.check(this._o) 87 | return x ? this.playerX : o ? this.playerO : false 88 | } 89 | } 90 | 91 | new TicTacToe().turn 92 | 93 | module.exports = TicTacToe -------------------------------------------------------------------------------- /lib/uploader.js: -------------------------------------------------------------------------------- 1 | let axios = require('axios') 2 | let BodyForm = require('form-data') 3 | let { fromBuffer } = require('file-type') 4 | let fetch = require('node-fetch') 5 | let fs = require('fs') 6 | let cheerio = require('cheerio') 7 | 8 | 9 | 10 | function TelegraPh (Path) { 11 | return new Promise (async (resolve, reject) => { 12 | if (!fs.existsSync(Path)) return reject(new Error("File not Found")) 13 | try { 14 | const form = new BodyForm(); 15 | form.append("file", fs.createReadStream(Path)) 16 | const data = await axios({ 17 | url: "https://telegra.ph/upload", 18 | method: "POST", 19 | headers: { 20 | ...form.getHeaders() 21 | }, 22 | data: form 23 | }) 24 | return resolve("https://telegra.ph" + data.data[0].src) 25 | } catch (err) { 26 | return reject(new Error(String(err))) 27 | } 28 | }) 29 | } 30 | 31 | async function UploadFileUgu (input) { 32 | return new Promise (async (resolve, reject) => { 33 | const form = new BodyForm(); 34 | form.append("files[]", fs.createReadStream(input)) 35 | await axios({ 36 | url: "https://uguu.se/upload.php", 37 | method: "POST", 38 | headers: { 39 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36", 40 | ...form.getHeaders() 41 | }, 42 | data: form 43 | }).then((data) => { 44 | resolve(data.data.files[0]) 45 | }).catch((err) => reject(err)) 46 | }) 47 | } 48 | 49 | function webp2mp4File(path) { 50 | return new Promise((resolve, reject) => { 51 | const form = new BodyForm() 52 | form.append('new-image-url', '') 53 | form.append('new-image', fs.createReadStream(path)) 54 | axios({ 55 | method: 'post', 56 | url: 'https://s6.ezgif.com/webp-to-mp4', 57 | data: form, 58 | headers: { 59 | 'Content-Type': `multipart/form-data; boundary=${form._boundary}` 60 | } 61 | }).then(({ data }) => { 62 | const bodyFormThen = new BodyForm() 63 | const $ = cheerio.load(data) 64 | const file = $('input[name="file"]').attr('value') 65 | bodyFormThen.append('file', file) 66 | bodyFormThen.append('convert', "Convert WebP to MP4!") 67 | axios({ 68 | method: 'post', 69 | url: 'https://ezgif.com/webp-to-mp4/' + file, 70 | data: bodyFormThen, 71 | headers: { 72 | 'Content-Type': `multipart/form-data; boundary=${bodyFormThen._boundary}` 73 | } 74 | }).then(({ data }) => { 75 | const $ = cheerio.load(data) 76 | const result = 'https:' + $('div#output > p.outfile > video > source').attr('src') 77 | resolve({ 78 | status: true, 79 | message: "Created By MRHRTZ", 80 | result: result 81 | }) 82 | }).catch(reject) 83 | }).catch(reject) 84 | }) 85 | } 86 | 87 | module.exports = { TelegraPh, UploadFileUgu, webp2mp4File } 88 | -------------------------------------------------------------------------------- /lib/y2mate.js: -------------------------------------------------------------------------------- 1 | let fetch = require('node-fetch') 2 | let { JSDOM } = require('jsdom') 3 | 4 | function post(url, formdata) { 5 | return fetch(url, { 6 | method: 'POST', 7 | headers: { 8 | accept: "*/*", 9 | 'accept-language': "en-US,en;q=0.9", 10 | 'content-type': "application/x-www-form-urlencoded; charset=UTF-8" 11 | }, 12 | body: new URLSearchParams(Object.entries(formdata)) 13 | }) 14 | } 15 | const ytIdRegex = /(?:youtube\.com\/\S*(?:(?:\/e(?:mbed))?\/|watch\?(?:\S*?&?v\=))|youtu\.be\/)([a-zA-Z0-9_-]{6,11})/ 16 | 17 | /** 18 | * Download YouTube Video via y2mate 19 | * @param {String} url YouTube Video URL 20 | * @param {String} quality (avaiable: `144p`, `240p`, `360p`, `480p`, `720p`, `1080p`, `1440p`, `2160p`) 21 | * @param {String} type (avaiable: `mp3`, `mp4`) 22 | * @param {String} bitrate (avaiable for video: `144`, `240`, `360`, `480`, `720`, `1080`, `1440`, `2160`) 23 | * (avaiable for audio: `128`) 24 | * @param {String} server (avaiable: `id4`, `en60`, `en61`, `en68`) 25 | */ 26 | async function yt(url, quality, type, bitrate, server = 'en68') { 27 | let ytId = ytIdRegex.exec(url) 28 | url = 'https://youtu.be/' + ytId[1] 29 | let res = await post(`https://www.y2mate.com/mates/${server}/analyze/ajax`, { 30 | url, 31 | q_auto: 0, 32 | ajax: 1 33 | }) 34 | let json = await res.json() 35 | let { document } = (new JSDOM(json.result)).window 36 | let tables = document.querySelectorAll('table') 37 | let table = tables[{ mp4: 0, mp3: 1 }[type] || 0] 38 | let list 39 | switch (type) { 40 | case 'mp4': 41 | list = Object.fromEntries([...table.querySelectorAll('td > a[href="#"]')].filter(v => !/\.3gp/.test(v.innerHTML)).map(v => [v.innerHTML.match(/.*?(?=\()/)[0].trim(), v.parentElement.nextSibling.nextSibling.innerHTML])) 42 | break 43 | case 'mp3': 44 | list = { 45 | '128kbps': table.querySelector('td > a[href="#"]').parentElement.nextSibling.nextSibling.innerHTML 46 | } 47 | break 48 | default: 49 | list = {} 50 | } 51 | let filesize = list[quality] 52 | let id = /var k__id = "(.*?)"/.exec(document.body.innerHTML) || ['', ''] 53 | let thumb = document.querySelector('img').src 54 | let title = document.querySelector('b').innerHTML 55 | let res2 = await post(`https://www.y2mate.com/mates/${server}/convert`, { 56 | type: 'youtube', 57 | _id: id[1], 58 | v_id: ytId[1], 59 | ajax: '1', 60 | token: '', 61 | ftype: type, 62 | fquality: bitrate 63 | }) 64 | let json2 = await res2.json() 65 | let KB = parseFloat(filesize) * (1000 * /MB$/.test(filesize)) 66 | let resUrl = / { 17 | ff(tmpFileIn) 18 | .on("error", reject) 19 | .on("end", () => resolve(true)) 20 | .addOutputOptions([ 21 | "-vcodec", 22 | "libwebp", 23 | "-vf", 24 | "scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease,fps=15, pad=320:320:-1:-1:color=white@0.0, split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse" 25 | ]) 26 | .toFormat("webp") 27 | .save(tmpFileOut) 28 | }) 29 | 30 | const buff = fs.readFileSync(tmpFileOut) 31 | fs.unlinkSync(tmpFileOut) 32 | fs.unlinkSync(tmpFileIn) 33 | return buff 34 | } 35 | 36 | async function videoToWebp (media) { 37 | 38 | const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 39 | const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.mp4`) 40 | 41 | fs.writeFileSync(tmpFileIn, media) 42 | 43 | await new Promise((resolve, reject) => { 44 | ff(tmpFileIn) 45 | .on("error", reject) 46 | .on("end", () => resolve(true)) 47 | .addOutputOptions([ 48 | "-vcodec", 49 | "libwebp", 50 | "-vf", 51 | "scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease,fps=15, pad=320:320:-1:-1:color=white@0.0, split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse", 52 | "-loop", 53 | "0", 54 | "-ss", 55 | "00:00:00", 56 | "-t", 57 | "00:00:05", 58 | "-preset", 59 | "default", 60 | "-an", 61 | "-vsync", 62 | "0" 63 | ]) 64 | .toFormat("webp") 65 | .save(tmpFileOut) 66 | }) 67 | 68 | const buff = fs.readFileSync(tmpFileOut) 69 | fs.unlinkSync(tmpFileOut) 70 | fs.unlinkSync(tmpFileIn) 71 | return buff 72 | } 73 | 74 | async function writeExifImg (media, metadata) { 75 | let wMedia = await imageToWebp(media) 76 | const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 77 | const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 78 | fs.writeFileSync(tmpFileIn, wMedia) 79 | 80 | if (metadata.packname || metadata.author) { 81 | const img = new webp.Image() 82 | const json = { "sticker-pack-id": `https://github.com/DikaArdnt/Hisoka-Morou`, "sticker-pack-name": metadata.packname, "sticker-pack-publisher": metadata.author, "emojis": metadata.categories ? metadata.categories : [""] } 83 | const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]) 84 | const jsonBuff = Buffer.from(JSON.stringify(json), "utf-8") 85 | const exif = Buffer.concat([exifAttr, jsonBuff]) 86 | exif.writeUIntLE(jsonBuff.length, 14, 4) 87 | await img.load(tmpFileIn) 88 | fs.unlinkSync(tmpFileIn) 89 | img.exif = exif 90 | await img.save(tmpFileOut) 91 | return tmpFileOut 92 | } 93 | } 94 | 95 | async function writeExifVid (media, metadata) { 96 | let wMedia = await videoToWebp(media) 97 | const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 98 | const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 99 | fs.writeFileSync(tmpFileIn, wMedia) 100 | 101 | if (metadata.packname || metadata.author) { 102 | const img = new webp.Image() 103 | const json = { "sticker-pack-id": `https://github.com/DikaArdnt/Hisoka-Morou`, "sticker-pack-name": metadata.packname, "sticker-pack-publisher": metadata.author, "emojis": metadata.categories ? metadata.categories : [""] } 104 | const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]) 105 | const jsonBuff = Buffer.from(JSON.stringify(json), "utf-8") 106 | const exif = Buffer.concat([exifAttr, jsonBuff]) 107 | exif.writeUIntLE(jsonBuff.length, 14, 4) 108 | await img.load(tmpFileIn) 109 | fs.unlinkSync(tmpFileIn) 110 | img.exif = exif 111 | await img.save(tmpFileOut) 112 | return tmpFileOut 113 | } 114 | } 115 | 116 | async function writeExif (media, metadata) { 117 | let wMedia = /webp/.test(media.mimetype) ? media.data : /image/.test(media.mimetype) ? await imageToWebp(media.data) : /video/.test(media.mimetype) ? await videoToWebp(media.data) : "" 118 | const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 119 | const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`) 120 | fs.writeFileSync(tmpFileIn, wMedia) 121 | 122 | if (metadata.packname || metadata.author) { 123 | const img = new webp.Image() 124 | const json = { "sticker-pack-id": `https://github.com/DikaArdnt/Hisoka-Morou`, "sticker-pack-name": metadata.packname, "sticker-pack-publisher": metadata.author, "emojis": metadata.categories ? metadata.categories : [""] } 125 | const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]) 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(tmpFileIn) 130 | fs.unlinkSync(tmpFileIn) 131 | img.exif = exif 132 | await img.save(tmpFileOut) 133 | return tmpFileOut 134 | } 135 | } 136 | 137 | module.exports = { imageToWebp, videoToWebp, writeExifImg, writeExifVid, writeExif } 138 | -------------------------------------------------------------------------------- /lib/scraper.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios') 2 | const cheerio = require('cheerio') 3 | 4 | 5 | function pinterest(querry){ 6 | return new Promise(async(resolve,reject) => { 7 | axios.get('https://id.pinterest.com/search/pins/?autologin=true&q=' + querry, { 8 | headers: { 9 | "cookie" : "_auth=1; _b=\"AVna7S1p7l1C5I9u0+nR3YzijpvXOPc6d09SyCzO+DcwpersQH36SmGiYfymBKhZcGg=\"; _pinterest_sess=TWc9PSZHamJOZ0JobUFiSEpSN3Z4a2NsMk9wZ3gxL1NSc2k2NkFLaUw5bVY5cXR5alZHR0gxY2h2MVZDZlNQalNpUUJFRVR5L3NlYy9JZkthekp3bHo5bXFuaFZzVHJFMnkrR3lTbm56U3YvQXBBTW96VUgzVUhuK1Z4VURGKzczUi9hNHdDeTJ5Y2pBTmxhc2owZ2hkSGlDemtUSnYvVXh5dDNkaDN3TjZCTk8ycTdHRHVsOFg2b2NQWCtpOWxqeDNjNkk3cS85MkhhSklSb0hwTnZvZVFyZmJEUllwbG9UVnpCYVNTRzZxOXNJcmduOVc4aURtM3NtRFo3STlmWjJvSjlWTU5ITzg0VUg1NGhOTEZzME9SNFNhVWJRWjRJK3pGMFA4Q3UvcHBnWHdaYXZpa2FUNkx6Z3RNQjEzTFJEOHZoaHRvazc1c1UrYlRuUmdKcDg3ZEY4cjNtZlBLRTRBZjNYK0lPTXZJTzQ5dU8ybDdVS015bWJKT0tjTWYyRlBzclpiamdsNmtpeUZnRjlwVGJXUmdOMXdTUkFHRWloVjBMR0JlTE5YcmhxVHdoNzFHbDZ0YmFHZ1VLQXU1QnpkM1FqUTNMTnhYb3VKeDVGbnhNSkdkNXFSMXQybjRGL3pyZXRLR0ZTc0xHZ0JvbTJCNnAzQzE0cW1WTndIK0trY05HV1gxS09NRktadnFCSDR2YzBoWmRiUGZiWXFQNjcwWmZhaDZQRm1UbzNxc21pV1p5WDlabm1UWGQzanc1SGlrZXB1bDVDWXQvUis3elN2SVFDbm1DSVE5Z0d4YW1sa2hsSkZJb1h0MTFpck5BdDR0d0lZOW1Pa2RDVzNySWpXWmUwOUFhQmFSVUpaOFQ3WlhOQldNMkExeDIvMjZHeXdnNjdMYWdiQUhUSEFBUlhUVTdBMThRRmh1ekJMYWZ2YTJkNlg0cmFCdnU2WEpwcXlPOVZYcGNhNkZDd051S3lGZmo0eHV0ZE42NW8xRm5aRWpoQnNKNnNlSGFad1MzOHNkdWtER0xQTFN5Z3lmRERsZnZWWE5CZEJneVRlMDd2VmNPMjloK0g5eCswZUVJTS9CRkFweHc5RUh6K1JocGN6clc1JmZtL3JhRE1sc0NMTFlpMVErRGtPcllvTGdldz0=; _ir=0" 10 | } 11 | }).then(({ data }) => { 12 | const $ = cheerio.load(data) 13 | const result = []; 14 | const hasil = []; 15 | $('div > a').get().map(b => { 16 | const link = $(b).find('img').attr('src') 17 | result.push(link) 18 | }); 19 | result.forEach(v => { 20 | if(v == undefined) return 21 | hasil.push(v.replace(/236/g,'736')) 22 | }) 23 | hasil.shift(); 24 | resolve(hasil) 25 | }) 26 | }) 27 | } 28 | 29 | function wallpaper(title, page = '1') { 30 | return new Promise((resolve, reject) => { 31 | axios.get(`https://www.besthdwallpaper.com/search?CurrentPage=${page}&q=${title}`) 32 | .then(({ data }) => { 33 | let $ = cheerio.load(data) 34 | let hasil = [] 35 | $('div.grid-item').each(function (a, b) { 36 | hasil.push({ 37 | title: $(b).find('div.info > a > h3').text(), 38 | type: $(b).find('div.info > a:nth-child(2)').text(), 39 | source: 'https://www.besthdwallpaper.com/'+$(b).find('div > a:nth-child(3)').attr('href'), 40 | image: [$(b).find('picture > img').attr('data-src') || $(b).find('picture > img').attr('src'), $(b).find('picture > source:nth-child(1)').attr('srcset'), $(b).find('picture > source:nth-child(2)').attr('srcset')] 41 | }) 42 | }) 43 | resolve(hasil) 44 | }) 45 | }) 46 | } 47 | 48 | function wikimedia(title) { 49 | return new Promise((resolve, reject) => { 50 | axios.get(`https://commons.wikimedia.org/w/index.php?search=${title}&title=Special:MediaSearch&go=Go&type=image`) 51 | .then((res) => { 52 | let $ = cheerio.load(res.data) 53 | let hasil = [] 54 | $('.sdms-search-results__list-wrapper > div > a').each(function (a, b) { 55 | hasil.push({ 56 | title: $(b).find('img').attr('alt'), 57 | source: $(b).attr('href'), 58 | image: $(b).find('img').attr('data-src') || $(b).find('img').attr('src') 59 | }) 60 | }) 61 | resolve(hasil) 62 | }) 63 | }) 64 | } 65 | 66 | function quotesAnime() { 67 | return new Promise((resolve, reject) => { 68 | const page = Math.floor(Math.random() * 184) 69 | axios.get('https://otakotaku.com/quote/feed/'+page) 70 | .then(({ data }) => { 71 | const $ = cheerio.load(data) 72 | const hasil = [] 73 | $('div.kotodama-list').each(function(l, h) { 74 | hasil.push({ 75 | link: $(h).find('a').attr('href'), 76 | gambar: $(h).find('img').attr('data-src'), 77 | karakter: $(h).find('div.char-name').text().trim(), 78 | anime: $(h).find('div.anime-title').text().trim(), 79 | episode: $(h).find('div.meta').text(), 80 | up_at: $(h).find('small.meta').text(), 81 | quotes: $(h).find('div.quote').text().trim() 82 | }) 83 | }) 84 | resolve(hasil) 85 | }).catch(reject) 86 | }) 87 | } 88 | 89 | function aiovideodl(link) { 90 | return new Promise((resolve, reject) => { 91 | axios({ 92 | url: 'https://aiovideodl.ml/', 93 | method: 'GET', 94 | headers: { 95 | "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", 96 | "cookie": "PHPSESSID=69ce1f8034b1567b99297eee2396c308; _ga=GA1.2.1360894709.1632723147; _gid=GA1.2.1782417082.1635161653" 97 | } 98 | }).then((src) => { 99 | let a = cheerio.load(src.data) 100 | let token = a('#token').attr('value') 101 | axios({ 102 | url: 'https://aiovideodl.ml/wp-json/aio-dl/video-data/', 103 | method: 'POST', 104 | headers: { 105 | "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", 106 | "cookie": "PHPSESSID=69ce1f8034b1567b99297eee2396c308; _ga=GA1.2.1360894709.1632723147; _gid=GA1.2.1782417082.1635161653" 107 | }, 108 | data: new URLSearchParams(Object.entries({ 'url': link, 'token': token })) 109 | }).then(({ data }) => { 110 | resolve(data) 111 | }) 112 | }) 113 | }) 114 | } 115 | 116 | function umma(url) { 117 | return new Promise((resolve, reject) => { 118 | axios.get(url) 119 | .then((res) => { 120 | let $ = cheerio.load(res.data) 121 | let image = [] 122 | $('#article-content > div').find('img').each(function (a, b) { 123 | image.push($(b).attr('src')) 124 | }) 125 | let hasil = { 126 | title: $('#wrap > div.content-container.font-6-16 > h1').text().trim(), 127 | author: { 128 | name: $('#wrap > div.content-container.font-6-16 > div.content-top > div > div.user-ame.font-6-16.fw').text().trim(), 129 | profilePic: $('#wrap > div.content-container.font-6-16 > div.content-top > div > div.profile-photo > img.photo').attr('src') 130 | }, 131 | caption: $('#article-content > div > p').text().trim(), 132 | media: $('#article-content > div > iframe').attr('src') ? [$('#article-content > div > iframe').attr('src')] : image, 133 | type: $('#article-content > div > iframe').attr('src') ? 'video' : 'image', 134 | like: $('#wrap > div.bottom-btns > div > button:nth-child(1) > div.text.font-6-12').text(), 135 | } 136 | resolve(hasil) 137 | }) 138 | }) 139 | } 140 | 141 | function ringtone(title) { 142 | return new Promise((resolve, reject) => { 143 | axios.get('https://meloboom.com/en/search/'+title) 144 | .then((get) => { 145 | let $ = cheerio.load(get.data) 146 | let hasil = [] 147 | $('#__next > main > section > div.jsx-2244708474.container > div > div > div > div:nth-child(4) > div > div > div > ul > li').each(function (a, b) { 148 | hasil.push({ title: $(b).find('h4').text(), source: 'https://meloboom.com/'+$(b).find('a').attr('href'), audio: $(b).find('audio').attr('src') }) 149 | }) 150 | resolve(hasil) 151 | }) 152 | }) 153 | } 154 | 155 | function styletext(teks) { 156 | return new Promise((resolve, reject) => { 157 | axios.get('http://qaz.wtf/u/convert.cgi?text='+teks) 158 | .then(({ data }) => { 159 | let $ = cheerio.load(data) 160 | let hasil = [] 161 | $('table > tbody > tr').each(function (a, b) { 162 | hasil.push({ name: $(b).find('td:nth-child(1) > span').text(), result: $(b).find('td:nth-child(2)').text().trim() }) 163 | }) 164 | resolve(hasil) 165 | }) 166 | }) 167 | } 168 | 169 | module.exports = { pinterest, wallpaper, wikimedia, quotesAnime, aiovideodl, umma, ringtone, styletext } 170 | -------------------------------------------------------------------------------- /lib/myfunc.js: -------------------------------------------------------------------------------- 1 | // Ketauan Lu Jual Gua Labrak Lu Ngentod \\ 2 | 3 | const { proto, delay, getContentType } = require('@adiwajshing/baileys') 4 | const chalk = require('chalk') 5 | const fs = require('fs') 6 | const Crypto = require('crypto') 7 | const axios = require('axios') 8 | const moment = require('moment-timezone') 9 | const { sizeFormatter } = require('human-readable') 10 | const util = require('util') 11 | const Jimp = require('jimp') 12 | const { defaultMaxListeners } = require('stream') 13 | 14 | 15 | const unixTimestampSeconds = (date = new Date()) => Math.floor(date.getTime() / 1000) 16 | 17 | exports.unixTimestampSeconds = unixTimestampSeconds 18 | 19 | exports.generateMessageTag = (epoch) => { 20 | let tag = (0, exports.unixTimestampSeconds)().toString(); 21 | if (epoch) 22 | tag += '.--' + epoch; // attach epoch if provided 23 | return tag; 24 | } 25 | 26 | exports.processTime = (timestamp, now) => { 27 | return moment.duration(now - moment(timestamp * 1000)).asSeconds() 28 | } 29 | 30 | exports.getRandom = (ext) => { 31 | return `${Math.floor(Math.random() * 10000)}${ext}` 32 | } 33 | 34 | exports.getBuffer = async (url, options) => { 35 | try { 36 | options ? options : {} 37 | const res = await axios({ 38 | method: "get", 39 | url, 40 | headers: { 41 | 'DNT': 1, 42 | 'Upgrade-Insecure-Request': 1 43 | }, 44 | ...options, 45 | responseType: 'arraybuffer' 46 | }) 47 | return res.data 48 | } catch (err) { 49 | return err 50 | } 51 | } 52 | 53 | exports.fetchJson = async (url, options) => { 54 | try { 55 | options ? options : {} 56 | const res = await axios({ 57 | method: 'GET', 58 | url: url, 59 | headers: { 60 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36' 61 | }, 62 | ...options 63 | }) 64 | return res.data 65 | } catch (err) { 66 | return err 67 | } 68 | } 69 | 70 | exports.runtime = function(seconds) { 71 | seconds = Number(seconds); 72 | var d = Math.floor(seconds / (3600 * 24)); 73 | var h = Math.floor(seconds % (3600 * 24) / 3600); 74 | var m = Math.floor(seconds % 3600 / 60); 75 | var s = Math.floor(seconds % 60); 76 | var dDisplay = d > 0 ? d + (d == 1 ? " day, " : " days, ") : ""; 77 | var hDisplay = h > 0 ? h + (h == 1 ? " hour, " : " hours, ") : ""; 78 | var mDisplay = m > 0 ? m + (m == 1 ? " minute, " : " minutes, ") : ""; 79 | var sDisplay = s > 0 ? s + (s == 1 ? " second" : " seconds") : ""; 80 | return dDisplay + hDisplay + mDisplay + sDisplay; 81 | } 82 | 83 | exports.clockString = (ms) => { 84 | let h = isNaN(ms) ? '--' : Math.floor(ms / 3600000) 85 | let m = isNaN(ms) ? '--' : Math.floor(ms / 60000) % 60 86 | let s = isNaN(ms) ? '--' : Math.floor(ms / 1000) % 60 87 | return [h, m, s].map(v => v.toString().padStart(2, 0)).join(':') 88 | } 89 | 90 | exports.sleep = async (ms) => { 91 | return new Promise(resolve => setTimeout(resolve, ms)); 92 | } 93 | 94 | exports.isUrl = (url) => { 95 | return url.match(new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)/, 'gi')) 96 | } 97 | 98 | exports.getTime = (format, date) => { 99 | if (date) { 100 | return moment(date).locale('id').format(format) 101 | } else { 102 | return moment.tz('Asia/Jakarta').locale('id').format(format) 103 | } 104 | } 105 | 106 | exports.formatDate = (n, locale = 'id') => { 107 | let d = new Date(n) 108 | return d.toLocaleDateString(locale, { 109 | weekday: 'long', 110 | day: 'numeric', 111 | month: 'long', 112 | year: 'numeric', 113 | hour: 'numeric', 114 | minute: 'numeric', 115 | second: 'numeric' 116 | }) 117 | } 118 | 119 | exports.tanggal = (numer) => { 120 | myMonths = ["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"]; 121 | myDays = ['Minggu','Senin','Selasa','Rabu','Kamis','Jum’at','Sabtu']; 122 | var tgl = new Date(numer); 123 | var day = tgl.getDate() 124 | bulan = tgl.getMonth() 125 | var thisDay = tgl.getDay(), 126 | thisDay = myDays[thisDay]; 127 | var yy = tgl.getYear() 128 | var year = (yy < 1000) ? yy + 1900 : yy; 129 | const time = moment.tz('Asia/Jakarta').format('DD/MM HH:mm:ss') 130 | let d = new Date 131 | let locale = 'id' 132 | let gmt = new Date(0).getTime() - new Date('1 January 1970').getTime() 133 | let weton = ['Pahing', 'Pon','Wage','Kliwon','Legi'][Math.floor(((d * 1) + gmt) / 84600000) % 5] 134 | 135 | return`${thisDay}, ${day} - ${myMonths[bulan]} - ${year}` 136 | } 137 | 138 | exports.formatp = sizeFormatter({ 139 | std: 'JEDEC', //'SI' = default | 'IEC' | 'JEDEC' 140 | decimalPlaces: 2, 141 | keepTrailingZeroes: false, 142 | render: (literal, symbol) => `${literal} ${symbol}B`, 143 | }) 144 | 145 | exports.jsonformat = (string) => { 146 | return JSON.stringify(string, null, 2) 147 | } 148 | 149 | function format(...args) { 150 | return util.format(...args) 151 | } 152 | 153 | exports.logic = (check, inp, out) => { 154 | if (inp.length !== out.length) throw new Error('Input and Output must have same length') 155 | for (let i in inp) 156 | if (util.isDeepStrictEqual(check, inp[i])) return out[i] 157 | return null 158 | } 159 | 160 | exports.generateProfilePicture = async (buffer) => { 161 | const jimp = await Jimp.read(buffer) 162 | const min = jimp.getWidth() 163 | const max = jimp.getHeight() 164 | const cropped = jimp.crop(0, 0, min, max) 165 | return { 166 | img: await cropped.scaleToFit(720, 720).getBufferAsync(Jimp.MIME_JPEG), 167 | preview: await cropped.scaleToFit(720, 720).getBufferAsync(Jimp.MIME_JPEG) 168 | } 169 | } 170 | 171 | exports.bytesToSize = (bytes, decimals = 2) => { 172 | if (bytes === 0) return '0 Bytes'; 173 | 174 | const k = 1024; 175 | const dm = decimals < 0 ? 0 : decimals; 176 | const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; 177 | 178 | const i = Math.floor(Math.log(bytes) / Math.log(k)); 179 | 180 | return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; 181 | } 182 | 183 | exports.getSizeMedia = (path) => { 184 | return new Promise((resolve, reject) => { 185 | if (/http/.test(path)) { 186 | axios.get(path) 187 | .then((res) => { 188 | let length = parseInt(res.headers['content-length']) 189 | let size = exports.bytesToSize(length, 3) 190 | if(!isNaN(length)) resolve(size) 191 | }) 192 | } else if (Buffer.isBuffer(path)) { 193 | let length = Buffer.byteLength(path) 194 | let size = exports.bytesToSize(length, 3) 195 | if(!isNaN(length)) resolve(size) 196 | } else { 197 | reject('error gatau apah') 198 | } 199 | }) 200 | } 201 | 202 | exports.parseMention = (text = '') => { 203 | return [...text.matchAll(/@([0-9]{5,16}|0)/g)].map(v => v[1] + '@s.whatsapp.net') 204 | } 205 | 206 | 207 | /** 208 | * Serialize Message 209 | * @param {WAConnection} conn 210 | * @param {Object} m 211 | * @param {store} store 212 | */ 213 | exports.smsg = (conn, m, store) => { 214 | if (!m) return m 215 | let M = proto.WebMessageInfo 216 | if (m.key) { 217 | m.id = m.key.id 218 | m.isBaileys = m.id.startsWith('BAE5') && m.id.length === 16 219 | m.chat = m.key.remoteJid 220 | m.fromMe = m.key.fromMe 221 | m.isGroup = m.chat.endsWith('@g.us') 222 | m.sender = conn.decodeJid(m.fromMe && conn.user.id || m.participant || m.key.participant || m.chat || '') 223 | if (m.isGroup) m.participant = conn.decodeJid(m.key.participant) || '' 224 | } 225 | if (m.message) { 226 | m.mtype = getContentType(m.message) 227 | m.msg = (m.mtype == 'viewOnceMessage' ? m.message[m.mtype].message[getContentType(m.message[m.mtype].message)] : m.message[m.mtype]) 228 | m.body = m.message.conversation || m.msg.caption || m.msg.text || (m.mtype == 'listResponseMessage') && m.msg.singleSelectReply.selectedRowId || (m.mtype == 'buttonsResponseMessage') && m.msg.selectedButtonId || (m.mtype == 'viewOnceMessage') && m.msg.caption || m.text 229 | let quoted = m.quoted = m.msg.contextInfo ? m.msg.contextInfo.quotedMessage : null 230 | m.mentionedJid = m.msg.contextInfo ? m.msg.contextInfo.mentionedJid : [] 231 | if (m.quoted) { 232 | let type = getContentType(quoted) 233 | m.quoted = m.quoted[type] 234 | if (['productMessage'].includes(type)) { 235 | type = getContentType(m.quoted) 236 | m.quoted = m.quoted[type] 237 | } 238 | if (typeof m.quoted === 'string') m.quoted = { 239 | text: m.quoted 240 | } 241 | m.quoted.mtype = type 242 | m.quoted.id = m.msg.contextInfo.stanzaId 243 | m.quoted.chat = m.msg.contextInfo.remoteJid || m.chat 244 | m.quoted.isBaileys = m.quoted.id ? m.quoted.id.startsWith('BAE5') && m.quoted.id.length === 16 : false 245 | m.quoted.sender = conn.decodeJid(m.msg.contextInfo.participant) 246 | m.quoted.fromMe = m.quoted.sender === (conn.user && conn.user.id) 247 | m.quoted.text = m.quoted.text || m.quoted.caption || m.quoted.conversation || m.quoted.contentText || m.quoted.selectedDisplayText || m.quoted.title || '' 248 | m.quoted.mentionedJid = m.msg.contextInfo ? m.msg.contextInfo.mentionedJid : [] 249 | m.getQuotedObj = m.getQuotedMessage = async () => { 250 | if (!m.quoted.id) return false 251 | let q = await store.loadMessage(m.chat, m.quoted.id, conn) 252 | return exports.smsg(conn, q, store) 253 | } 254 | let vM = m.quoted.fakeObj = M.fromObject({ 255 | key: { 256 | remoteJid: m.quoted.chat, 257 | fromMe: m.quoted.fromMe, 258 | id: m.quoted.id 259 | }, 260 | message: quoted, 261 | ...(m.isGroup ? { participant: m.quoted.sender } : {}) 262 | }) 263 | 264 | /** 265 | * 266 | * @returns 267 | */ 268 | m.quoted.delete = () => conn.sendMessage(m.quoted.chat, { delete: vM.key }) 269 | 270 | /** 271 | * 272 | * @param {*} jid 273 | * @param {*} forceForward 274 | * @param {*} options 275 | * @returns 276 | */ 277 | m.quoted.copyNForward = (jid, forceForward = false, options = {}) => conn.copyNForward(jid, vM, forceForward, options) 278 | 279 | /** 280 | * 281 | * @returns 282 | */ 283 | m.quoted.download = () => conn.downloadMediaMessage(m.quoted) 284 | } 285 | } 286 | if (m.msg.url) m.download = () => conn.downloadMediaMessage(m.msg) 287 | m.text = m.msg.text || m.msg.caption || m.message.conversation || m.msg.contentText || m.msg.selectedDisplayText || m.msg.title || '' 288 | /** 289 | * Reply to this message 290 | * @param {String|Object} text 291 | * @param {String|false} chatId 292 | * @param {Object} options 293 | */ 294 | m.reply = (text, chatId = m.chat, options = {}) => Buffer.isBuffer(text) ? conn.sendMedia(chatId, text, 'file', '', m, { ...options }) : conn.sendText(chatId, text, m, { ...options }) 295 | /** 296 | * Copy this message 297 | */ 298 | m.copy = () => exports.smsg(conn, M.fromObject(M.toObject(m))) 299 | 300 | /** 301 | * 302 | * @param {*} jid 303 | * @param {*} forceForward 304 | * @param {*} options 305 | * @returns 306 | */ 307 | m.copyNForward = (jid = m.chat, forceForward = false, options = {}) => conn.copyNForward(jid, m, forceForward, options) 308 | 309 | return m 310 | } 311 | 312 | 313 | let file = require.resolve(__filename) 314 | fs.watchFile(file, () => { 315 | fs.unwatchFile(file) 316 | console.log(chalk.redBright(`Update ${__filename}`)) 317 | delete require.cache[file] 318 | require(file) 319 | }) 320 | -------------------------------------------------------------------------------- /src/database.json: -------------------------------------------------------------------------------- 1 | { 2 | "sticker": {}, 3 | "database": {}, 4 | "game": { 5 | "tebaklagu": [], 6 | "family100": [], 7 | "math": [], 8 | "tebakgambar": [], 9 | "tebakkata": [], 10 | "lontong": [], 11 | "lontong_desk": [], 12 | "kalimat": [], 13 | "lirik": [], 14 | "tebakan": [] 15 | }, 16 | "others": { 17 | "vote": [] 18 | }, 19 | "users": { 20 | "6281365814200@s.whatsapp.net": { 21 | "afkTime": -1, 22 | "afkReason": "", 23 | "limit": 100 24 | }, 25 | "6283127014833@s.whatsapp.net": { 26 | "afkTime": -1, 27 | "afkReason": "", 28 | "limit": 100 29 | }, 30 | "6285741857458@s.whatsapp.net": { 31 | "afkTime": -1, 32 | "afkReason": "", 33 | "limit": 100 34 | }, 35 | "6289501060783@s.whatsapp.net": { 36 | "afkTime": -1, 37 | "afkReason": "", 38 | "limit": 100 39 | }, 40 | "6285741857464@s.whatsapp.net": { 41 | "afkTime": -1, 42 | "afkReason": "", 43 | "limit": 100 44 | }, 45 | "62857815632831@s.whatsapp.net": { 46 | "afkTime": -1, 47 | "afkReason": "", 48 | "limit": 100 49 | }, 50 | "628998067856@s.whatsapp.net": { 51 | "afkTime": -1, 52 | "afkReason": "", 53 | "limit": 100 54 | }, 55 | "6282198571732@s.whatsapp.net": { 56 | "afkTime": -1, 57 | "afkReason": "", 58 | "limit": 100 59 | }, 60 | "6285693352917@s.whatsapp.net": { 61 | "afkTime": -1, 62 | "afkReason": "", 63 | "limit": 100 64 | }, 65 | "6285891528650@s.whatsapp.net": { 66 | "afkTime": -1, 67 | "afkReason": "", 68 | "limit": 100 69 | }, 70 | "6282351045388@s.whatsapp.net": { 71 | "afkTime": -1, 72 | "afkReason": "", 73 | "limit": 100 74 | }, 75 | "6285870756663@s.whatsapp.net": { 76 | "afkTime": -1, 77 | "afkReason": "", 78 | "limit": 100 79 | }, 80 | "6285377193100@s.whatsapp.net": { 81 | "afkTime": -1, 82 | "afkReason": "", 83 | "limit": 100 84 | }, 85 | "6288238953940@s.whatsapp.net": { 86 | "afkTime": -1, 87 | "afkReason": "", 88 | "limit": 100 89 | }, 90 | "6285778615851@s.whatsapp.net": { 91 | "afkTime": -1, 92 | "afkReason": "", 93 | "limit": 100 94 | }, 95 | "62895326097674@s.whatsapp.net": { 96 | "afkTime": -1, 97 | "afkReason": "", 98 | "limit": 100 99 | }, 100 | "6282288190016@s.whatsapp.net": { 101 | "afkTime": -1, 102 | "afkReason": "", 103 | "limit": 100 104 | }, 105 | "6285848300025@s.whatsapp.net": { 106 | "afkTime": -1, 107 | "afkReason": "", 108 | "limit": 100 109 | }, 110 | "6283110928302@s.whatsapp.net": { 111 | "afkTime": -1, 112 | "afkReason": "", 113 | "limit": 100 114 | }, 115 | "6285226629295@s.whatsapp.net": { 116 | "afkTime": -1, 117 | "afkReason": "", 118 | "limit": 100 119 | }, 120 | "6285831325140@s.whatsapp.net": { 121 | "afkTime": -1, 122 | "afkReason": "", 123 | "limit": 100 124 | }, 125 | "6282142961010@s.whatsapp.net": { 126 | "afkTime": -1, 127 | "afkReason": "", 128 | "limit": 100 129 | }, 130 | "6281212083401@s.whatsapp.net": { 131 | "afkTime": -1, 132 | "afkReason": "", 133 | "limit": 100 134 | }, 135 | "6289653381067@s.whatsapp.net": { 136 | "afkTime": -1, 137 | "afkReason": "", 138 | "limit": 100 139 | }, 140 | "994408621598@s.whatsapp.net": { 141 | "afkTime": -1, 142 | "afkReason": "", 143 | "limit": 100 144 | }, 145 | "212774421209@s.whatsapp.net": { 146 | "afkTime": -1, 147 | "afkReason": "", 148 | "limit": 100 149 | }, 150 | "6287772228391@s.whatsapp.net": { 151 | "afkTime": -1, 152 | "afkReason": "", 153 | "limit": 100 154 | }, 155 | "6285803050751@s.whatsapp.net": { 156 | "afkTime": -1, 157 | "afkReason": "", 158 | "limit": 100 159 | }, 160 | "6282172010674@s.whatsapp.net": { 161 | "afkTime": -1, 162 | "afkReason": "", 163 | "limit": 100 164 | }, 165 | "6285607858648@s.whatsapp.net": { 166 | "afkTime": -1, 167 | "afkReason": "", 168 | "limit": 100 169 | }, 170 | "628885960825@s.whatsapp.net": { 171 | "afkTime": -1, 172 | "afkReason": "", 173 | "limit": 100 174 | }, 175 | "62895321521245@s.whatsapp.net": { 176 | "afkTime": -1, 177 | "afkReason": "", 178 | "limit": 100 179 | }, 180 | "6283154736816@s.whatsapp.net": { 181 | "afkTime": -1, 182 | "afkReason": "", 183 | "limit": 100 184 | }, 185 | "6283829003070@s.whatsapp.net": { 186 | "afkTime": -1, 187 | "afkReason": "", 188 | "limit": 100 189 | }, 190 | "6285954993954@s.whatsapp.net": { 191 | "afkTime": -1, 192 | "afkReason": "", 193 | "limit": 100 194 | }, 195 | "6281255268810@s.whatsapp.net": { 196 | "afkTime": -1, 197 | "afkReason": "", 198 | "limit": 100 199 | }, 200 | "6282199535392@s.whatsapp.net": { 201 | "afkTime": -1, 202 | "afkReason": "", 203 | "limit": 100 204 | }, 205 | "6281269677942@s.whatsapp.net": { 206 | "afkTime": -1, 207 | "afkReason": "", 208 | "limit": 100 209 | }, 210 | "6285777451314@s.whatsapp.net": { 211 | "afkTime": -1, 212 | "afkReason": "", 213 | "limit": 100 214 | }, 215 | "62882017009764@s.whatsapp.net": { 216 | "afkTime": -1, 217 | "afkReason": "", 218 | "limit": 100 219 | }, 220 | "62895345157755@s.whatsapp.net": { 221 | "afkTime": -1, 222 | "afkReason": "", 223 | "limit": 100 224 | }, 225 | "6285640068416@s.whatsapp.net": { 226 | "afkTime": -1, 227 | "afkReason": "", 228 | "limit": 100 229 | }, 230 | "628979530736@s.whatsapp.net": { 231 | "afkTime": -1, 232 | "afkReason": "", 233 | "limit": 100 234 | }, 235 | "62882015982050@s.whatsapp.net": { 236 | "afkTime": -1, 237 | "afkReason": "", 238 | "limit": 100 239 | }, 240 | "6281545835104@s.whatsapp.net": { 241 | "afkTime": -1, 242 | "afkReason": "", 243 | "limit": 100 244 | }, 245 | "6281252489631@s.whatsapp.net": { 246 | "afkTime": -1, 247 | "afkReason": "", 248 | "limit": 100 249 | }, 250 | "51903476362@s.whatsapp.net": { 251 | "afkTime": -1, 252 | "afkReason": "", 253 | "limit": 100 254 | }, 255 | "6287708357324@s.whatsapp.net": { 256 | "afkTime": -1, 257 | "afkReason": "", 258 | "limit": 100 259 | }, 260 | "6281317790596@s.whatsapp.net": { 261 | "afkTime": -1, 262 | "afkReason": "", 263 | "limit": 100 264 | }, 265 | "6281572368626@s.whatsapp.net": { 266 | "afkTime": -1, 267 | "afkReason": "", 268 | "limit": 100 269 | }, 270 | "6283850394078@s.whatsapp.net": { 271 | "afkTime": -1, 272 | "afkReason": "", 273 | "limit": 100 274 | }, 275 | "16084013060@s.whatsapp.net": { 276 | "afkTime": -1, 277 | "afkReason": "", 278 | "limit": 100 279 | }, 280 | "6281519665177@s.whatsapp.net": { 281 | "afkTime": -1, 282 | "afkReason": "", 283 | "limit": 100 284 | }, 285 | "62895321787910@s.whatsapp.net": { 286 | "afkTime": -1, 287 | "afkReason": "", 288 | "limit": 100 289 | }, 290 | "6287704764819@s.whatsapp.net": { 291 | "afkTime": -1, 292 | "afkReason": "", 293 | "limit": 100 294 | }, 295 | "919402104403@s.whatsapp.net": { 296 | "afkTime": -1, 297 | "afkReason": "", 298 | "limit": 100 299 | }, 300 | "916909137213@s.whatsapp.net": { 301 | "afkTime": -1, 302 | "afkReason": "", 303 | "limit": 100 304 | }, 305 | "918116781147@s.whatsapp.net": { 306 | "afkTime": -1, 307 | "afkReason": "", 308 | "limit": 100 309 | }, 310 | "919048399670@s.whatsapp.net": { 311 | "afkTime": -1, 312 | "afkReason": "", 313 | "limit": 100 314 | }, 315 | "918275589600@s.whatsapp.net": { 316 | "afkTime": -1, 317 | "afkReason": "", 318 | "limit": 100 319 | }, 320 | "6283839980451@s.whatsapp.net": { 321 | "afkTime": -1, 322 | "afkReason": "", 323 | "limit": 100 324 | }, 325 | "6285822396085@s.whatsapp.net": { 326 | "afkTime": -1, 327 | "afkReason": "", 328 | "limit": 100 329 | }, 330 | "19736361768@s.whatsapp.net": { 331 | "afkTime": -1, 332 | "afkReason": "", 333 | "limit": 100 334 | }, 335 | "918240890871@s.whatsapp.net": { 336 | "afkTime": -1, 337 | "afkReason": "", 338 | "limit": 100 339 | }, 340 | "917606966383@s.whatsapp.net": { 341 | "afkTime": -1, 342 | "afkReason": "", 343 | "limit": 100 344 | }, 345 | "919967246285@s.whatsapp.net": { 346 | "afkTime": -1, 347 | "afkReason": "", 348 | "limit": 100 349 | }, 350 | "923027089670@s.whatsapp.net": { 351 | "afkTime": -1, 352 | "afkReason": "", 353 | "limit": 100 354 | }, 355 | "917085563840@s.whatsapp.net": { 356 | "afkTime": -1, 357 | "afkReason": "", 358 | "limit": 100 359 | }, 360 | "916281816271@s.whatsapp.net": { 361 | "afkTime": -1, 362 | "afkReason": "", 363 | "limit": 100 364 | }, 365 | "917439455733@s.whatsapp.net": { 366 | "afkTime": -1, 367 | "afkReason": "", 368 | "limit": 100 369 | }, 370 | "244922465993@s.whatsapp.net": { 371 | "afkTime": -1, 372 | "afkReason": "", 373 | "limit": 100 374 | }, 375 | "917604016334@s.whatsapp.net": { 376 | "afkTime": -1, 377 | "afkReason": "", 378 | "limit": 100 379 | }, 380 | "917219339553@s.whatsapp.net": { 381 | "afkTime": -1, 382 | "afkReason": "", 383 | "limit": 100 384 | }, 385 | "6281263733543@s.whatsapp.net": { 386 | "afkTime": -1, 387 | "afkReason": "", 388 | "limit": 100 389 | }, 390 | "917872232347@s.whatsapp.net": { 391 | "afkTime": -1, 392 | "afkReason": "", 393 | "limit": 100 394 | }, 395 | "917778069605@s.whatsapp.net": { 396 | "afkTime": -1, 397 | "afkReason": "", 398 | "limit": 100 399 | }, 400 | "923219207659@s.whatsapp.net": { 401 | "afkTime": -1, 402 | "afkReason": "", 403 | "limit": 100 404 | }, 405 | "17058062269@s.whatsapp.net": { 406 | "afkTime": -1, 407 | "afkReason": "", 408 | "limit": 100 409 | }, 410 | "923410609118@s.whatsapp.net": { 411 | "afkTime": -1, 412 | "afkReason": "", 413 | "limit": 100 414 | }, 415 | "261341980966@s.whatsapp.net": { 416 | "afkTime": -1, 417 | "afkReason": "", 418 | "limit": 100 419 | }, 420 | "4917646161282@s.whatsapp.net": { 421 | "afkTime": -1, 422 | "afkReason": "", 423 | "limit": 100 424 | }, 425 | "994408204050@s.whatsapp.net": { 426 | "afkTime": -1, 427 | "afkReason": "", 428 | "limit": 100 429 | }, 430 | "18722422694@s.whatsapp.net": { 431 | "afkTime": -1, 432 | "afkReason": "", 433 | "limit": 100 434 | }, 435 | "94701132306@s.whatsapp.net": { 436 | "afkTime": -1, 437 | "afkReason": "", 438 | "limit": 100 439 | }, 440 | "923017705358@s.whatsapp.net": { 441 | "afkTime": -1, 442 | "afkReason": "", 443 | "limit": 100 444 | }, 445 | "923144818148@s.whatsapp.net": { 446 | "afkTime": -1, 447 | "afkReason": "", 448 | "limit": 100 449 | }, 450 | "923053741087@s.whatsapp.net": { 451 | "afkTime": -1, 452 | "afkReason": "", 453 | "limit": 100 454 | }, 455 | "6282114746258@s.whatsapp.net": { 456 | "afkTime": -1, 457 | "afkReason": "", 458 | "limit": 100 459 | }, 460 | "6283162818323@s.whatsapp.net": { 461 | "afkTime": -1, 462 | "afkReason": "", 463 | "limit": 100 464 | }, 465 | "6281237965166@s.whatsapp.net": { 466 | "afkTime": -1, 467 | "afkReason": "", 468 | "limit": 100 469 | }, 470 | "12497018123@s.whatsapp.net": { 471 | "afkTime": -1, 472 | "afkReason": "", 473 | "limit": 100 474 | }, 475 | "3546329122@s.whatsapp.net": { 476 | "afkTime": -1, 477 | "afkReason": "", 478 | "limit": 100 479 | }, 480 | "919609900020@s.whatsapp.net": { 481 | "afkTime": -1, 482 | "afkReason": "", 483 | "limit": 100 484 | }, 485 | "6285878313791@s.whatsapp.net": { 486 | "afkTime": -1, 487 | "afkReason": "", 488 | "limit": "Infinity" 489 | }, 490 | "6281804680327@s.whatsapp.net": { 491 | "afkTime": -1, 492 | "afkReason": "", 493 | "limit": 100 494 | }, 495 | "6283811034750@s.whatsapp.net": { 496 | "afkTime": -1, 497 | "afkReason": "", 498 | "limit": 100 499 | }, 500 | "436506665652664@s.whatsapp.net": { 501 | "afkTime": -1, 502 | "afkReason": "", 503 | "limit": "Infinity" 504 | }, 505 | "6283879635336@s.whatsapp.net": { 506 | "afkTime": -1, 507 | "afkReason": "", 508 | "limit": 100 509 | }, 510 | "6287868480153@s.whatsapp.net": { 511 | "afkTime": -1, 512 | "afkReason": "", 513 | "limit": 100 514 | }, 515 | "6281523868063@s.whatsapp.net": { 516 | "afkTime": -1, 517 | "afkReason": "", 518 | "limit": 100 519 | }, 520 | "6281347250317@s.whatsapp.net": { 521 | "afkTime": -1, 522 | "afkReason": "", 523 | "limit": 100 524 | }, 525 | "62818617578@s.whatsapp.net": { 526 | "afkTime": -1, 527 | "afkReason": "", 528 | "limit": 100 529 | }, 530 | "6281288339373@s.whatsapp.net": { 531 | "afkTime": -1, 532 | "afkReason": "", 533 | "limit": 100 534 | }, 535 | "6288211665259@s.whatsapp.net": { 536 | "afkTime": -1, 537 | "afkReason": "", 538 | "limit": 100 539 | }, 540 | "6288225027186@s.whatsapp.net": { 541 | "afkTime": -1, 542 | "afkReason": "", 543 | "limit": 100 544 | } 545 | }, 546 | "chats": { 547 | "120363024073006505@g.us": { 548 | "mute": false, 549 | "wame": true 550 | }, 551 | "6283127014833@s.whatsapp.net": { 552 | "mute": false, 553 | "wame": false 554 | }, 555 | "120363039525080361@g.us": { 556 | "mute": true, 557 | "wame": false 558 | }, 559 | "6285693352917@s.whatsapp.net": { 560 | "mute": false 561 | }, 562 | "120363022735092029@g.us": { 563 | "mute": false, 564 | "wame": false 565 | }, 566 | "62895326097674-1627009257@g.us": { 567 | "mute": false 568 | }, 569 | "212774421209@s.whatsapp.net": { 570 | "mute": false 571 | }, 572 | "62882017009764@s.whatsapp.net": { 573 | "mute": false 574 | }, 575 | "6281317790596@s.whatsapp.net": { 576 | "mute": false 577 | }, 578 | "6281365814200@s.whatsapp.net": { 579 | "mute": false 580 | }, 581 | "6287704764819@s.whatsapp.net": { 582 | "mute": false, 583 | "wame": false 584 | }, 585 | "919402104403@s.whatsapp.net": { 586 | "mute": false, 587 | "wame": false 588 | }, 589 | "916909137213-1632759248@g.us": { 590 | "mute": false, 591 | "wame": false 592 | }, 593 | "120363021468707920@g.us": { 594 | "mute": false, 595 | "wame": false 596 | }, 597 | "917085563840@s.whatsapp.net": { 598 | "mute": false, 599 | "wame": false 600 | }, 601 | "917439455733@s.whatsapp.net": { 602 | "mute": false, 603 | "wame": false 604 | }, 605 | "14256895031-1632639905@g.us": { 606 | "mute": false, 607 | "wame": false 608 | }, 609 | "17058062269@s.whatsapp.net": { 610 | "mute": false, 611 | "wame": false 612 | }, 613 | "916909137213@s.whatsapp.net": { 614 | "mute": false, 615 | "wame": false 616 | }, 617 | "994408204050@s.whatsapp.net": { 618 | "mute": false, 619 | "wame": false 620 | }, 621 | "120363038720618354@g.us": { 622 | "mute": false, 623 | "wame": false 624 | }, 625 | "12497018123@s.whatsapp.net": { 626 | "mute": false, 627 | "wame": false 628 | }, 629 | "120363025081486209@g.us": { 630 | "mute": false, 631 | "wame": false 632 | }, 633 | "6281288339373@s.whatsapp.net": { 634 | "mute": false, 635 | "wame": false 636 | }, 637 | "436506665652664@s.whatsapp.net": { 638 | "mute": false, 639 | "wame": false 640 | }, 641 | "62818617578@s.whatsapp.net": { 642 | "mute": false, 643 | "wame": false 644 | } 645 | } 646 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('./config') 2 | const { default: ZakiConnect, useSingleFileAuthState, DisconnectReason, fetchLatestBaileysVersion, generateForwardMessageContent, prepareWAMessageMedia, generateWAMessageFromContent, generateMessageID, downloadContentFromMessage, makeInMemoryStore, jidDecode, proto } = require("@adiwajshing/baileys") 3 | const { state, saveState } = useSingleFileAuthState(`./${sessionName}.json`) 4 | const pino = require('pino') 5 | const fs = require('fs') 6 | const chalk = require('chalk') 7 | const FileType = require('file-type') 8 | const path = require('path') 9 | const { Boom } = require('@hapi/boom') 10 | const PhoneNumber = require('awesome-phonenumber') 11 | const { imageToWebp, videoToWebp, writeExifImg, writeExifVid } = require('./lib/exif') 12 | const { smsg, isUrl, generateMessageTag, getBuffer, getSizeMedia, fetchJson, await, sleep } = require('./lib/myfunc') 13 | 14 | global.api = (name, path = '/', query = {}, apikeyqueryname) => (name in global.APIs ? global.APIs[name] : name) + path + (query || apikeyqueryname ? '?' + new URLSearchParams(Object.entries({ ...query, ...(apikeyqueryname ? { [apikeyqueryname]: global.APIKeys[name in global.APIs ? global.APIs[name] : name] } : {}) })) : '') 15 | 16 | const store = makeInMemoryStore({ logger: pino().child({ level: 'silent', stream: 'store' }) }) 17 | 18 | async function startZaki() { 19 | let { version, isLatest } = await fetchLatestBaileysVersion() 20 | const Zaki = ZakiConnect({ 21 | logger: pino({ level: 'silent' }), 22 | printQRInTerminal: true, 23 | browser: ['YouTube FLOB','Safari','1.0.0'], 24 | auth: state, 25 | version 26 | }) 27 | 28 | store.bind(Zaki.ev) 29 | 30 | Zaki.ws.on('CB:call', async (json) => { 31 | const callerId = json.content[0].attrs['call-creator'] 32 | if (json.content[0].tag == 'offer') { 33 | let pa7rick = await Zaki.sendContact(callerId, global.owner) 34 | Zaki.sendMessage(callerId, { text: `Automatic block system!\nDon't call bot!\nPlease contact the owner to open !`}, { quoted : pa7rick }) 35 | Zaki.sendMessage(`6285878313791@s.whatsapp.net`, {text: `*Report Bot:* Someone Called Bot`}) 36 | await sleep(8000) 37 | await Zaki.updateBlockStatus(callerId, "block") 38 | } 39 | }) 40 | 41 | Zaki.ev.on('messages.upsert', async chatUpdate => { 42 | //console.log(JSON.stringify(chatUpdate, undefined, 2)) 43 | try { 44 | mek = chatUpdate.messages[0] 45 | if (!mek.message) return 46 | mek.message = (Object.keys(mek.message)[0] === 'ephemeralMessage') ? mek.message.ephemeralMessage.message : mek.message 47 | if (mek.key && mek.key.remoteJid === 'status@broadcast') return 48 | if (!Zaki.public && !mek.key.fromMe && chatUpdate.type === 'notify') return 49 | if (mek.key.id.startsWith('BAE5') && mek.key.id.length === 16) return 50 | m = smsg(Zaki, mek, store) 51 | require("./zaki")(Zaki, m, chatUpdate, store) 52 | } catch (err) { 53 | console.log(err) 54 | } 55 | }) 56 | 57 | Zaki.ev.on('group-participants.update', async (anu) => { 58 | console.log(anu) 59 | try { 60 | let metadata = await Zaki.groupMetadata(anu.id) 61 | let participants = anu.participants 62 | for (let num of participants) { 63 | //═══════[get profile pic]════════\\ 64 | try { 65 | ppuser = await Zaki.profilePictureUrl(num, 'image') 66 | } catch { 67 | ppuser = 'https://i0.wp.com/www.gambarunik.id/wp-content/uploads/2019/06/Top-Gambar-Foto-Profil-Kosong-Lucu-Tergokil-.jpg' 68 | } 69 | 70 | //═══════[get group dp]════════\\ 71 | try { 72 | ppgroup = await Zaki.profilePictureUrl(anu.id, 'image') 73 | } catch { 74 | ppgroup = 'https://i0.wp.com/www.gambarunik.id/wp-content/uploads/2019/06/Top-Gambar-Foto-Profil-Kosong-Lucu-Tergokil-.jpg' 75 | } 76 | 77 | let nama = await Zaki.getName(num) 78 | memb = metadata.participants.length 79 | 80 | Kon = await getBuffer(`https://hardianto.xyz/api/welcome3?profile=${encodeURIComponent(ppuser)}&name=${encodeURIComponent(nama)}&bg=https://telegra.ph/file/3983c55ac7f3ebea225d3.jpg&namegb=${encodeURIComponent(metadata.subject)}&member=${encodeURIComponent(memb)}`) 81 | 82 | Tol = await getBuffer(`https://hardianto.xyz/api/goodbye3?profile=${encodeURIComponent(ppuser)}&name=${encodeURIComponent(nama)}&bg=https://telegra.ph/file/3983c55ac7f3ebea225d3.jpg&namegb=${encodeURIComponent(metadata.subject)}&member=${encodeURIComponent(memb)}`) 83 | if (anu.action == 'add') { 84 | Zaki.sendMessage(anu.id, { image: Kon, contextInfo: { mentionedJid: [num] }, caption: `Welcome To ${metadata.subject} @${num.split("@")[0]} 85 | 86 | Description: ${metadata.desc} 87 | 88 | Welcome 👋`} ) 89 | } else if (anu.action == 'remove') { 90 | Zaki.sendMessage(anu.id, { image: Tol, contextInfo: { mentionedJid: [num] }, caption: `@${num.split("@")[0]} Left ${metadata.subject} 91 | 92 | Good Bye 👋` }) 93 | } 94 | } 95 | } catch (err) { 96 | console.log(err) 97 | } 98 | }) 99 | Zaki.decodeJid = (jid) => { 100 | if (!jid) return jid 101 | if (/:\d+@/gi.test(jid)) { 102 | let decode = jidDecode(jid) || {} 103 | return decode.user && decode.server && decode.user + '@' + decode.server || jid 104 | } else return jid 105 | } 106 | 107 | Zaki.ev.on('contacts.update', update => { 108 | for (let contact of update) { 109 | let id = Zaki.decodeJid(contact.id) 110 | if (store && store.contacts) store.contacts[id] = { id, name: contact.notify } 111 | } 112 | }) 113 | 114 | Zaki.getName = (jid, withoutContact = false) => { 115 | id = Zaki.decodeJid(jid) 116 | withoutContact = Zaki.withoutContact || withoutContact 117 | let v 118 | if (id.endsWith("@g.us")) return new Promise(async (resolve) => { 119 | v = store.contacts[id] || {} 120 | if (!(v.name || v.subject)) v = Zaki.groupMetadata(id) || {} 121 | resolve(v.name || v.subject || PhoneNumber('+' + id.replace('@s.whatsapp.net', '')).getNumber('international')) 122 | }) 123 | else v = id === '0@s.whatsapp.net' ? { 124 | id, 125 | name: 'WhatsApp' 126 | } : id === Zaki.decodeJid(Zaki.user.id) ? 127 | Zaki.user : 128 | (store.contacts[id] || {}) 129 | return (withoutContact ? '' : v.name) || v.subject || v.verifiedName || PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international') 130 | } 131 | 132 | Zaki.sendContact = async (jid, kon, quoted = '', opts = {}) => { 133 | let list = [] 134 | for (let i of kon) { 135 | list.push({ 136 | displayName: await Zaki.getName(i + '@s.whatsapp.net'), 137 | vcard: `BEGIN:VCARD\nVERSION:3.0\nN:${await Zaki.getName(i + '@s.whatsapp.net')}\nFN:${await Zaki.getName(i + '@s.whatsapp.net')}\nitem1.TEL;waid=${i}:${i}\nitem1.X-ABLabel:Click To Chat\nitem2.EMAIL;type=INTERNET:helloiamkizakixd@gmail.com\nitem2.X-ABLabel:Stay A Burden\nitem3.URL:YouTube: Flob\nitem3.X-ABLabel:Youtube\nitem4.ADR:;;Indonesia, Mizoram;;;;\nitem4.X-ABLabel:Region\nEND:VCARD` 138 | }) 139 | } 140 | Zaki.sendMessage(jid, { contacts: { displayName: `${list.length} Contact`, contacts: list }, ...opts }, { quoted }) 141 | } 142 | 143 | Zaki.setStatus = (status) => { 144 | Zaki.query({ 145 | tag: 'iq', 146 | attrs: { 147 | to: '@s.whatsapp.net', 148 | type: 'set', 149 | xmlns: 'status', 150 | }, 151 | content: [{ 152 | tag: 'status', 153 | attrs: {}, 154 | content: Buffer.from(status, 'utf-8') 155 | }] 156 | }) 157 | return status 158 | } 159 | 160 | Zaki.public = true 161 | 162 | Zaki.serializeM = (m) => smsg(Zaki, m, store) 163 | 164 | Zaki.ev.on('connection.update', async (update) => { 165 | const { connection, lastDisconnect } = update 166 | if (connection === 'close') { 167 | let reason = new Boom(lastDisconnect?.error)?.output?.statusCode 168 | if (reason === DisconnectReason.badSession) { console.log(`Bad Session File, Please Delete Session and Scan Again`); process.exit(); } 169 | else if (reason === DisconnectReason.connectionClosed) { console.log("Connection closed, Reconnecting...."); startZaki(); } 170 | else if (reason === DisconnectReason.connectionLost) { console.log("Connection Lost from Server, Reconnecting..."); startZaki(); } 171 | else if (reason === DisconnectReason.connectionReplaced) { console.log("Connection Replaced, Another New Session Opened, Please Close Current Session First"); process.exit(); } 172 | else if (reason === DisconnectReason.loggedOut) { console.log(`Device Logged Out, Please Delete Session And Scan Again.`); process.exit(); } 173 | else if (reason === DisconnectReason.restartRequired) { console.log("Restart Required, Restarting..."); startZaki(); } 174 | else if (reason === DisconnectReason.timedOut) { console.log("Connection TimedOut, Reconnecting..."); startZaki(); } 175 | else { console.log(`Unknown DisconnectReason: ${reason}|${connection}`) } 176 | } 177 | console.log('Connected...', update) 178 | }) 179 | 180 | Zaki.ev.on('creds.update', saveState) 181 | 182 | // Add Other 183 | /** Send Button 5 Image 184 | * 185 | * @param {*} jid 186 | * @param {*} text 187 | * @param {*} footer 188 | * @param {*} image 189 | * @param [*] button 190 | * @param {*} options 191 | * @returns 192 | */ 193 | Zaki.send5ButImg = async (jid , text = '' , footer = '', img, but = [], options = {}) =>{ 194 | let message = await prepareWAMessageMedia({ image: img }, { upload: Zaki.waUploadToServer }) 195 | var template = generateWAMessageFromContent(m.chat, proto.Message.fromObject({ 196 | templateMessage: { 197 | hydratedTemplate: { 198 | imageMessage: message.imageMessage, 199 | "hydratedContentText": text, 200 | "hydratedFooterText": footer, 201 | "hydratedButtons": but 202 | } 203 | } 204 | }), options) 205 | Zaki.relayMessage(jid, template.message, { messageId: template.key.id }) 206 | } 207 | 208 | /** 209 | * 210 | * @param {*} jid 211 | * @param {*} buttons 212 | * @param {*} caption 213 | * @param {*} footer 214 | * @param {*} quoted 215 | * @param {*} options 216 | */ 217 | Zaki.sendButtonText = (jid, buttons = [], text, footer, quoted = '', options = {}) => { 218 | let buttonMessage = { 219 | text, 220 | footer, 221 | buttons, 222 | headerType: 2, 223 | ...options 224 | } 225 | Zaki.sendMessage(jid, buttonMessage, { quoted, ...options }) 226 | } 227 | 228 | /** 229 | * 230 | * @param {*} jid 231 | * @param {*} text 232 | * @param {*} quoted 233 | * @param {*} options 234 | * @returns 235 | */ 236 | Zaki.sendText = (jid, text, quoted = '', options) => Zaki.sendMessage(jid, { text: text, ...options }, { quoted }) 237 | 238 | /** 239 | * 240 | * @param {*} jid 241 | * @param {*} path 242 | * @param {*} caption 243 | * @param {*} quoted 244 | * @param {*} options 245 | * @returns 246 | */ 247 | Zaki.sendImage = async (jid, path, caption = '', quoted = '', options) => { 248 | let buffer = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0) 249 | return await Zaki.sendMessage(jid, { image: buffer, caption: caption, ...options }, { quoted }) 250 | } 251 | 252 | /** 253 | * 254 | * @param {*} jid 255 | * @param {*} path 256 | * @param {*} caption 257 | * @param {*} quoted 258 | * @param {*} options 259 | * @returns 260 | */ 261 | Zaki.sendVideo = async (jid, path, caption = '', quoted = '', gif = false, options) => { 262 | let buffer = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0) 263 | return await Zaki.sendMessage(jid, { video: buffer, caption: caption, gifPlayback: gif, ...options }, { quoted }) 264 | } 265 | 266 | /** 267 | * 268 | * @param {*} jid 269 | * @param {*} path 270 | * @param {*} quoted 271 | * @param {*} mime 272 | * @param {*} options 273 | * @returns 274 | */ 275 | Zaki.sendAudio = async (jid, path, quoted = '', ptt = false, options) => { 276 | let buffer = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0) 277 | return await Zaki.sendMessage(jid, { audio: buffer, ptt: ptt, ...options }, { quoted }) 278 | } 279 | 280 | /** 281 | * 282 | * @param {*} jid 283 | * @param {*} text 284 | * @param {*} quoted 285 | * @param {*} options 286 | * @returns 287 | */ 288 | Zaki.sendTextWithMentions = async (jid, text, quoted, options = {}) => Zaki.sendMessage(jid, { text: text, contextInfo: { mentionedJid: [...text.matchAll(/@(\d{0,16})/g)].map(v => v[1] + '@s.whatsapp.net') }, ...options }, { quoted }) 289 | 290 | /** 291 | * 292 | * @param {*} jid 293 | * @param {*} path 294 | * @param {*} quoted 295 | * @param {*} options 296 | * @returns 297 | */ 298 | Zaki.sendImageAsSticker = async (jid, path, quoted, options = {}) => { 299 | let buff = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0) 300 | let buffer 301 | if (options && (options.packname || options.author)) { 302 | buffer = await writeExifImg(buff, options) 303 | } else { 304 | buffer = await imageToWebp(buff) 305 | } 306 | 307 | await Zaki.sendMessage(jid, { sticker: { url: buffer }, ...options }, { quoted }) 308 | return buffer 309 | } 310 | 311 | /** 312 | * 313 | * @param {*} jid 314 | * @param {*} path 315 | * @param {*} quoted 316 | * @param {*} options 317 | * @returns 318 | */ 319 | Zaki.sendVideoAsSticker = async (jid, path, quoted, options = {}) => { 320 | let buff = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0) 321 | let buffer 322 | if (options && (options.packname || options.author)) { 323 | buffer = await writeExifVid(buff, options) 324 | } else { 325 | buffer = await videoToWebp(buff) 326 | } 327 | 328 | await Zaki.sendMessage(jid, { sticker: { url: buffer }, ...options }, { quoted }) 329 | return buffer 330 | } 331 | 332 | /** 333 | * 334 | * @param {*} message 335 | * @param {*} filename 336 | * @param {*} attachExtension 337 | * @returns 338 | */ 339 | Zaki.downloadAndSaveMediaMessage = async (message, filename, attachExtension = true) => { 340 | let quoted = message.msg ? message.msg : message 341 | let mime = (message.msg || message).mimetype || '' 342 | let messageType = message.mtype ? message.mtype.replace(/Message/gi, '') : mime.split('/')[0] 343 | const stream = await downloadContentFromMessage(quoted, messageType) 344 | let buffer = Buffer.from([]) 345 | for await(const chunk of stream) { 346 | buffer = Buffer.concat([buffer, chunk]) 347 | } 348 | let type = await FileType.fromBuffer(buffer) 349 | trueFileName = attachExtension ? (filename + '.' + type.ext) : filename 350 | // save to file 351 | await fs.writeFileSync(trueFileName, buffer) 352 | return trueFileName 353 | } 354 | 355 | Zaki.downloadMediaMessage = async (message) => { 356 | let mime = (message.msg || message).mimetype || '' 357 | let messageType = message.mtype ? message.mtype.replace(/Message/gi, '') : mime.split('/')[0] 358 | const stream = await downloadContentFromMessage(message, messageType) 359 | let buffer = Buffer.from([]) 360 | for await(const chunk of stream) { 361 | buffer = Buffer.concat([buffer, chunk]) 362 | } 363 | 364 | return buffer 365 | } 366 | 367 | /** 368 | * 369 | * @param {*} jid 370 | * @param {*} path 371 | * @param {*} filename 372 | * @param {*} caption 373 | * @param {*} quoted 374 | * @param {*} options 375 | * @returns 376 | */ 377 | Zaki.sendMedia = async (jid, path, fileName = '', caption = '', quoted = '', options = {}) => { 378 | let types = await Zaki.getFile(path, true) 379 | let { mime, ext, res, data, filename } = types 380 | if (res && res.status !== 200 || file.length <= 65536) { 381 | try { throw { json: JSON.parse(file.toString()) } } 382 | catch (e) { if (e.json) throw e.json } 383 | } 384 | let type = '', mimetype = mime, pathFile = filename 385 | if (options.asDocument) type = 'document' 386 | if (options.asSticker || /webp/.test(mime)) { 387 | let { writeExif } = require('./lib/exif') 388 | let media = { mimetype: mime, data } 389 | pathFile = await writeExif(media, { packname: options.packname ? options.packname : global.packname, author: options.author ? options.author : global.author, categories: options.categories ? options.categories : [] }) 390 | await fs.promises.unlink(filename) 391 | type = 'sticker' 392 | mimetype = 'image/webp' 393 | } 394 | else if (/image/.test(mime)) type = 'image' 395 | else if (/video/.test(mime)) type = 'video' 396 | else if (/audio/.test(mime)) type = 'audio' 397 | else type = 'document' 398 | await Zaki.sendMessage(jid, { [type]: { url: pathFile }, caption, mimetype, fileName, ...options }, { quoted, ...options }) 399 | return fs.promises.unlink(pathFile) 400 | } 401 | 402 | /** 403 | * 404 | * @param {*} jid 405 | * @param {*} message 406 | * @param {*} forceForward 407 | * @param {*} options 408 | * @returns 409 | */ 410 | Zaki.copyNForward = async (jid, message, forceForward = false, options = {}) => { 411 | let vtype 412 | if (options.readViewOnce) { 413 | message.message = message.message && message.message.ephemeralMessage && message.message.ephemeralMessage.message ? message.message.ephemeralMessage.message : (message.message || undefined) 414 | vtype = Object.keys(message.message.viewOnceMessage.message)[0] 415 | delete(message.message && message.message.ignore ? message.message.ignore : (message.message || undefined)) 416 | delete message.message.viewOnceMessage.message[vtype].viewOnce 417 | message.message = { 418 | ...message.message.viewOnceMessage.message 419 | } 420 | } 421 | 422 | let mtype = Object.keys(message.message)[0] 423 | let content = await generateForwardMessageContent(message, forceForward) 424 | let ctype = Object.keys(content)[0] 425 | let context = {} 426 | if (mtype != "conversation") context = message.message[mtype].contextInfo 427 | content[ctype].contextInfo = { 428 | ...context, 429 | ...content[ctype].contextInfo 430 | } 431 | const waMessage = await generateWAMessageFromContent(jid, content, options ? { 432 | ...content[ctype], 433 | ...options, 434 | ...(options.contextInfo ? { 435 | contextInfo: { 436 | ...content[ctype].contextInfo, 437 | ...options.contextInfo 438 | } 439 | } : {}) 440 | } : {}) 441 | await Zaki.relayMessage(jid, waMessage.message, { messageId: waMessage.key.id }) 442 | return waMessage 443 | } 444 | 445 | Zaki.cMod = (jid, copy, text = '', sender = Zaki.user.id, options = {}) => { 446 | //let copy = message.toJSON() 447 | let mtype = Object.keys(copy.message)[0] 448 | let isEphemeral = mtype === 'ephemeralMessage' 449 | if (isEphemeral) { 450 | mtype = Object.keys(copy.message.ephemeralMessage.message)[0] 451 | } 452 | let msg = isEphemeral ? copy.message.ephemeralMessage.message : copy.message 453 | let content = msg[mtype] 454 | if (typeof content === 'string') msg[mtype] = text || content 455 | else if (content.caption) content.caption = text || content.caption 456 | else if (content.text) content.text = text || content.text 457 | if (typeof content !== 'string') msg[mtype] = { 458 | ...content, 459 | ...options 460 | } 461 | if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant 462 | else if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant 463 | if (copy.key.remoteJid.includes('@s.whatsapp.net')) sender = sender || copy.key.remoteJid 464 | else if (copy.key.remoteJid.includes('@broadcast')) sender = sender || copy.key.remoteJid 465 | copy.key.remoteJid = jid 466 | copy.key.fromMe = sender === Zaki.user.id 467 | 468 | return proto.WebMessageInfo.fromObject(copy) 469 | } 470 | 471 | 472 | /** 473 | * 474 | * @param {*} path 475 | * @returns 476 | */ 477 | Zaki.getFile = async (PATH, save) => { 478 | let res 479 | let data = Buffer.isBuffer(PATH) ? PATH : /^data:.*?\/.*?;base64,/i.test(PATH) ? Buffer.from(PATH.split`,`[1], 'base64') : /^https?:\/\//.test(PATH) ? await (res = await getBuffer(PATH)) : fs.existsSync(PATH) ? (filename = PATH, fs.readFileSync(PATH)) : typeof PATH === 'string' ? PATH : Buffer.alloc(0) 480 | //if (!Buffer.isBuffer(data)) throw new TypeError('Result is not a buffer') 481 | let type = await FileType.fromBuffer(data) || { 482 | mime: 'application/octet-stream', 483 | ext: '.bin' 484 | } 485 | filename = path.join(__filename, '../src/' + new Date * 1 + '.' + type.ext) 486 | if (data && save) fs.promises.writeFile(filename, data) 487 | return { 488 | res, 489 | filename, 490 | size: await getSizeMedia(data), 491 | ...type, 492 | data 493 | } 494 | 495 | } 496 | 497 | return Zaki 498 | } 499 | 500 | startZaki() 501 | 502 | 503 | let file = require.resolve(__filename) 504 | fs.watchFile(file, () => { 505 | fs.unwatchFile(file) 506 | console.log(chalk.redBright(`Update ${__filename}`)) 507 | delete require.cache[file] 508 | require(file) 509 | }) 510 | --------------------------------------------------------------------------------