├── .env ├── .github ├── FUNDING.yml └── workflows │ └── docker-image.yml ├── Dockerfile ├── Procfile ├── README.md ├── SECURITY.md ├── app.json ├── config.js ├── docker-compose.yml ├── handler.js ├── heroku.yml ├── index.js ├── lib ├── canvas.js ├── cloudDBAdapter.js ├── converter.js ├── database.js ├── gdrive.js ├── levelling.js ├── logs.js ├── lowdb │ ├── Low.d.ts │ ├── Low.js │ ├── LowSync.d.ts │ ├── LowSync.js │ ├── MissingAdapterError.d.ts │ ├── MissingAdapterError.js │ ├── adapters │ │ ├── JSONFile.d.ts │ │ ├── JSONFile.js │ │ ├── JSONFileSync.d.ts │ │ ├── JSONFileSync.js │ │ ├── LocalStorage.d.ts │ │ ├── LocalStorage.js │ │ ├── Memory.d.ts │ │ ├── Memory.js │ │ ├── MemorySync.d.ts │ │ ├── MemorySync.js │ │ ├── TextFile.d.ts │ │ ├── TextFile.js │ │ ├── TextFileSync.d.ts │ │ └── TextFileSync.js │ ├── index.d.ts │ └── index.js ├── mongoDB.js ├── print.js ├── simple.js ├── sticker.js ├── store.js ├── tictactoe.d.ts ├── tictactoe.js ├── uploadFile.js ├── uploadImage.js ├── wallq.js ├── webp.js ├── webp2mp4.js ├── welcome.js └── y2mate.js ├── main.js ├── package.json ├── plugins ├── _afk.js ├── _anonymous_chat.js.js ├── _antilink.js ├── _antispam.js ├── _autolevelup.js ├── _cmdWithMedia.js ├── _durability.js ├── _expired.js ├── _health.js ├── _premium.js ├── _simi.js ├── _templateResponse.js ├── afk-afk.js ├── anime-lolice.js ├── anime-waifu.js ├── anonymous_chat.js ├── anonymous_chat_.js.js ├── audio-tomp3.js ├── audio-toptt.js ├── bank-cek.js ├── bank-nabung.js ├── bank-tarik.js ├── broadcast.js ├── broadcastchats.js ├── broadcastgroups.js ├── creator.js ├── database-cmd-delete.js ├── database-cmd-list.js ├── database-cmd-set.js ├── donasi.js ├── downloader-facebook.js ├── downloader-gitclone.js ├── downloader-ig.js ├── downloader-igstalk.js ├── downloader-mediafire.js ├── downloader-tiktok.js ├── downloader-twitter.js ├── enable.js ├── exp-ceksn.js ├── exp-daftar.js ├── exp-profile.js ├── exp-tomoney.js ├── exp-unreg.js ├── fun-apakah.js ├── fun-apakah2.js ├── fun-generate_nama.js ├── fun-generate_purba.js ├── fun-how.js ├── fun-jadian.js ├── fun-kapankah.js ├── fun-kapankah2.js ├── fun-kerangajaib.js ├── fun-paling.js ├── fun-siapa.js ├── fun-twibbonizze.js ├── game-caklontong.js ├── game-caklontong_ans.js ├── game-caklontong_hint.js ├── game-family100.js ├── game-family100_answer.js ├── game-math.js ├── game-math_answer.js ├── game-siapakahaku.js ├── game-siapakahaku_ans.js ├── game-siapakahaku_hint.js ├── game-tebakgambar.js ├── game-tebakgambar_answer.js ├── game-tebakgambar_hint.js ├── games-_tictactoe.js ├── games-tebakkata.js ├── games-tebakkata_ans.js ├── games-tebakkata_hint.js ├── games-tictactoe.js ├── gitclone.js ├── google.js ├── group-admin.js ├── group-info ├── group-info.js ├── group-leavegc.js ├── group-link.js ├── group-pengumuman.js ├── group-settings.js ├── group-tagall.js ├── group-tagme.js ├── image-gimage.js ├── image-pinterest.js ├── image-wallpaper.js ├── info-grouplist.js ├── internet-fetch.js ├── internet-kbbi.js ├── internet-lewd.js ├── jadwalsholat.js ├── join.js ├── levelup.js ├── lyrics.js ├── menu.js ├── nulis-hartatahta..js ├── nulis-nulis.js ├── nulis-nulis2.js ├── nulis-textpro.js ├── nulis.js ├── nulis2.js ├── owner-add.js ├── owner-addprem.js ├── owner-banchat.js ├── owner-delprem.js ├── owner-exec.js ├── owner-exec2.js ├── owner-getdb.js ├── owner-getsesi.js ├── owner-listprem.js ├── owner-order.js ├── owner-setbio.js ├── owner-setppbot.js ├── owner-unbanchat.js ├── photo-canvas.js ├── premium.js ├── quotes-bucin.js ├── quotes-dare.js ├── quotes-truth.js ├── rpg-adventure.js ├── rpg-bet.js ├── rpg-craft.js ├── rpg-daily.js ├── rpg-dungeon.js ├── rpg-feed.js ├── rpg-heal.js ├── rpg-inventory.js ├── rpg-leaderboard.js ├── rpg-mining.js ├── rpg-monthly.js ├── rpg-open.js ├── rpg-petstore.js ├── rpg-repair.js ├── rpg-shop.js ├── rpg-transfer.js ├── rpg-weekly.js ├── siegrin.js ├── speed.js ├── sticker-attp.js ├── sticker-colong.js ├── sticker-getexif.js ├── sticker-meme.js ├── sticker-sticker.js ├── sticker-stickerLLT.js ├── sticker-toimg.js ├── sticker-toimg2.js ├── sticker-tovideo.js ├── sticker-ttp.js ├── sticker-wm.js ├── tool-calc.js ├── tool-delete.js ├── tool-getPlugins.js ├── tool-hlh.js ├── tool-qrcode.js ├── tool-react.js ├── tool-readmore.js ├── tool-readviewonce.js ├── tool-savefile.js ├── tool-sendquote.js ├── tool-styletext.js ├── tool-tourl.js ├── tool-tts.js ├── totalfeature.js ├── wikipedia.js ├── youtube-play.js ├── youtube-yta.js ├── youtube-yts.js └── youtube-ytv.js ├── server.js ├── session.data.json ├── speed.py ├── src ├── Aesthetic │ ├── Aesthetic_000.jpeg │ ├── Aesthetic_001.jpg │ └── Aesthetic_002.jpg ├── LICENSE ├── avatar_contact.png ├── bab2.pdf ├── font │ ├── 212BabyGirl.otf │ ├── 212LeahleeSans.ttf │ ├── 99HandWritting.ttf │ ├── ACallingFontDby7NTypes.otf │ ├── ACasualHandwrittenPenNoncommercial.ttf │ ├── ADayinSeptember.otf │ ├── ASMelanieHandwritting.ttf │ ├── Alittlesunshine.ttf │ ├── And-This-Happened.ttf │ ├── AvenirCondensedHand.ttf │ ├── Avocados.ttf │ ├── BabyDoll.ttf │ ├── BattleOfKingsRegular.ttf │ ├── BrayNotes.ttf │ ├── Convered-By-Your-Grace.ttf │ ├── Edoms-Handwritting-Normal.ttf │ ├── Futura Bold Italic font.ttf │ ├── Futura Bold font.ttf │ ├── Futura Book Italic font.ttf │ ├── Futura Book font.ttf │ ├── Futura Extra Black font.ttf │ ├── Futura Heavy Italic font.ttf │ ├── Futura Heavy font.ttf │ ├── Futura Light Italic font.ttf │ ├── Futura Light font.ttf │ ├── Futura Medium Italic font.ttf │ ├── Futura XBlk BT.ttf │ ├── Futura-CondensedLight.otf │ ├── GloriaHallelujah-Regular.ttf │ ├── HandwritingCR-2.ttf │ ├── Kempton-Demo-Handwritting.ttf │ ├── MyHandsareHoldingYou.ttf │ ├── My_handwriting.ttf │ ├── Nadeznas-Handwritting.ttf │ ├── Roboto-Black.ttf │ ├── Roboto-BlackItalic.ttf │ ├── Roboto-Bold.ttf │ ├── Roboto-BoldItalic.ttf │ ├── Roboto-Italic.ttf │ ├── Roboto-Light.ttf │ ├── Roboto-LightItalic.ttf │ ├── Roboto-Medium.ttf │ ├── Roboto-MediumItalic.ttf │ ├── Roboto-Regular.ttf │ ├── Roboto-Thin.ttf │ ├── Roboto-ThinItalic.ttf │ ├── ShadowsIntoLight-Regular.ttf │ ├── Zahraaa.ttf │ ├── angelina.ttf │ ├── futur.ttf │ ├── futura light bt.ttf │ ├── futura medium bt.ttf │ ├── futura medium condensed bt.ttf │ ├── level_c.otf │ ├── michellehandwritting.ttf │ └── texts.otf ├── kertas │ └── magernulis1.jpg ├── level_c.otf ├── lvlup_template.jpg ├── s_pgsd_penjas_0701098_chapter3.pdf ├── squidGame_GLRL.mp3 ├── squidGame_GLRL_Scan.mp3 ├── squidGame_GLRL_Shoot.mp3 ├── temp │ └── File ├── texts.otf └── welcome.svg ├── temp └── .file ├── test.js ├── thumbnail.jpg └── views ├── img ├── dark │ ├── balloon_centered_normal.9.png │ ├── balloon_centered_pressed.9.png │ ├── balloon_centered_shadow.9.png │ ├── balloon_incoming_frame.9.png │ ├── balloon_incoming_normal.9.png │ ├── balloon_incoming_normal_ext.9.png │ ├── balloon_incoming_normal_stkr.9.png │ ├── balloon_incoming_pressed.9.png │ ├── balloon_incoming_pressed_ext.9.png │ ├── balloon_live_location_incoming_frame.9.png │ ├── balloon_live_location_outgoing_frame.9.png │ ├── balloon_outgoing_frame.9.png │ ├── balloon_outgoing_normal.9.png │ ├── balloon_outgoing_normal_ext.9.png │ ├── balloon_outgoing_normal_stkr.9.png │ ├── balloon_outgoing_pressed.9.png │ └── balloon_outgoing_pressed_ext.9.png └── light │ ├── balloon_centered_normal.9.png │ ├── balloon_centered_pressed.9.png │ ├── balloon_centered_shadow.9.png │ ├── balloon_incoming_frame.9.png │ ├── balloon_incoming_normal.9.png │ ├── balloon_incoming_normal_ext.9.png │ ├── balloon_incoming_normal_stkr.9.png │ ├── balloon_incoming_pressed.9.png │ ├── balloon_incoming_pressed_ext.9.png │ ├── balloon_live_location_incoming_frame.9.png │ ├── balloon_live_location_outgoing_frame.9.png │ ├── balloon_outgoing_frame.9.png │ ├── balloon_outgoing_normal.9.png │ ├── balloon_outgoing_normal_ext.9.png │ ├── balloon_outgoing_normal_stkr.9.png │ ├── balloon_outgoing_pressed.9.png │ └── balloon_outgoing_pressed_ext.9.png ├── index.html ├── index.js └── style.css /.env: -------------------------------------------------------------------------------- 1 | LINK_GITHUB= 2 | LINK_GROUP= 3 | LINK_IG= 4 | NOWNER= 5 | NAMAOWNER= 6 | MODERATOR= 7 | PACKNAME= 8 | AUTHOR= 9 | THUMB_MENU= 10 | DONASI= 11 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['https://github.com/siegrin/CloudBot/new/main?repository_funding=1'] 14 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Build the Docker image 18 | run: docker build . --file Dockerfile --tag my-image-name:$(date +%s) 19 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-buster 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y \ 5 | ffmpeg \ 6 | imagemagick \ 7 | webp && \ 8 | apt-get upgrade -y && \ 9 | rm -rf /var/lib/apt/lists/* 10 | 11 | COPY package.json . 12 | 13 | RUN npm install && npm install qrcode-terminal && npm install pm2 -g 14 | 15 | COPY . . 16 | 17 | EXPOSE 5000 18 | 19 | CMD ["node", "index.js"] 20 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node . --server 2 | db: node . --db "mongodb+srv://Della:lylia9090@cloudclus1.dlgwh.mongodb.net/cloudclus1?retryWrites=true&w=majority" --autocleartmp --restrict 3 | worker: npx pm2 start npm --node-args="--optimize_for_size --max_old_space_size=460" -- run db && npx pm2 logs 4 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CloudBot", 3 | "description": "Customizable WhatsApp Bot", 4 | "repository": "https://github.com/lordlightness/Cloud-Bot-Whatsapp-Multi-Device", 5 | "logo": "https://node-js-sample.herokuapp.com/node.png", 6 | "keywords": ["bot", "whatsapp", "whatsapp-bot", "rpg", "games-wabot", "epic rpg"], 7 | "stack": "container", 8 | "env": { 9 | "NOWNER": { 10 | "description": "Nomer Owner", 11 | "required": true, 12 | "value": "6281224863098" 13 | }, 14 | "NAMAOWNER": { 15 | "description": "Nama Owner", 16 | "required": true, 17 | "value": "Dellas" 18 | }, 19 | "LINK_GITHUB": { 20 | "description": "Link Github", 21 | "required": true, 22 | "value": "https://github.com/itsmedell" 23 | }, 24 | "LINK_IG": { 25 | "description": "Link Profile Instagram", 26 | "required": true, 27 | "value": "https://www.instagram.com/lord_lightness" 28 | }, 29 | "LINK_GROUP": { 30 | "description": "Link tautan grup whatsapp", 31 | "required": true, 32 | "value": "https://chat.whatsapp.com/Bx5aAxINL4hBLt6MxaK5xB" 33 | }, 34 | "PACKNAME": { 35 | "description": "Packname sticker", 36 | "required": true, 37 | "value": "Created by" 38 | }, 39 | "AUTHOR": { 40 | "description": "Author Bot (WM)", 41 | "required": true, 42 | "value": "CloudBot" 43 | }, 44 | "MODERATOR": { 45 | "description": "Moderator Bot", 46 | "required": false, 47 | "value": "" 48 | }, 49 | "THUMB_MENU": { 50 | "description": "Nomer Owner", 51 | "required": true, 52 | "value": "https://telegra.ph/file/baea4ead668adebdc5073.jpg" 53 | }, 54 | "DONASI": { 55 | "description": "Nomer Owner", 56 | "required": true, 57 | "value": "https://saweria.co/itsmedell" 58 | } 59 | }, 60 | "buildpacks": [ 61 | {"url": "heroku/nodejs"}, 62 | {"url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git"}, 63 | {"url": "https://github.com/DuckyTeam/heroku-buildpack-imagemagick.git"}, 64 | {"url": "https://github.com/clhuang/heroku-buildpack-webp-binaries.git"}, 65 | {"url": "https://github.com/ItsJimi/heroku-buildpack-pm2.git"} 66 | ] 67 | } 68 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" # optional since v1.27.0 2 | services: 3 | web: 4 | build: . 5 | ports: 6 | - "8000:5000" 7 | volumes: 8 | - .:/code 9 | - logvolume01:/var/log 10 | links: 11 | - redis 12 | redis: 13 | image: redis 14 | volumes: 15 | logvolume01: {} 16 | -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | worker: Dockerfile 4 | run: 5 | worker: npx pm2 start npm --node-args="--optimize_for_size --max_old_space_size=460" -- run db && npx pm2 logs 6 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | console.log('Starting...') 2 | 3 | import { join, dirname } from 'path' 4 | import { createRequire } from "module"; 5 | import { fileURLToPath } from 'url' 6 | import { setupMaster, fork } from 'cluster' 7 | import { watchFile, unwatchFile } from 'fs' 8 | import cfonts from 'cfonts'; 9 | import { createInterface } from 'readline' 10 | import yargs from 'yargs' 11 | 12 | // https://stackoverflow.com/a/50052194 13 | const __dirname = dirname(fileURLToPath(import.meta.url)) 14 | const require = createRequire(__dirname) // Bring in the ability to create the 'require' method 15 | const { name, author } = require(join(__dirname, './package.json')) // https://www.stefanjudis.com/snippets/how-to-import-json-files-in-es-modules-node-js/ 16 | const { say } = cfonts 17 | const rl = createInterface(process.stdin, process.stdout) 18 | 19 | say('Lightweight\nWhatsApp Bot', { 20 | font: 'chrome', 21 | align: 'center', 22 | gradient: ['red', 'magenta'] 23 | }) 24 | say(`'${name}' By @${author.name || author}`, { 25 | font: 'console', 26 | align: 'center', 27 | gradient: ['red', 'magenta'] 28 | }) 29 | 30 | var isRunning = false 31 | /** 32 | * Start a js file 33 | * @param {String} file `path/to/file` 34 | */ 35 | function start(file) { 36 | if (isRunning) return 37 | isRunning = true 38 | let args = [join(__dirname, file), ...process.argv.slice(2)] 39 | say([process.argv[0], ...args].join(' '), { 40 | font: 'console', 41 | align: 'center', 42 | gradient: ['red', 'magenta'] 43 | }) 44 | setupMaster({ 45 | exec: args[0], 46 | args: args.slice(1), 47 | }) 48 | let p = fork() 49 | p.on('message', data => { 50 | console.log('[RECEIVED]', data) 51 | switch (data) { 52 | case 'reset': 53 | p.process.kill() 54 | isRunning = false 55 | start.apply(this, arguments) 56 | break 57 | case 'uptime': 58 | p.send(process.uptime()) 59 | break 60 | } 61 | }) 62 | p.on('exit', (_, code) => { 63 | isRunning = false 64 | console.error('Exited with code:', code) 65 | if (code === 0) return 66 | watchFile(args[0], () => { 67 | unwatchFile(args[0]) 68 | start(file) 69 | }) 70 | }) 71 | let opts = new Object(yargs(process.argv.slice(2)).exitProcess(false).parse()) 72 | if (!opts['test']) 73 | if (!rl.listenerCount()) rl.on('line', line => { 74 | p.emit('message', line.trim()) 75 | }) 76 | // console.log(p) 77 | } 78 | 79 | start('main.js') 80 | -------------------------------------------------------------------------------- /lib/canvas.js: -------------------------------------------------------------------------------- 1 | import { spawn } from 'child_process' 2 | import { join } from 'path' 3 | 4 | const __dirname = global.__dirname(import.meta.url) 5 | /** 6 | * Levelup image 7 | * @param {String} teks 8 | * @param {Number} level 9 | * @returns {Promise} 10 | */ 11 | export function levelup(teks, level) { 12 | return new Promise(async (resolve, reject) => { 13 | if (!(global.support.convert || global.support.magick || global.support.gm)) return reject('Not Support!') 14 | const font = join(__dirname, '../src/font') 15 | let fontLevel = join(font, './level_c.otf') 16 | let fontTexts = join(font, './texts.otf') 17 | let xtsx = join(__dirname, '../src/lvlup_template.jpg') 18 | let anotations = '+1385+260' // gapake else if kadang error 19 | if (level > 2) anotations = '+1370+260' 20 | if (level > 10) anotations = '+1330+260' 21 | if (level > 50) anotations = '+1310+260' 22 | if (level > 100) anotations = '+1260+260' 23 | 24 | const [_spawnprocess, ..._spawnargs] = [...(global.support.gm ? ['gm'] : global.support.magick ? ['magick'] : []), 25 | 'convert', 26 | xtsx, 27 | '-font', 28 | fontTexts, 29 | '-fill', 30 | '#0F3E6A', 31 | '-size', 32 | '1024x784', 33 | '-pointsize', 34 | '68', 35 | '-interline-spacing', 36 | '-7.5', 37 | '-annotate', 38 | '+153+200', 39 | teks, 40 | //original together 41 | '-font', 42 | fontLevel, 43 | '-fill', 44 | '#0A2A48', 45 | '-size', 46 | '1024x784', 47 | '-pointsize', 48 | '140', 49 | '-interline-spacing', 50 | '-1.2', 51 | '-annotate', 52 | anotations, 53 | level, 54 | '-append', 55 | 'jpg:-' 56 | ] 57 | let bufs = [] 58 | spawn(_spawnprocess, _spawnargs) 59 | .on('error', reject) 60 | .on('close', () => { 61 | return resolve(Buffer.concat(bufs)) 62 | }) 63 | .stdout.on('data', chunk => bufs.push(chunk)) 64 | }) 65 | } -------------------------------------------------------------------------------- /lib/cloudDBAdapter.js: -------------------------------------------------------------------------------- 1 | import got from 'got' 2 | 3 | const stringify = obj => JSON.stringify(obj, null, 2) 4 | const parse = str => JSON.parse(str, (_, v) => { 5 | if ( 6 | v !== null && 7 | typeof v === 'object' && 8 | 'type' in v && 9 | v.type === 'Buffer' && 10 | 'data' in v && 11 | Array.isArray(v.data)) { 12 | return Buffer.from(v.data) 13 | } 14 | return v 15 | }) 16 | class CloudDBAdapter { 17 | constructor(url, { 18 | serialize = stringify, 19 | deserialize = parse, 20 | fetchOptions = {} 21 | } = {}) { 22 | this.url = url 23 | this.serialize = serialize 24 | this.deserialize = deserialize 25 | this.fetchOptions = fetchOptions 26 | } 27 | 28 | async read() { 29 | try { 30 | let res = await got(this.url, { 31 | method: 'GET', 32 | headers: { 33 | 'Accept': 'application/json;q=0.9,text/plain' 34 | }, 35 | ...this.fetchOptions 36 | }) 37 | if (res.statusCode !== 200) throw res.statusMessage 38 | return this.deserialize(res.body) 39 | } catch (e) { 40 | return null 41 | } 42 | } 43 | 44 | async write(obj) { 45 | let res = await got(this.url, { 46 | method: 'POST', 47 | headers: { 48 | 'Content-Type': 'application/json' 49 | }, 50 | ...this.fetchOptions, 51 | body: this.serialize(obj) 52 | }) 53 | if (res.statusCode !== 200) throw res.statusMessage 54 | return res.body 55 | } 56 | } 57 | 58 | export default CloudDBAdapter 59 | -------------------------------------------------------------------------------- /lib/converter.js: -------------------------------------------------------------------------------- 1 | import { promises } from 'fs' 2 | import { join } from 'path' 3 | import { spawn } from 'child_process' 4 | 5 | function ffmpeg(buffer, args = [], ext = '', ext2 = '') { 6 | return new Promise(async (resolve, reject) => { 7 | try { 8 | let tmp = join(global.__dirname(import.meta.url), '../tmp', + new Date + '.' + ext) 9 | let out = tmp + '.' + ext2 10 | await 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 promises.unlink(tmp) 21 | if (code !== 0) return reject(code) 22 | resolve({ 23 | data: await promises.readFile(out), 24 | filename: out, 25 | delete() { 26 | return promises.unlink(out) 27 | } 28 | }) 29 | } catch (e) { 30 | reject(e) 31 | } 32 | }) 33 | } catch (e) { 34 | reject(e) 35 | } 36 | }) 37 | } 38 | 39 | /** 40 | * Convert Audio to Playable WhatsApp Audio 41 | * @param {Buffer} buffer Audio Buffer 42 | * @param {String} ext File Extension 43 | * @returns {Promise<{data: Buffer, filename: String, delete: Function}>} 44 | */ 45 | function toPTT(buffer, ext) { 46 | return ffmpeg(buffer, [ 47 | '-vn', 48 | '-c:a', 'libopus', 49 | '-b:a', '128k', 50 | '-vbr', 'on', 51 | ], ext, 'ogg') 52 | } 53 | 54 | /** 55 | * Convert Audio to Playable WhatsApp PTT 56 | * @param {Buffer} buffer Audio Buffer 57 | * @param {String} ext File Extension 58 | * @returns {Promise<{data: Buffer, filename: String, delete: Function}>} 59 | */ 60 | function toAudio(buffer, ext) { 61 | return ffmpeg(buffer, [ 62 | '-vn', 63 | '-c:a', 'libopus', 64 | '-b:a', '128k', 65 | '-vbr', 'on', 66 | '-compression_level', '10' 67 | ], ext, 'opus') 68 | } 69 | 70 | /** 71 | * Convert Audio to Playable WhatsApp Video 72 | * @param {Buffer} buffer Video Buffer 73 | * @param {String} ext File Extension 74 | * @returns {Promise<{data: Buffer, filename: String, delete: Function}>} 75 | */ 76 | function toVideo(buffer, ext) { 77 | return ffmpeg(buffer, [ 78 | '-c:v', 'libx264', 79 | '-c:a', 'aac', 80 | '-ab', '128k', 81 | '-ar', '44100', 82 | '-crf', '32', 83 | '-preset', 'slow' 84 | ], ext, 'mp4') 85 | } 86 | 87 | export { 88 | toAudio, 89 | toPTT, 90 | toVideo, 91 | ffmpeg, 92 | } -------------------------------------------------------------------------------- /lib/database.js: -------------------------------------------------------------------------------- 1 | import { resolve, dirname as _dirname } from 'path' 2 | import _fs, { existsSync, readFileSync } from 'fs' 3 | const { promises: fs } = _fs 4 | 5 | class Database { 6 | /** 7 | * Create new Database 8 | * @param {String} filepath Path to specified json database 9 | * @param {...any} args JSON.stringify arguments 10 | */ 11 | constructor(filepath, ...args) { 12 | this.file = resolve(filepath) 13 | this.logger = console 14 | 15 | this._load() 16 | 17 | this._jsonargs = args 18 | this._state = false 19 | this._queue = [] 20 | this._interval = setInterval(async () => { 21 | if (!this._state && this._queue && this._queue[0]) { 22 | this._state = true 23 | await this[this._queue.shift()]().catch(this.logger.error) 24 | this._state = false 25 | } 26 | }, 1000) 27 | 28 | } 29 | 30 | get data() { 31 | return this._data 32 | } 33 | 34 | set data(value) { 35 | this._data = value 36 | this.save() 37 | } 38 | 39 | /** 40 | * Queue Load 41 | */ 42 | load() { 43 | this._queue.push('_load') 44 | } 45 | 46 | /** 47 | * Queue Save 48 | */ 49 | save() { 50 | this._queue.push('_save') 51 | } 52 | 53 | _load() { 54 | try { 55 | return this._data = existsSync(this.file) ? JSON.parse(readFileSync(this.file)) : {} 56 | } catch (e) { 57 | this.logger.error(e) 58 | return this._data = {} 59 | } 60 | } 61 | 62 | async _save() { 63 | let dirname = _dirname(this.file) 64 | if (!existsSync(dirname)) await fs.mkdir(dirname, { recursive: true }) 65 | await fs.writeFile(this.file, JSON.stringify(this._data, ...this._jsonargs)) 66 | return this.file 67 | } 68 | } 69 | 70 | export default Database 71 | 72 | -------------------------------------------------------------------------------- /lib/gdrive.js: -------------------------------------------------------------------------------- 1 | import { join } from 'path' 2 | import { promises as fs } from 'fs' 3 | import { promisify } from 'util' 4 | import { google } from 'googleapis' 5 | 6 | 7 | // If modifying these scopes, delete token.json. 8 | const SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'] 9 | // The file token.json stores the user's access and refresh tokens, and is 10 | // created automatically when the authorization flow completes for the first 11 | // time. 12 | const TOKEN_PATH = join(__dirname, '..', 'token.json') 13 | 14 | class GoogleAuth extends EventEmitter { 15 | constructor() { 16 | super() 17 | } 18 | 19 | async authorize(credentials) { 20 | let token 21 | const { client_secret, client_id } = credentials 22 | const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, `http://localhost:${port}`) 23 | try { 24 | token = JSON.parse(await fs.readFile(TOKEN_PATH)) 25 | } catch (e) { 26 | const authUrl = oAuth2Client.generateAuthUrl({ 27 | access_type: 'offline', 28 | scope: SCOPES 29 | }) 30 | this.emit('auth', authUrl) 31 | let code = await promisify(this.once).bind(this)('token') 32 | token = await oAuth2Client.getToken(code) 33 | await fs.writeFile(TOKEN_PATH, JSON.stringify(token)) 34 | } finally { 35 | await oAuth2Client.setCredentials(token) 36 | } 37 | } 38 | 39 | token(code) { 40 | this.emit('token', code) 41 | } 42 | } 43 | 44 | class GoogleDrive extends GoogleAuth { 45 | constructor() { 46 | super() 47 | this.path = '/drive/api' 48 | } 49 | 50 | async getFolderID(path) { 51 | 52 | } 53 | 54 | async infoFile(path) { 55 | 56 | } 57 | 58 | async folderList(path) { 59 | 60 | } 61 | 62 | async downloadFile(path) { 63 | 64 | } 65 | 66 | async uploadFile(path) { 67 | 68 | } 69 | } 70 | 71 | export { 72 | GoogleAuth, 73 | GoogleDrive, 74 | } 75 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /lib/logs.js: -------------------------------------------------------------------------------- 1 | let stdouts = [] 2 | export default (maxLength = 200) => { 3 | let oldWrite = process.stdout.write.bind(process.stdout) 4 | module.exports.disable = () => { 5 | module.exports.isModified = false 6 | return process.stdout.write = oldWrite 7 | } 8 | process.stdout.write = (chunk, encoding, callback) => { 9 | stdouts.push(Buffer.from(chunk, encoding)) 10 | oldWrite(chunk, encoding, callback) 11 | if (stdouts.length > maxLength) stdouts.shift() 12 | } 13 | module.exports.isModified = true 14 | return module.exports 15 | } 16 | 17 | export const isModified = false 18 | export function logs() { return Buffer.concat(stdouts)} 19 | 20 | -------------------------------------------------------------------------------- /lib/lowdb/Low.d.ts: -------------------------------------------------------------------------------- 1 | export interface Adapter { 2 | read: () => Promise; 3 | write: (data: T) => Promise; 4 | } 5 | export declare class Low { 6 | adapter: Adapter; 7 | data: T | null; 8 | constructor(adapter: Adapter); 9 | read(): Promise; 10 | write(): Promise; 11 | } 12 | -------------------------------------------------------------------------------- /lib/lowdb/Low.js: -------------------------------------------------------------------------------- 1 | const { MissingAdapterError } = require('./MissingAdapterError.js'); 2 | class Low { 3 | constructor(adapter) { 4 | this.data = null; 5 | if (adapter) { 6 | this.adapter = adapter; 7 | } 8 | else { 9 | throw new MissingAdapterError(); 10 | } 11 | } 12 | async read() { 13 | this.data = await this.adapter.read(); 14 | } 15 | async write() { 16 | if (this.data) { 17 | await this.adapter.write(this.data); 18 | } 19 | } 20 | } 21 | module.exports = { Low }; 22 | -------------------------------------------------------------------------------- /lib/lowdb/LowSync.d.ts: -------------------------------------------------------------------------------- 1 | export interface SyncAdapter { 2 | read: () => T | null; 3 | write: (data: T) => void; 4 | } 5 | export declare class LowSync { 6 | adapter: SyncAdapter; 7 | data: T | null; 8 | constructor(adapter: SyncAdapter); 9 | read(): void; 10 | write(): void; 11 | } 12 | -------------------------------------------------------------------------------- /lib/lowdb/LowSync.js: -------------------------------------------------------------------------------- 1 | const { MissingAdapterError } = require('./MissingAdapterError.js'); 2 | class LowSync { 3 | constructor(adapter) { 4 | this.data = null; 5 | if (adapter) { 6 | this.adapter = adapter; 7 | } 8 | else { 9 | throw new MissingAdapterError(); 10 | } 11 | } 12 | read() { 13 | this.data = this.adapter.read(); 14 | } 15 | write() { 16 | if (this.data !== null) { 17 | this.adapter.write(this.data); 18 | } 19 | } 20 | } 21 | module.exports = { LowSync }; 22 | -------------------------------------------------------------------------------- /lib/lowdb/MissingAdapterError.d.ts: -------------------------------------------------------------------------------- 1 | export declare class MissingAdapterError extends Error { 2 | constructor(); 3 | } 4 | -------------------------------------------------------------------------------- /lib/lowdb/MissingAdapterError.js: -------------------------------------------------------------------------------- 1 | class MissingAdapterError extends Error { 2 | constructor() { 3 | super(); 4 | this.message = 'Missing Adapter'; 5 | } 6 | } 7 | module.exports = { MissingAdapterError }; 8 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/JSONFile.d.ts: -------------------------------------------------------------------------------- 1 | import { Adapter } from '../Low.js'; 2 | export declare class JSONFile implements Adapter { 3 | private adapter; 4 | constructor(filename: string); 5 | read(): Promise; 6 | write(obj: T): Promise; 7 | } 8 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/JSONFile.js: -------------------------------------------------------------------------------- 1 | const { TextFile } = require('./TextFile.js'); 2 | class JSONFile { 3 | constructor(filename) { 4 | this.adapter = new TextFile(filename); 5 | } 6 | async read() { 7 | const data = await this.adapter.read(); 8 | if (data === null) { 9 | return null; 10 | } 11 | else { 12 | return JSON.parse(data); 13 | } 14 | } 15 | write(obj) { 16 | return this.adapter.write(JSON.stringify(obj, null, 2)); 17 | } 18 | } 19 | module.exports = { JSONFile }; 20 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/JSONFileSync.d.ts: -------------------------------------------------------------------------------- 1 | import { SyncAdapter } from '../LowSync.js'; 2 | export declare class JSONFileSync implements SyncAdapter { 3 | private adapter; 4 | constructor(filename: string); 5 | read(): T | null; 6 | write(obj: T): void; 7 | } 8 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/JSONFileSync.js: -------------------------------------------------------------------------------- 1 | const { TextFileSync } = require('./TextFileSync.js'); 2 | class JSONFileSync { 3 | constructor(filename) { 4 | this.adapter = new TextFileSync(filename); 5 | } 6 | read() { 7 | const data = this.adapter.read(); 8 | if (data === null) { 9 | return null; 10 | } 11 | else { 12 | return JSON.parse(data); 13 | } 14 | } 15 | write(obj) { 16 | this.adapter.write(JSON.stringify(obj, null, 2)); 17 | } 18 | } 19 | module.exports = { JSONFileSync }; 20 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/LocalStorage.d.ts: -------------------------------------------------------------------------------- 1 | import { SyncAdapter } from '../LowSync.js'; 2 | export declare class LocalStorage implements SyncAdapter { 3 | private key; 4 | constructor(key: string); 5 | read(): T | null; 6 | write(obj: T): void; 7 | } 8 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/LocalStorage.js: -------------------------------------------------------------------------------- 1 | class LocalStorage { 2 | constructor(key) { 3 | this.key = key; 4 | } 5 | read() { 6 | const value = localStorage.getItem(this.key); 7 | if (value === null) { 8 | return null; 9 | } 10 | return JSON.parse(value); 11 | } 12 | write(obj) { 13 | localStorage.setItem(this.key, JSON.stringify(obj)); 14 | } 15 | } 16 | module.exports = { LocalStorage }; 17 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/Memory.d.ts: -------------------------------------------------------------------------------- 1 | import { Adapter } from '../Low.js'; 2 | export declare class Memory implements Adapter { 3 | private data; 4 | read(): Promise; 5 | write(obj: T): Promise; 6 | } 7 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/Memory.js: -------------------------------------------------------------------------------- 1 | class Memory { 2 | constructor() { 3 | this.data = null; 4 | } 5 | read() { 6 | return Promise.resolve(this.data); 7 | } 8 | write(obj) { 9 | this.data = obj; 10 | return Promise.resolve(); 11 | } 12 | } 13 | module.exports = { Memory }; 14 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/MemorySync.d.ts: -------------------------------------------------------------------------------- 1 | import { SyncAdapter } from '../LowSync.js'; 2 | export declare class MemorySync implements SyncAdapter { 3 | private data; 4 | read(): T | null; 5 | write(obj: T): void; 6 | } 7 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/MemorySync.js: -------------------------------------------------------------------------------- 1 | class MemorySync { 2 | constructor() { 3 | this.data = null; 4 | } 5 | read() { 6 | return this.data || null; 7 | } 8 | write(obj) { 9 | this.data = obj; 10 | } 11 | } 12 | module.exports = { MemorySync }; 13 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/TextFile.d.ts: -------------------------------------------------------------------------------- 1 | import { Adapter } from '../Low.js'; 2 | export declare class TextFile implements Adapter { 3 | private filename; 4 | private writer; 5 | constructor(filename: string); 6 | read(): Promise; 7 | write(str: string): Promise; 8 | } 9 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/TextFile.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const { Writer } = require('steno'); 3 | class TextFile { 4 | constructor(filename) { 5 | this.filename = filename; 6 | this.writer = new Writer(filename); 7 | } 8 | async read() { 9 | let data; 10 | try { 11 | data = await fs.promises.readFile(this.filename, 'utf-8'); 12 | } 13 | catch (e) { 14 | if (e.code === 'ENOENT') { 15 | return null; 16 | } 17 | throw e; 18 | } 19 | return data; 20 | } 21 | write(str) { 22 | return this.writer.write(str); 23 | } 24 | } 25 | module.exports = { TextFile }; -------------------------------------------------------------------------------- /lib/lowdb/adapters/TextFileSync.d.ts: -------------------------------------------------------------------------------- 1 | import { SyncAdapter } from '../LowSync.js'; 2 | export declare class TextFileSync implements SyncAdapter { 3 | private tempFilename; 4 | private filename; 5 | constructor(filename: string); 6 | read(): string | null; 7 | write(str: string): void; 8 | } 9 | -------------------------------------------------------------------------------- /lib/lowdb/adapters/TextFileSync.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | class TextFileSync { 4 | constructor(filename) { 5 | this.filename = filename; 6 | this.tempFilename = path.join(path.dirname(filename), `.${path.basename(filename)}.tmp`); 7 | } 8 | read() { 9 | let data; 10 | try { 11 | data = fs.readFileSync(this.filename, 'utf-8'); 12 | } 13 | catch (e) { 14 | if (e.code === 'ENOENT') { 15 | return null; 16 | } 17 | throw e; 18 | } 19 | return data; 20 | } 21 | write(str) { 22 | fs.writeFileSync(this.tempFilename, str); 23 | fs.renameSync(this.tempFilename, this.filename); 24 | } 25 | } 26 | module.exports = { TextFileSync }; 27 | -------------------------------------------------------------------------------- /lib/lowdb/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './adapters/JSONFile.js'; 2 | export * from './adapters/JSONFileSync.js'; 3 | export * from './adapters/LocalStorage.js'; 4 | export * from './adapters/Memory.js'; 5 | export * from './adapters/MemorySync.js'; 6 | export * from './adapters/TextFile.js'; 7 | export * from './adapters/TextFileSync.js'; 8 | export * from './Low.js'; 9 | export * from './LowSync.js'; 10 | -------------------------------------------------------------------------------- /lib/lowdb/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('./adapters/JSONFile.js'), 3 | ...require('./adapters/JSONFileSync.js'), 4 | ...require('./adapters/LocalStorage.js'), 5 | ...require('./adapters/Memory.js'), 6 | ...require('./adapters/MemorySync.js'), 7 | ...require('./adapters/TextFile.js'), 8 | ...require('./adapters/TextFileSync.js'), 9 | ...require('./Low.js'), 10 | ...require('./LowSync.js'), 11 | } -------------------------------------------------------------------------------- /lib/tictactoe.d.ts: -------------------------------------------------------------------------------- 1 | export declare class TicTacToe { 2 | /* X PlayerName */ 3 | playerX: string; 4 | /* Y PlayerName */ 5 | playerY: string; 6 | /* X if true, Y if false */ 7 | _currentTurn: boolean; 8 | _x: number; 9 | _y: number; 10 | _turns: number; 11 | constructor(playerX: string, playerY: string); 12 | get board(): number; 13 | turn(player, index: number): boolean; 14 | turn(player, x: number, y: number): boolean; 15 | } 16 | -------------------------------------------------------------------------------- /lib/uploadFile.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | import { FormData, Blob } from 'formdata-node' 3 | import { fileTypeFromBuffer } from 'file-type' 4 | /** 5 | * Upload epheremal file to file.io 6 | * `Expired in 1 day` 7 | * `100MB Max Filesize` 8 | * @param {Buffer} buffer File Buffer 9 | */ 10 | const fileIO = async buffer => { 11 | const { ext, mime } = await fileTypeFromBuffer(buffer) || {} 12 | let form = new FormData() 13 | const blob = new Blob([buffer.toArrayBuffer()], { type: mime }) 14 | form.append('file', blob, 'tmp.' + ext) 15 | let res = await fetch('https://file.io/?expires=1d', { // 1 Day Expiry Date 16 | method: 'POST', 17 | body: form 18 | }) 19 | let json = await res.json() 20 | if (!json.success) throw json 21 | return json.link 22 | } 23 | 24 | /** 25 | * Upload file to storage.restfulapi.my.id 26 | * @param {Buffer|ReadableStream|(Buffer|ReadableStream)[]} inp File Buffer/Stream or Array of them 27 | * @returns {string|null|(string|null)[]} 28 | */ 29 | const RESTfulAPI = async inp => { 30 | let form = new FormData() 31 | let buffers = inp 32 | if (!Array.isArray(inp)) buffers = [inp] 33 | for (let buffer of buffers) { 34 | const blob = new Blob([buffer.toArrayBuffer()]) 35 | form.append('file', blob) 36 | } 37 | let res = await fetch('https://storage.restfulapi.my.id/upload', { 38 | method: 'POST', 39 | body: form 40 | }) 41 | let json = await res.text() 42 | try { 43 | json = JSON.parse(json) 44 | if (!Array.isArray(inp)) return json.files[0].url 45 | return json.files.map(res => res.url) 46 | } catch (e) { 47 | throw json 48 | } 49 | } 50 | 51 | /** 52 | * 53 | * @param {Buffer} inp 54 | * @returns {Promise} 55 | */ 56 | export default async function (inp) { 57 | let err = false 58 | for (let upload of [RESTfulAPI, fileIO]) { 59 | try { 60 | return await upload(inp) 61 | } catch (e) { 62 | err = e 63 | } 64 | } 65 | if (err) throw err 66 | } -------------------------------------------------------------------------------- /lib/uploadImage.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | import { FormData, Blob } from 'formdata-node'; 3 | import { fileTypeFromBuffer } from 'file-type' 4 | 5 | /** 6 | * Upload image to telegra.ph 7 | * Supported mimetype: 8 | * - `image/jpeg` 9 | * - `image/jpg` 10 | * - `image/png`s 11 | * @param {Buffer} buffer Image Buffer 12 | * @return {Promise} 13 | */ 14 | export default async buffer => { 15 | const { ext, mime } = await fileTypeFromBuffer(buffer) 16 | let form = new FormData() 17 | const blob = new Blob([buffer.toArrayBuffer()], { type: mime }) 18 | form.append('file', blob, 'tmp.' + ext) 19 | let res = await fetch('https://telegra.ph/upload', { 20 | method: 'POST', 21 | body: form 22 | }) 23 | let img = await res.json() 24 | if (img.error) throw img.error 25 | return 'https://telegra.ph' + img[0].src 26 | } 27 | 28 | -------------------------------------------------------------------------------- /lib/wallq.js: -------------------------------------------------------------------------------- 1 | // cewe yang ada di iklan royco bikin ange njing 2 | // pdhl cuma iklan :v 3 | 4 | const fetch = require('node-fetch') 5 | 6 | let handler = async (m, { conn, text }) => { 7 | if (!text) throw 'Nyari apa?' 8 | let res = await fetch(global.API('https://wall.alphacoders.com/api2.0','/get.php', { 9 | auth: '3e7756c85df54b78f934a284c11abe4e', 10 | method: 'search', 11 | term: text 12 | })) 13 | if (!res.ok) throw await res.text() 14 | let json = await res.json() 15 | let img = json.wallpapers[Math.floor(Math.random() * json.wallpapers.length)] 16 | await conn.sendFile(m.chat, img.url_image, 'wallpaper', 'Nih wallpaper!', m) 17 | } 18 | handler.help = ['wallpaperq '] 19 | handler.tags = ['internet'] 20 | handler.command = /^wall(paper)?q?$/i 21 | handler.limit = true 22 | 23 | module.exports = handler 24 | -------------------------------------------------------------------------------- /lib/webp2mp4.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | import { FormData, Blob } from 'formdata-node'; 3 | import { JSDOM } from 'jsdom'; 4 | /** 5 | * 6 | * @param {Buffer|String} source 7 | */ 8 | async function webp2mp4(source) { 9 | let form = new FormData() 10 | let isUrl = typeof source === 'string' && /https?:\/\//.test(source) 11 | const blob = !isUrl && new Blob([source.toArrayBuffer()]) 12 | form.append('new-image-url', isUrl ? blob : '') 13 | form.append('new-image', isUrl ? '' : blob, 'image.webp') 14 | let res = await fetch('https://s6.ezgif.com/webp-to-mp4', { 15 | method: 'POST', 16 | body: form 17 | }) 18 | let html = await res.text() 19 | let { document } = new JSDOM(html).window 20 | let form2 = new FormData() 21 | let obj = {} 22 | for (let input of document.querySelectorAll('form input[name]')) { 23 | obj[input.name] = input.value 24 | form2.append(input.name, input.value) 25 | } 26 | let res2 = await fetch('https://ezgif.com/webp-to-mp4/' + obj.file, { 27 | method: 'POST', 28 | body: form2 29 | }) 30 | let html2 = await res2.text() 31 | let { document: document2 } = new JSDOM(html2).window 32 | return new URL(document2.querySelector('div#output > p.outfile > video > source').src, res2.url).toString() 33 | } 34 | 35 | async function webp2png(source) { 36 | let form = new FormData() 37 | let isUrl = typeof source === 'string' && /https?:\/\//.test(source) 38 | const blob = !isUrl && new Blob([source.toArrayBuffer()]) 39 | form.append('new-image-url', isUrl ? blob : '') 40 | form.append('new-image', isUrl ? '' : blob, 'image.webp') 41 | let res = await fetch('https://s6.ezgif.com/webp-to-png', { 42 | method: 'POST', 43 | body: form 44 | }) 45 | let html = await res.text() 46 | let { document } = new JSDOM(html).window 47 | let form2 = new FormData() 48 | let obj = {} 49 | for (let input of document.querySelectorAll('form input[name]')) { 50 | obj[input.name] = input.value 51 | form2.append(input.name, input.value) 52 | } 53 | let res2 = await fetch('https://ezgif.com/webp-to-png/' + obj.file, { 54 | method: 'POST', 55 | body: form2 56 | }) 57 | let html2 = await res2.text() 58 | let { document: document2 } = new JSDOM(html2).window 59 | return new URL(document2.querySelector('div#output > p.outfile > img').src, res2.url).toString() 60 | } 61 | 62 | export { 63 | webp2mp4, 64 | webp2png 65 | } -------------------------------------------------------------------------------- /plugins/_afk.js: -------------------------------------------------------------------------------- 1 | export function before(m) { 2 | let user = global.db.data.users[m.sender] 3 | if (user.afk > -1) { 4 | m.reply(` 5 | Kamu berhenti AFK${user.afkReason ? ' setelah ' + user.afkReason : ''} 6 | Selama ${(new Date - user.afk).toTimeString()} 7 | `.trim()) 8 | user.afk = -1 9 | user.afkReason = '' 10 | } 11 | let jids = [...new Set([...(m.mentionedJid || []), ...(m.quoted ? [m.quoted.sender] : [])])] 12 | for (let jid of jids) { 13 | let user = global.db.data.users[jid] 14 | if (!user) 15 | continue 16 | let afkTime = user.afk 17 | if (!afkTime || afkTime < 0) 18 | continue 19 | let reason = user.afkReason || '' 20 | m.reply(` 21 | Jangan tag dia! 22 | Dia sedang AFK ${reason ? 'dengan alasan ' + reason : 'tanpa alasan'} 23 | Selama ${(new Date - afkTime).toTimeString()} 24 | `.trim()) 25 | } 26 | return true 27 | } 28 | -------------------------------------------------------------------------------- /plugins/_anonymous_chat.js.js: -------------------------------------------------------------------------------- 1 | export default async function before(m, { match }) { 2 | // if (match) return !1 3 | if (!m.chat.endsWith('@s.whatsapp.net')) 4 | return !0 5 | this.anonymous = this.anonymous ? this.anonymous : {} 6 | let room = Object.values(this.anonymous).find(room => [room.a, room.b].includes(m.sender) && room.state === 'CHATTING') 7 | if (room) { 8 | if (/^.*(next|leave|start)/.test(m.text)) 9 | return 10 | let other = [room.a, room.b].find(user => user !== m.sender) 11 | m.copyNForward(other, true, m.quoted && m.quoted.fromMe ? { 12 | contextInfo: { 13 | ...m.msg.contextInfo, 14 | forwardingScore: 1, 15 | isForwarded: true, 16 | participant: other 17 | } 18 | } : {}) 19 | } 20 | return !0 21 | } -------------------------------------------------------------------------------- /plugins/_antilink.js: -------------------------------------------------------------------------------- 1 | const linkRegex = /chat.whatsapp.com\/(?:invite\/)?([0-9A-Za-z]{20,24})/i 2 | export async function before(m, { isAdmin, isBotAdmin }) { 3 | if (m.isBaileys && m.fromMe) 4 | return !0 5 | if (!m.isGroup) return !1 6 | let chat = global.db.data.chats[m.chat] 7 | let bot = global.db.data.settings[this.user.jid] || {} 8 | const isGroupLink = linkRegex.exec(m.text) 9 | 10 | if (chat.antiLink && isGroupLink && !isAdmin) { 11 | if (isBotAdmin) { 12 | const linkThisGroup = `https://chat.whatsapp.com/${await this.groupInviteCode(m.chat)}` 13 | if (m.text.includes(linkThisGroup)) return !0 14 | } 15 | await conn.sendButton(m.chat, `*Group link detect!*${isBotAdmin ? '' : '\n\n_Bot not admin_ t_t'}`, author, ['off antilink', '/disable antilink'], m) 16 | if (isBotAdmin && bot.restrict) { 17 | await conn.groupParticipantsUpdate(m.chat, [m.sender], 'remove') 18 | } else if (!bot.restrict) return m.reply('Owner disable auto kick!') 19 | } 20 | return !0 21 | } -------------------------------------------------------------------------------- /plugins/_antispam.js: -------------------------------------------------------------------------------- 1 | export async function all(m) { 2 | if (!m.message) 3 | return 4 | this.spam = this.spam ? this.spam : {} 5 | if (m.sender in this.spam) { 6 | this.spam[m.sender].count++ 7 | if (m.messageTimestamp.toNumber() - this.spam[m.sender].lastspam > 10) { 8 | if (this.spam[m.sender].count > 10) { 9 | //global.db.data.users[m.sender].banned = true 10 | m.reply('*Jangan Spam!!*') 11 | } 12 | this.spam[m.sender].count = 0 13 | this.spam[m.sender].lastspam = m.messageTimestamp.toNumber() 14 | } 15 | } 16 | else 17 | this.spam[m.sender] = { 18 | jid: m.sender, 19 | count: 0, 20 | lastspam: 0 21 | } 22 | } -------------------------------------------------------------------------------- /plugins/_autolevelup.js: -------------------------------------------------------------------------------- 1 | import { canLevelUp } from '../lib/levelling.js' 2 | export function before(m) { 3 | let user = global.db.data.users[m.sender] 4 | if (!user.autolevelup) 5 | return !0 6 | let before = user.level * 1 7 | while (canLevelUp(user.level, user.exp, global.multiplier)) 8 | user.level++ 9 | 10 | if (before !== user.level) { 11 | m.reply(` 12 | Selamat, anda telah naik level! 13 | *${before}* -> *${user.level}* 14 | gunakan *.profile* untuk mengecek 15 | `.trim()) 16 | } 17 | } 18 | export const disabled = false 19 | -------------------------------------------------------------------------------- /plugins/_cmdWithMedia.js: -------------------------------------------------------------------------------- 1 | const { 2 | proto, 3 | generateWAMessage, 4 | areJidsSameUser 5 | } = (await import('@adiwajshing/baileys')).default 6 | 7 | export async function all(m, chatUpdate) { 8 | if (m.isBaileys) return 9 | if (!m.message) return 10 | if (!m.msg.fileSha256) return 11 | if (!(Buffer.from(m.msg.fileSha256).toString('base64') in global.db.data.sticker)) return 12 | 13 | let hash = global.db.data.sticker[Buffer.from(m.msg.fileSha256).toString('base64')] 14 | let { text, mentionedJid } = hash 15 | let messages = await generateWAMessage(m.chat, { text: text, mentions: mentionedJid }, { 16 | userJid: this.user.id, 17 | quoted: m.quoted && m.quoted.fakeObj 18 | }) 19 | messages.key.fromMe = areJidsSameUser(m.sender, this.user.id) 20 | messages.key.id = m.key.id 21 | messages.pushName = m.pushName 22 | if (m.isGroup) messages.participant = m.sender 23 | let msg = { 24 | ...chatUpdate, 25 | messages: [proto.WebMessageInfo.fromObject(messages)], 26 | type: 'append' 27 | } 28 | this.ev.emit('messages.upsert', msg) 29 | } 30 | -------------------------------------------------------------------------------- /plugins/_durability.js: -------------------------------------------------------------------------------- 1 | let handler = m => m 2 | 3 | handler.before = async function (m) { 4 | let user = db.data.users[m.sender] 5 | 6 | //Sword 7 | if (user.sword > 0) { 8 | if (user.sworddurability < 1) { 9 | user.sworddurability = 30 10 | user.sword -= 1 11 | } 12 | } 13 | if (user.sword == 0) { 14 | user.sworddurability = 0 15 | } 16 | 17 | //pickaxe 18 | if (user.pickaxe > 0) { 19 | if (user.pickaxedurability < 1) { 20 | user.pickaxedurability = 30 21 | user.pickaxe -= 1 22 | } 23 | } 24 | if (user.pickaxe == 0) { 25 | user.pickaxedurability = 0 26 | } 27 | 28 | //armor 29 | if (user.armor > 0) { 30 | if (user.armordurability < 1) { 31 | user.armordurability = 30 32 | user.armor -= 1 33 | } 34 | } 35 | if (user.armor == 0) { 36 | user.armordurability = 0 37 | } 38 | } 39 | export default handler -------------------------------------------------------------------------------- /plugins/_expired.js: -------------------------------------------------------------------------------- 1 | export async function all(m) { 2 | if (!m.isGroup) 3 | return 4 | let chats = global.db.data.chats[m.chat] 5 | if (!chats.expired) 6 | return !0 7 | if (+new Date() > chats.expired) { 8 | await this.reply(m.chat, 'Bye🖐 bot akan left!!') 9 | await this.groupLeave(m.chat) 10 | chats.expired = null 11 | } 12 | } -------------------------------------------------------------------------------- /plugins/_health.js: -------------------------------------------------------------------------------- 1 | let handler = m => m 2 | 3 | handler.before = async function (m) { 4 | let user = db.data.users[m.sender] 5 | if (user.health > 100) { 6 | user.health = 100 7 | } 8 | if (user.health < 0) { 9 | user.health = 0 10 | } 11 | } 12 | 13 | export default handler -------------------------------------------------------------------------------- /plugins/_premium.js: -------------------------------------------------------------------------------- 1 | let handler = m => m 2 | 3 | handler.before = async function (m) { 4 | let user = db.data.users[m.sender] 5 | if (new Date() - user.premiumTime > 0) { 6 | user.premiumTime = 0 7 | user.premium = false 8 | } 9 | } 10 | 11 | export default handler -------------------------------------------------------------------------------- /plugins/_simi.js: -------------------------------------------------------------------------------- 1 | // simi 2 | import fetch from 'node-fetch' 3 | 4 | export async function before(m) { 5 | let chat = db.data.chats[m.chat] 6 | if (chat.simi) { 7 | if (!m.text) return 8 | let url = `https://api-sv2.simsimi.net/v2/?text=${m.text}&lc=id&cf=true` 9 | let res = await fetch(url) 10 | let json = await res.json() 11 | let { 12 | response, 13 | result 14 | } = json.messages[0] 15 | await this.chatRead(m.chat, m.sender, m.id || m.key.id) 16 | await delay(1000) 17 | await this.sendPresenceUpdate('composing', m.chat) 18 | await delay(2000) 19 | m.reply(response) 20 | return !0 21 | } 22 | return !0 23 | } 24 | 25 | const delay = time => new Promise(res => setTimeout(res, time)) 26 | -------------------------------------------------------------------------------- /plugins/afk-afk.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { text }) => { 2 | let user = global.db.data.users[m.sender] 3 | user.afk = + new Date 4 | user.afkReason = text 5 | m.reply(` 6 | ${conn.getName(m.sender)} is now AFK${text ? ': ' + text : ''} 7 | `) 8 | } 9 | handler.help = ['afk [alasan]'] 10 | handler.tags = ['main'] 11 | handler.command = /^afk$/i 12 | 13 | export default handler -------------------------------------------------------------------------------- /plugins/anime-lolice.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, usedprefix }) => { 2 | let who = m.quoted ? m.quoted.sender : m.mentionedJid && m.mentionedJid[0] ? m.mentionedJid[0] : m.fromMe ? conn.user.jid : m.sender 3 | conn.sendButton(m.chat, 'liuliuliuliuliu kami dengar disini ada lolicon', author, global.API('https://some-random-api.ml', '/canvas/lolice', { 4 | avatar: await conn.profilePictureUrl(who).catch(_ => 'https://telegra.ph/file/24fa902ead26340f3df2c.png'), 5 | }), [['lolice', `${usedprefix}lolice`]], m) 6 | } 7 | 8 | handler.help = ['lolice'] 9 | handler.tags = ['maker'] 10 | 11 | handler.command = /^(lolice)$/i 12 | 13 | export default handler -------------------------------------------------------------------------------- /plugins/anime-waifu.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | 3 | let handler = async (m, { conn, usedPrefix }) => { 4 | let res = await fetch('https://api.waifu.pics/sfw/waifu') 5 | if (!res.ok) throw await res.text() 6 | let json = await res.json() 7 | if (!json.url) throw 'Error!' 8 | conn.sendButton(m.chat, 'Istri kartun', author, json.url, [['waifu', `${usedPrefix}waifu`]], m) 9 | } 10 | handler.help = ['waifu'] 11 | handler.tags = ['internet'] 12 | handler.command = /^(waifu)$/i 13 | //MADE IN ERPAN 1140 BERKOLABORASI DENGAN BTS 14 | export default handler -------------------------------------------------------------------------------- /plugins/anonymous_chat.js: -------------------------------------------------------------------------------- 1 | async function handler(m, { command }) { 2 | command = command.toLowerCase() 3 | this.anonymous = this.anonymous ? this.anonymous : {} 4 | switch (command) { 5 | case 'next': 6 | case 'leave': { 7 | let room = Object.values(this.anonymous).find(room => room.check(m.sender)) 8 | if (!room) return this.sendButton(m.chat, '_Kamu tidak sedang berada di anonymous chat_', author, null, [['Cari Partner', `.start`]], m) 9 | m.reply('Ok') 10 | let other = room.other(m.sender) 11 | if (other) await this.sendButton(other, '_Partner meninggalkan chat_', author, null, [['Cari Partner', `.start`]], m) 12 | delete this.anonymous[room.id] 13 | if (command === 'leave') break 14 | } 15 | case 'start': { 16 | if (Object.values(this.anonymous).find(room => room.check(m.sender))) return this.sendButton(m.chat, '_Kamu masih berada di dalam anonymous chat, menunggu partner_', author, null, [['Keluar', `.leave`]], m) 17 | let room = Object.values(this.anonymous).find(room => room.state === 'WAITING' && !room.check(m.sender)) 18 | if (room) { 19 | await this.sendButton(room.a, '_Partner ditemukan!_', author, null, [['Next', `.next`]], m) 20 | room.b = m.sender 21 | room.state = 'CHATTING' 22 | await this.sendButton(room.a, '_Partner ditemukan!_', author, null, [['Next', `.next`]], m) 23 | } else { 24 | let id = + new Date 25 | this.anonymous[id] = { 26 | id, 27 | a: m.sender, 28 | b: '', 29 | state: 'WAITING', 30 | check: function (who = '') { 31 | return [this.a, this.b].includes(who) 32 | }, 33 | other: function (who = '') { 34 | return who === this.a ? this.b : who === this.b ? this.a : '' 35 | }, 36 | } 37 | await this.sendButton(m.chat, '_Menunggu partner..._', author, null, [['Keluar', `.leave`]], m) 38 | } 39 | break 40 | } 41 | } 42 | } 43 | handler.help = ['start', 'leave', 'next'] 44 | handler.tags = ['anonymous'] 45 | handler.command = ['start', 'leave', 'next'] 46 | 47 | handler.private = true 48 | 49 | export default handler -------------------------------------------------------------------------------- /plugins/anonymous_chat_.js.js: -------------------------------------------------------------------------------- 1 | export async function before(m, { match }) { 2 | // if (match) return !1 3 | if (!m.chat.endsWith('@s.whatsapp.net')) 4 | return !0 5 | this.anonymous = this.anonymous ? this.anonymous : {} 6 | let room = Object.values(this.anonymous).find(room => [room.a, room.b].includes(m.sender) && room.state === 'CHATTING') 7 | if (room) { 8 | if (/^.*(next|leave|start)/.test(m.text)) 9 | return 10 | let other = [room.a, room.b].find(user => user !== m.sender) 11 | await m.copyNForward(other, true) 12 | } 13 | return !0 14 | } -------------------------------------------------------------------------------- /plugins/audio-tomp3.js: -------------------------------------------------------------------------------- 1 | import { toAudio } from '../lib/converter.js' 2 | 3 | let handler = async (m, { conn, usedPrefix, command }) => { 4 | let q = m.quoted ? m.quoted : m 5 | let mime = (m.quoted ? m.quoted : m.msg).mimetype || '' 6 | if (!/video|audio/.test(mime)) throw `reply video/voice note you want to convert to audio/mp3 with caption *${usedPrefix + command}*` 7 | let media = await q.download?.() 8 | if (!media) throw 'Can\'t download media' 9 | let audio = await toAudio(media, 'mp4') 10 | if (!audio.data) throw 'Can\'t convert media to audio' 11 | conn.sendFile(m.chat, audio.data, 'audio.mp3', '', m, null, { mimetype: 'audio/mp4' }) 12 | } 13 | handler.help = ['tomp3 (reply)'] 14 | handler.tags = ['audio'] 15 | 16 | handler.command = /^to(mp3|a(udio)?)$/i 17 | 18 | export default handler -------------------------------------------------------------------------------- /plugins/audio-toptt.js: -------------------------------------------------------------------------------- 1 | import { toPTT } from '../lib/converter.js' 2 | 3 | let handler = async (m, { conn, usedPrefix, command }) => { 4 | let q = m.quoted ? m.quoted : m 5 | let mime = (m.quoted ? m.quoted : m.msg).mimetype || '' 6 | if (!/video|audio/.test(mime)) throw `reply video/audio you want to convert to voice note/vn with caption *${usedPrefix + command}*` 7 | let media = await q.download?.() 8 | if (!media) throw 'Can\'t download media' 9 | let audio = await toPTT(media, 'mp4') 10 | if (!audio.data) throw 'Can\'t convert media to audio' 11 | conn.sendFile(m.chat, audio.data, 'audio.mp3', '', m, true, { mimetype: 'audio/mp4' }) 12 | } 13 | handler.help = ['tovn (reply)'] 14 | handler.tags = ['audio'] 15 | 16 | handler.command = /^to(vn|(ptt)?)$/i 17 | 18 | export default handler -------------------------------------------------------------------------------- /plugins/bank-cek.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn }) => { 2 | let user = global.db.data.users[m.sender] 3 | const caption = ` 4 | ▧「 *B A N K U S E R* 」 5 | │ 📛 *Name:* ${user.registered ? user.name : conn.getName(m.sender)} 6 | │ 💳 *Atm:* ${user.atm > 0 ? 'Level ' + user.atm : '✖️'} 7 | │ 🏛️ *Bank:* ${user.bank} 💲 / ${user.fullatm} 💲 8 | │ 💹 *Money:* ${user.money} 💲 9 | │ 🤖 *Robo:* ${user.robo > 0 ? 'Level ' + user.robo : '✖️'} 10 | │ 🌟 *Status:* ${user.premiumTime > 0 ? 'Premium' : 'Free'} 11 | │ 📑 *Registered:* ${user.registered ? 'Yes':'No'} 12 | └──··· 13 | `.trim() 14 | conn.sendButton(m.chat, caption, author, 'https://telegra.ph/file/0451b07945f7f9633b59b.jpg', [`Inventory`, '.inv'],m) 15 | } 16 | handler.help = ['bank'] 17 | handler.tags = ['rpg'] 18 | handler.command = /^(bank)$/i 19 | 20 | handler.register = false 21 | export default handler 22 | -------------------------------------------------------------------------------- /plugins/bank-nabung.js: -------------------------------------------------------------------------------- 1 | const xpperlimit = 1 2 | let handler = async (m, { conn, command, args }) => { 3 | let user = global.db.data.users[m.sender] 4 | let count = command.replace(/^nabung/i, '') 5 | count = count ? /all/i.test(count) ? Math.floor(global.db.data.users[m.sender].money / xpperlimit) : parseInt(count) : args[0] ? parseInt(args[0]) : 1 6 | count = Math.max(1, count) 7 | if (user.atm == 0) return m.reply('kamu belum mempuyai atm !') 8 | if (user.bank > user.fullatm) return m.reply('Uang dibankmu sudah penuh!') 9 | if (count > user.fullatm - user.bank) return m.reply('Uangnya ga muat dibank') 10 | if (global.db.data.users[m.sender].money >= xpperlimit * count) { 11 | global.db.data.users[m.sender].money -= xpperlimit * count 12 | global.db.data.users[m.sender].bank += count 13 | conn.reply(m.chat, `Sukses menabung sebesar ${count} Money 💹`, m) 14 | } else conn.reply(m.chat, `[❗] Uang anda tidak mencukupi untuk menabung ${count} money 💹`, m) 15 | } 16 | handler.help = ['nabung '] 17 | handler.tags = ['rpg'] 18 | handler.command = /^nabung([0-9]+)|nabung|nabungall$/i 19 | 20 | export default handler -------------------------------------------------------------------------------- /plugins/bank-tarik.js: -------------------------------------------------------------------------------- 1 | const xpperlimit = 1 2 | let handler = async (m, { conn, command, args }) => { 3 | let user = global.db.data.users[m.sender] 4 | let count = command.replace(/^tarik/i, '') 5 | count = count ? /all/i.test(count) ? Math.floor(global.db.data.users[m.sender].bank / xpperlimit) : parseInt(count) : args[0] ? parseInt(args[0]) : 1 6 | count = Math.max(1, count) 7 | if (user.atm == 0) return m.reply('kamu belum mempuyai atm !') 8 | if (global.db.data.users[m.sender].bank >= xpperlimit * count) { 9 | global.db.data.users[m.sender].bank -= xpperlimit * count 10 | global.db.data.users[m.sender].money += count 11 | conn.reply(m.chat, `Sukses menarik sebesar ${count} Money 💹`, m) 12 | } else conn.reply(m.chat, `[❗] Uang dibank anda tidak mencukupi untuk ditarik sebesar ${count} money 💹`, m) 13 | } 14 | handler.help = ['tarik '] 15 | handler.tags = ['rpg'] 16 | handler.command = /^tarik([0-9]+)|tarik|tarikall$/i 17 | 18 | export default handler -------------------------------------------------------------------------------- /plugins/broadcast.js: -------------------------------------------------------------------------------- 1 | import { randomBytes } from 'crypto' 2 | 3 | let handler = async (m, { conn, text }) => { 4 | let chats = Object.entries(conn.chats).filter(([_, chat]) => chat.isChats).map(v => v[0]) 5 | let cc = conn.serializeM(text ? m : m.quoted ? await m.getQuotedObj() : false || m) 6 | let teks = text ? text : cc.text 7 | conn.reply(m.chat, `_Mengirim pesan broadcast ke ${chats.length} chat_`, m) 8 | for (let id of chats) await conn.copyNForward(id, conn.cMod(m.chat, cc, /bc|broadcast/i.test(teks) ? teks : teks + '\n' + readMore + '「 ' + author + ' All Chat Broadcast 」\n' + randomID(32)), true).catch(_ => _) 9 | m.reply('Selesai Broadcast All Chat :)') 10 | } 11 | handler.help = ['broadcast', 'bc'].map(v => v + ' ') 12 | handler.tags = ['owner'] 13 | handler.command = /^(broadcast|bc)$/i 14 | 15 | handler.owner = true 16 | 17 | export default handler 18 | 19 | const more = String.fromCharCode(8206) 20 | const readMore = more.repeat(4001) 21 | 22 | const randomID = length => randomBytes(Math.ceil(length * .5)).toString('hex').slice(0, length) -------------------------------------------------------------------------------- /plugins/broadcastchats.js: -------------------------------------------------------------------------------- 1 | import { randomBytes } from 'crypto' 2 | 3 | let handler = async (m, { conn, text }) => { 4 | let chats = Object.entries(conn.chats).filter(([jid, chat]) => !jid.endsWith('@g.us') && chat.isChats).map(v => v[0]) 5 | let cc = conn.serializeM(text ? m : m.quoted ? await m.getQuotedObj() : false || m) 6 | let teks = text ? text : cc.text 7 | conn.reply(m.chat, `_Mengirim pesan broadcast ke ${chats.length} chat_`, m) 8 | for (let id of chats) await conn.copyNForward(id, conn.cMod(m.chat, cc, /bc|broadcast/i.test(teks) ? teks : teks + '\n' + readMore + '「 ' + author + ' All Chat Broadcast 」\n' + randomID(32)), true).catch(_ => _) 9 | m.reply('Selesai Broadcast All Chat :)') 10 | } 11 | handler.help = ['broadcastchats', 'bcchats'].map(v => v + ' ') 12 | handler.tags = ['owner'] 13 | handler.command = /^(broadcastchats?|bcc(hats?)?)$/i 14 | 15 | handler.owner = true 16 | 17 | export default handler 18 | 19 | const more = String.fromCharCode(8206) 20 | const readMore = more.repeat(4001) 21 | 22 | const randomID = length => randomBytes(Math.ceil(length * .5)).toString('hex').slice(0, length) -------------------------------------------------------------------------------- /plugins/broadcastgroups.js: -------------------------------------------------------------------------------- 1 | import { randomBytes } from 'crypto' 2 | 3 | let handler = async (m, { conn, text }) => { 4 | let groups = Object.entries(conn.chats).filter(([jid, chat]) => jid.endsWith('@g.us') && chat.isChats && !chat.metadata?.read_only && !chat.metadata?.announce).map(v => v[0]) 5 | let cc = text ? m : m.quoted ? await m.getQuotedObj() : false || m 6 | let teks = text ? text : cc.text 7 | conn.reply(m.chat, `_Mengirim pesan broadcast ke ${groups.length} grup_`, m) 8 | for (let id of groups) await conn.copyNForward(id, conn.cMod(m.chat, cc, /bc|broadcast/i.test(teks) ? teks : teks + '\n' + readMore + '「 All Group Broadcast 」\n' + randomID(32)), true).catch(_ => _) 9 | m.reply('Selesai Broadcast All Group :)') 10 | } 11 | handler.help = ['broadcastgroup', 'bcgc'].map(v => v + ' ') 12 | handler.tags = ['owner'] 13 | handler.command = /^(broadcast|bc)(group|grup|gc)$/i 14 | 15 | handler.owner = true 16 | 17 | export default handler 18 | 19 | const more = String.fromCharCode(8206) 20 | const readMore = more.repeat(4001) 21 | 22 | const randomID = length => randomBytes(Math.ceil(length * .5)).toString('hex').slice(0, length) 23 | -------------------------------------------------------------------------------- /plugins/creator.js: -------------------------------------------------------------------------------- 1 | function handler(m) { 2 | const data = global.owner.filter(([id, isCreator]) => id && isCreator) 3 | this.sendContact(m.chat, data.map(([id, name]) => [id, name]), m) 4 | } 5 | handler.help = ['owner', 'creator'] 6 | handler.tags = ['info'] 7 | 8 | handler.command = /^(owner|creator)$/i 9 | 10 | export default handler 11 | -------------------------------------------------------------------------------- /plugins/database-cmd-delete.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, usedPrefix, text, command }) => { 2 | let hash = text 3 | if (m.quoted && m.quoted.fileSha256) hash = m.quoted.fileSha256.toString('hex') 4 | if (!hash) throw `Tidak ada hash` 5 | let sticker = global.db.data.sticker 6 | if (sticker[hash] && sticker[hash].locked) throw 'Kamu tidak memiliki izin untuk menghapus perintah stiker ini' 7 | delete sticker[hash] 8 | m.reply(`Berhasil!`) 9 | } 10 | 11 | 12 | handler.help = ['cmd'].map(v => 'del' + v + ' ') 13 | handler.tags = ['database'] 14 | handler.command = ['delcmd'] 15 | 16 | export default handler 17 | -------------------------------------------------------------------------------- /plugins/database-cmd-list.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn }) => { 2 | conn.reply(m.chat, ` 3 | *DAFTAR HASH* 4 | \`\`\` 5 | ${Object.entries(global.db.data.sticker).map(([key, value], index) => `${index + 1}. ${value.locked ? `(Terkunci) ${key}` : key} : ${value.text}`).join('\n')} 6 | \`\`\` 7 | `.trim(), null, { 8 | mentions: Object.values(global.db.data.sticker).map(x => x.mentionedJid).reduce((a, b) => [...a, ...b], []) 9 | }) 10 | } 11 | 12 | 13 | handler.help = ['listcmd'] 14 | handler.tags = ['database'] 15 | handler.command = ['listcmd'] 16 | 17 | export default handler 18 | -------------------------------------------------------------------------------- /plugins/database-cmd-set.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, text, usedPrefix, command }) => { 2 | db.data.sticker = db.data.sticker || {} 3 | if (!m.quoted) throw 'Balas stiker dengan perintah *${usedPrefix + command}*' 4 | if (!m.quoted.fileSha256) throw 'SHA256 Hash Missing' 5 | if (!text) throw `Penggunaan:\n${usedPrefix + command} \n\nContoh:\n${usedPrefix + command} tes` 6 | let sticker = db.data.sticker 7 | let hash = m.quoted.fileSha256.toString('base64') 8 | if (sticker[hash] && sticker[hash].locked) throw 'Kamu tidak memiliki izin untuk mengubah perintah stiker ini' 9 | sticker[hash] = { 10 | text, 11 | mentionedJid: m.mentionedJid, 12 | creator: m.sender, 13 | at: + new Date, 14 | locked: false, 15 | } 16 | m.reply(`Berhasil!`) 17 | } 18 | 19 | 20 | handler.help = ['cmd'].map(v => 'set' + v + ' ') 21 | handler.tags = ['database'] 22 | handler.command = ['setcmd'] 23 | 24 | export default handler 25 | -------------------------------------------------------------------------------- /plugins/donasi.js: -------------------------------------------------------------------------------- 1 | let handler = m => m.reply(` 2 | ╭─「 Donasi 」 3 | │ • ${global.donasi} 4 | ╰──── 5 | `.trim()) // Tambah sendiri kalo mau 6 | handler.help = ['donasi'] 7 | handler.tags = ['info'] 8 | handler.command = /^dona(te|si)$/i 9 | 10 | export default handler 11 | -------------------------------------------------------------------------------- /plugins/downloader-facebook.js: -------------------------------------------------------------------------------- 1 | import { facebookdl, facebookdlv2 } from '@bochilteam/scraper' 2 | let handler = async (m, { conn, args, usedPrefix, command }) => { 3 | if (!args[0]) throw `Use example ${usedPrefix}${command} https://fb.watch/azFEBmFRcy/` 4 | const { result } = await facebookdl(args[0]).catch(async _ => await facebookdlv2(args[0])) 5 | for (const { url, isVideo } of result.reverse()) conn.sendFile(m.chat, url, `facebook.${!isVideo ? 'bin' : 'mp4'}`, `🔗 *Url:* ${url}`, m) 6 | } 7 | handler.help = ['facebbok'].map(v => v + ' ') 8 | handler.tags = ['downloader'] 9 | 10 | handler.command = /^((facebook|fb)(downloder|dl)?)$/i 11 | 12 | export default handler 13 | -------------------------------------------------------------------------------- /plugins/downloader-gitclone.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | const regex = /(?:https|git)(?::\/\/|@)github\.com[\/:]([^\/:]+)\/(.+)/i 3 | let handler = async (m, { args, usedPrefix, command }) => { 4 | if (!args[0]) throw `Example user ${usedPrefix}${command} https://github.com/BochilGaming/games-wabot` 5 | if (!regex.test(args[0])) throw 'link salah!' 6 | let [_, user, repo] = args[0].match(regex) || [] 7 | repo = repo.replace(/.git$/, '') 8 | let url = `https://api.github.com/repos/${user}/${repo}/zipball` 9 | let filename = (await fetch(url, { method: 'HEAD' })).headers.get('content-disposition').match(/attachment; filename=(.*)/)[1] 10 | // 'attachment; filename=Nurutomo-wabot-aq-v2.5.1-251-g836cccd.zip' 11 | m.reply(`*Mohon tunggu, sedang mengirim repository..*`) 12 | conn.sendFile(m.chat, url, filename, null, m) 13 | } 14 | handler.help = ['gitclone '] 15 | handler.tags = ['downloader'] 16 | handler.command = /gitclone/i 17 | 18 | handler.limit = true 19 | 20 | export default handler -------------------------------------------------------------------------------- /plugins/downloader-ig.js: -------------------------------------------------------------------------------- 1 | import { instagramdl, instagramdlv2, instagramdlv3, instagramdlv4 } from '@bochilteam/scraper' 2 | let handler = async (m, { conn, args, usedPrefix, command }) => { 3 | if (!args[0]) throw `Use example ${usedPrefix}${command} https://www.instagram.com/p/ByxKbUSnubS/?utm_source=ig_web_copy_link` 4 | const results = await instagramdl(args[0]) 5 | .catch(async _ => await instagramdlv2(args[0])) 6 | .catch(async _ => await instagramdlv3(args[0])) 7 | .catch(async _ => await instagramdlv4(args[0])) 8 | for (const { url } of results) await conn.sendFile(m.chat, url, 'instagram.mp4', `🔗 *Url:* ${url}`, m) 9 | } 10 | handler.help = ['ig'].map(v => v + ' ') 11 | handler.tags = ['downloader'] 12 | 13 | handler.command = /^(ig(dl)?)$/i 14 | 15 | export default handler 16 | -------------------------------------------------------------------------------- /plugins/downloader-igstalk.js: -------------------------------------------------------------------------------- 1 | import { instagramStalk } from '@bochilteam/scraper' 2 | 3 | let handler= async (m, { args, usedPrefix, command }) => { 4 | if (!args[0]) throw `Example use ${usedPrefix}${command} ` 5 | const { 6 | username, 7 | name, 8 | description, 9 | followersH, 10 | followingH, 11 | postsH, 12 | } = await instagramStalk(args[0]) 13 | m.reply(` 14 | ${name} *(${username})* 15 | https://instagram.com/${username.replace(/^@/, '')} 16 | *${followersH}* Followers 17 | *${followingH}* Following 18 | *${postsH}* Posts 19 | *Bio:* ${description} 20 | `.trim()) 21 | } 22 | 23 | handler.help = ['igstalk'].map(v => v + ' ') 24 | handler.tags = ['downloader'] 25 | 26 | handler.command = /^(igstalk)$/i 27 | 28 | export default handler -------------------------------------------------------------------------------- /plugins/downloader-mediafire.js: -------------------------------------------------------------------------------- 1 | import { mediafiredl } from '@bochilteam/scraper' 2 | let handler = async (m, { conn, args, usedPrefix, command }) => { 3 | if (!args[0]) throw `Use example ${usedPrefix}${command} https://www.mediafire.com/file/941xczxhn27qbby/GBWA_V12.25FF-By.SamMods-.apk/file` 4 | let res = await mediafiredl(args[0]) 5 | let { url, url2, filename, ext, aploud, filesize, filesizeH } = res 6 | let caption = ` 7 | *Name:* ${filename} 8 | *Size:* ${filesizeH} 9 | *Extension:* ${ext} 10 | *Uploaded:* ${aploud} 11 | `.trim() 12 | m.reply(caption) 13 | await conn.sendFile(m.chat, url, filename, '', m, null, { mimetype: ext, asDocument: true }) 14 | } 15 | handler.help = ['mediafire'].map(v => v + ' ') 16 | handler.tags = ['downloader'] 17 | handler.command = /^(mediafire|mf)$/i 18 | 19 | handler.limit = false 20 | 21 | export default handler 22 | -------------------------------------------------------------------------------- /plugins/downloader-twitter.js: -------------------------------------------------------------------------------- 1 | import { twitterdlv2 } from '@bochilteam/scraper' 2 | let handler = async (m, { conn, args, usedPrefix, command }) => { 3 | if (!args[0]) throw `uhm. urlnya mana?\n\ncontoh:\n${usedPrefix + command} https://twitter.com/gofoodindonesia/status/1229369819511709697` 4 | let res = await twitterdlv2(args[0]) 5 | const { url, quality, type } = res[1] 6 | conn.sendFile(m.chat, url, 'twitter' + (type == 'image' ? '.jpg' : '.mp4'), quality, m) 7 | } 8 | handler.help = ['twitter'].map(v => v + ' ') 9 | handler.tags = ['downloader'] 10 | handler.command = /^(twitter)$/i 11 | 12 | export default handler 13 | -------------------------------------------------------------------------------- /plugins/exp-ceksn.js: -------------------------------------------------------------------------------- 1 | import { createHash } from 'crypto' 2 | 3 | let Reg = /\|?(.*)([.|] *?)([0-9]*)$/i 4 | let handler = async function (m, { conn, text, usedPrefix }) { 5 | let sn = createHash('md5').update(m.sender).digest('hex') 6 | 7 | m.reply(`*📮 SN:* ${sn}`) 8 | } 9 | 10 | handler.help = ['ceksn'] 11 | handler.tags = ['xp'] 12 | handler.command = /^(ceksn)$/i 13 | handler.register = true 14 | export default handler -------------------------------------------------------------------------------- /plugins/exp-profile.js: -------------------------------------------------------------------------------- 1 | import PhoneNumber from 'awesome-phonenumber' 2 | import fetch from 'node-fetch' 3 | let handler = async (m, { conn }) => { 4 | let _pp = './src/avatar_contact.png' 5 | let user = db.data.users[m.sender] 6 | let who = m.mentionedJid && m.mentionedJid[0] ? m.mentionedJid[0] : m.fromMe ? conn.user.jid : m.sender 7 | let pp = await conn.profilePictureUrl(who, 'image').catch(_ => './src/avatar_contact.png') 8 | let { premium, level, limit, exp, lastclaim, registered, regTime, age } = global.db.data.users[m.sender] 9 | let username = conn.getName(who) 10 | let name = conn.getName(who) 11 | let fkon = { key: { fromMe: false, participant: `${m.sender.split`@`[0]}@s.whatsapp.net`, ...(m.chat ? { remoteJid: '16504228206@s.whatsapp.net' } : {}) }, message: { contactMessage: { displayName: `${name}`, vcard: `BEGIN:VCARD\nVERSION:3.0\nN:;a,;;;\nFN:${name}\nitem1.TEL;waid=${m.sender.split('@')[0]}:${m.sender.split('@')[0]}\nitem1.X-ABLabel:Ponsel\nEND:VCARD`}}} 12 | let str = ` 13 | ]──────────❏ *PROFILE* ❏──────────[ 14 | 💌 • *Name:* ${username} 15 | 🎐 • *Username:* ${registered ? name : ''} 16 | 📧 • *Tag:* @${who.replace(/@.+/, '')} 17 | 📞 • *Number:* ${PhoneNumber('+' + who.replace('@s.whatsapp.net', '')).getNumber('international')} 18 | 🔗 • *Link:* https://wa.me/${who.split`@`[0]} 19 | 🎨 • *Age:* ${registered ? age : ''} 20 | ${readMore} 21 | 🌟 • *Premium:* ${premium ? "✅" :"❌"} 22 | ⏰ • *PremiumTime:* 23 | ${clockString(user.premiumTime)} 24 | 📑 • *Registered:* ${registered ? '✅': '❌'} 25 | `.trim() 26 | conn.sendButton(m.chat, str, author, pp, [[`${registered ? 'Menu':'Verify'}`, `${user.registered ? '.menu':'.verify'}`]], fkon, { contextInfo: { mentionedJid: [who], forwardingScore: 999, isForwarded: true}}) 27 | } 28 | handler.help = ['profile [@user]'] 29 | handler.tags = ['xp'] 30 | handler.command = /^profile|pp$/i 31 | export default handler 32 | 33 | const more = String.fromCharCode(8206) 34 | const readMore = more.repeat(4001) 35 | 36 | function clockString(ms) { 37 | let d = isNaN(ms) ? '--' : Math.floor(ms / 86400000) 38 | let h = isNaN(ms) ? '--' : Math.floor(ms / 3600000) % 24 39 | let m = isNaN(ms) ? '--' : Math.floor(ms / 60000) % 60 40 | let s = isNaN(ms) ? '--' : Math.floor(ms / 1000) % 60 41 | return [d, ' *Days ☀️*\n ', h, ' *Hours 🕐*\n ', m, ' *Minute ⏰*\n ', s, ' *Second ⏱️* '].map(v => v.toString().padStart(2, 0)).join('') 42 | } 43 | -------------------------------------------------------------------------------- /plugins/exp-tomoney.js: -------------------------------------------------------------------------------- 1 | const xpperlimit = 2 2 | let handler = async (m, { conn, command, args }) => { 3 | let user = global.db.data.users[m.sender] 4 | let count = command.replace(/^tomoney/i, '') 5 | count = count ? /all/i.test(count) ? Math.floor(global.db.data.users[m.sender].exp / xpperlimit) : parseInt(count) : args[0] ? parseInt(args[0]) : 1 6 | count = Math.max(1, count) 7 | if (global.db.data.users[m.sender].exp >= xpperlimit * count) { 8 | global.db.data.users[m.sender].exp -= xpperlimit * count 9 | global.db.data.users[m.sender].money += count 10 | conn.reply(m.chat, `Sukses menukarkan exp sebesar ${count} Exp ✨`, m) 11 | } else conn.reply(m.chat, `[❗] Exp anda tidak mencukupi untuk ditukar sebesar ${count} ✨`, m) 12 | } 13 | handler.help = ['tomoney '] 14 | handler.tags = ['xp'] 15 | handler.command = /^tomoney([0-9]+)|tomoney|tomoneyall$/i 16 | 17 | export default handler -------------------------------------------------------------------------------- /plugins/exp-unreg.js: -------------------------------------------------------------------------------- 1 | import { createHash } from 'crypto' 2 | let handler = async function (m, { args }) { 3 | if (!args[0]) throw 'Serial Number kosong' 4 | let user = global.db.data.users[m.sender] 5 | let sn = createHash('md5').update(m.sender).digest('hex') 6 | if (args[0] !== sn) throw 'Serial Number salah' 7 | user.registered = false 8 | m.reply('```Succes Unreg !```') 9 | } 10 | handler.help = ['', 'ister'].map(v => 'unreg' + v + ' ') 11 | handler.tags = ['xp'] 12 | 13 | handler.command = /^unreg(ister)?$/i 14 | handler.register = true 15 | 16 | export default handler -------------------------------------------------------------------------------- /plugins/fun-apakah.js: -------------------------------------------------------------------------------- 1 | let handler = async (m) => m.reply(` 2 | *Pertanyaan:* ${m.text} 3 | *Jawaban:* ${['Ya', 'Mungkin iya', 'Mungkin', 'Mungkin tidak', 'Tidak', 'Tidak mungkin'].getRandom()} 4 | `.trim(), null, m.mentionedJid ? { 5 | mentions: m.mentionedJid 6 | } : {}) 7 | 8 | handler.help = ['apakah ?'] 9 | handler.tags = ['kerang', 'fun'] 10 | handler.customPrefix = /(\?$)/ 11 | handler.command = /^apakah$/i 12 | 13 | export default handler 14 | -------------------------------------------------------------------------------- /plugins/fun-apakah2.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { command, text }) => m.reply(` 2 | *Pertanyaan:* ${command} ${text} 3 | *Jawaban:* ${['Ya', 'Mungkin iya', 'Mungkin', 'Mungkin tidak', 'Tidak', 'Tidak mungkin'].getRandom()} 4 | `.trim(), null, m.mentionedJid ? { 5 | mentions: m.mentionedJid 6 | } : {}) 7 | 8 | handler.help = ['apakah ?'] 9 | handler.tags = ['kerang', 'fun'] 10 | handler.command = /^apakah$/i 11 | 12 | export default handler 13 | -------------------------------------------------------------------------------- /plugins/fun-generate_nama.js: -------------------------------------------------------------------------------- 1 | function handler(m, { text }) { 2 | let teks = text ? text : m.quoted && m.quoted.text ? m.quoted.text : m.text 3 | m.reply(teks.replace(/[a-z]/gi, v => { 4 | return { 5 | 'a': 'ka', 6 | 'b': 'tu', 7 | 'c': 'mi', 8 | 'd': 'te', 9 | 'e': 'ku', 10 | 'f': 'lu', 11 | 'g': 'ji', 12 | 'h': 'ri', 13 | 'i': 'ki', 14 | 'j': 'zu', 15 | 'k': 'me', 16 | 'l': 'ta', 17 | 'm': 'rin', 18 | 'n': 'to', 19 | 'o': 'mo', 20 | 'p': 'no', 21 | 'q': 'ke', 22 | 'r': 'shi', 23 | 's': 'ari', 24 | 't': 'ci', 25 | 'u': 'do', 26 | 'v': 'ru', 27 | 'w': 'mei', 28 | 'x': 'na', 29 | 'y': 'fu', 30 | 'z': 'zi' 31 | }[v.toLowerCase()] || v 32 | })) 33 | } 34 | handler.help = ['namaninja '] 35 | handler.tags = ['fun'] 36 | handler.command = /^(namaninja|namae)$/i 37 | 38 | export default handler -------------------------------------------------------------------------------- /plugins/fun-generate_purba.js: -------------------------------------------------------------------------------- 1 | function handler(m, { text }) { 2 | let teks = text ? text : m.quoted && m.quoted.text ? m.quoted.text : m.text 3 | m.reply(teks.replace(/[aiueo]/gi, '$&ve')) 4 | } 5 | handler.help = ['purba '] 6 | handler.tags = ['fun'] 7 | handler.command = /^(purba)$/i 8 | 9 | 10 | export default handler -------------------------------------------------------------------------------- /plugins/fun-how.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, command, text, usedPrefix }) => { 2 | if (!text) throw `Use example ${usedPrefix}${command} i'm` 3 | conn.reply(m.chat, ` 4 | ${command} *${text}* 5 | *${text}* is *${(101).getRandom()}*% ${command.replace('how', '').toUpperCase()} 6 | `.trim(), m, m.mentionedJid ? { 7 | mentions: m.mentionedJid 8 | } : {}) 9 | } 10 | handler.help = ['gay', 'pintar', 'cantik', 'ganteng', 'gabut', 'gila', 'lesbi', 'stress', 'bucin', 'jones', 'sadboy'].map(v => 'how' + v + ' siapa?') 11 | handler.tags = ['kerang', 'fun'] 12 | handler.command = /^how(gay|pintar|cantik|ganteng|gabut|gila|lesbi|stress?|bucin|jones|sadboy)/i 13 | 14 | export default handler -------------------------------------------------------------------------------- /plugins/fun-jadian.js: -------------------------------------------------------------------------------- 1 | let toM = a => '@' + a.split('@')[0] 2 | function handler(m, { groupMetadata }) { 3 | let ps = groupMetadata.participants.map(v => v.id) 4 | let a = ps.getRandom() 5 | let b 6 | do b = ps.getRandom() 7 | while (b === a) 8 | m.reply(`${toM(a)} ❤️ ${toM(b)}`, null, { 9 | mentions: [a, b] 10 | }) 11 | } 12 | handler.help = ['jadian'] 13 | handler.tags = ['main', 'fun'] 14 | handler.command = ['jadian'] 15 | 16 | handler.group = true 17 | 18 | export default handler -------------------------------------------------------------------------------- /plugins/fun-kapankah.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn }) => conn.reply(m.chat, ` 2 | *Pertanyaan:* ${m.text} 3 | *Jawaban:* ${(10).getRandom()} ${['detik', 'menit', 'jam', 'hari', 'minggu', 'bulan', 'tahun', 'dekade', 'abad'].getRandom()} lagi ... 4 | `.trim(), m, m.mentionedJid ? { 5 | mentions: m.mentionedJid 6 | } : {}) 7 | 8 | handler.help = ['', 'kah'].map(v => 'kapan' + v + ' ?') 9 | handler.tags = ['kerang', 'fun'] 10 | handler.customPrefix = /(\?$)/ 11 | handler.command = /^kapan(kah)?$/i 12 | 13 | export default handler -------------------------------------------------------------------------------- /plugins/fun-kapankah2.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, command, text }) => conn.reply(m.chat, ` 2 | *Pertanyaan:* ${command} ${text} 3 | *Jawaban:* ${(10).getRandom()} ${['detik', 'menit', 'jam', 'hari', 'minggu', 'bulan', 'tahun', 'dekade', 'abad'].getRandom()} lagi ... 4 | `.trim(), m, m.mentionedJid ? { 5 | mentions: m.mentionedJid 6 | } : {}) 7 | 8 | handler.help = ['', 'kah'].map(v => 'kapan' + v + ' ?') 9 | handler.tags = ['kerang', 'fun'] 10 | handler.command = /^kapan(kah)?$/i 11 | 12 | export default handler -------------------------------------------------------------------------------- /plugins/fun-kerangajaib.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { text, command, usedPrefix }) => { 2 | if (!text) throw `Use example ${usedPrefix}${command} i'm alien?` 3 | m.reply(`"${[ 4 | 'Mungkin suatu hari', 5 | 'Tidak juga', 6 | 'Tidak keduanya', 7 | 'Kurasa tidak', 8 | 'Ya', 9 | 'Coba tanya lagi', 10 | 'Tidak ada' 11 | ].getRandom()}."`) 12 | } 13 | handler.help = ['kerang', 'kerangajaib'].map(v => v + ' ') 14 | handler.tags = ['kerang', 'fun'] 15 | 16 | handler.command = /^(kulit)?kerang(ajaib)?$/i 17 | 18 | export default handler 19 | -------------------------------------------------------------------------------- /plugins/fun-paling.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, text, participants, usedPrefix }) => { 2 | if (!text) throw `Example:\n${usedPrefix}paling cantik` 3 | let member = participants.map(u => u.id).filter(v => v !== conn.user.jid) 4 | let tagged = member[Math.floor(Math.random() * member.length)] 5 | let jawab = `Yang paling *${text}* disini adalah @${tagged.replace(/@.+/, '')}`.trim() 6 | let mentionedJid = [tagged] 7 | conn.reply(m.chat, jawab, m, { contextInfo: { mentionedJid } }) 8 | } 9 | handler.help = ['paling '] 10 | handler.tags = ['fun'] 11 | handler.command = /^(paling)$/i 12 | handler.group = true 13 | 14 | export default handler 15 | -------------------------------------------------------------------------------- /plugins/fun-siapa.js: -------------------------------------------------------------------------------- 1 | let toM = a => '@' + a.split('@')[0] 2 | function handler(m, { groupMetadata, text, usedPrefix, command }) { 3 | let ps = groupMetadata.participants.map(v => v.id) 4 | if (!text) throw `Use example ${usedPrefix}${command} mukanya kayak babi` 5 | let a = ps.getRandom() 6 | m.reply(`𝐏𝐞𝐫𝐭𝐚𝐧𝐲𝐚𝐚𝐧: ${command} ${text}\n 𝐉𝐚𝐰𝐚𝐛𝐚𝐧: ${toM(a)}`, null, { 7 | mentions: [a] 8 | }) 9 | } 10 | handler.help = ['siapa'] 11 | handler.tags = ['main', 'fun'] 12 | handler.customPrefix = /(\?$)/ 13 | handler.command = ['siapa'] 14 | 15 | handler.group = true 16 | 17 | export default handler 18 | -------------------------------------------------------------------------------- /plugins/fun-twibbonizze.js: -------------------------------------------------------------------------------- 1 | import { twisearch, Twibbonizze } from 'twibbonizze' 2 | import * as fs from 'fs' 3 | import { join } from 'path' 4 | 5 | let __dirname = global.__dirname(import.meta.url) 6 | let src = join(__dirname, '../src/temp/') 7 | let tesss = join(src, pickRandom()+'.jpg') 8 | 9 | let handler = async (m, { conn, text }) => { 10 | if (!text) throw 'Twibbon apa kak?\nCnth. *#twibbon* badut' 11 | let q = m.quoted ? m.quoted : m 12 | let mime = (q.msg || q).mimetype || q.mediaType || '' 13 | if (!mime) throw `Reply Foto/Kirim foto` 14 | if (!/image\/(jpe?g|png)/.test(mime)) throw `Mime ${mime} tidak support` 15 | let msg = await conn.fakeReply(m.chat, `Proses Kak...`, '0@s.whatsapp.net', text) 16 | let img = await q.download?.() 17 | try { 18 | let tes = await (new Twibbonizze(text)).create(img) 19 | let trs = await fs.writeFileSync(tesss, tes, { encoding: 'base64'}) 20 | await conn.sendFile(m.chat, await fs.readFileSync(tesss), 'tes.jpg', 'Sudah Jadi kak >_<', m) 21 | await conn.sendMessage(m.chat, { delete: msg.key }) 22 | } catch (err) { 23 | await delay(2500) 24 | conn.fakeReply(m.chat, `FAIL!`, '0@s.whatsapp.net', text) 25 | } 26 | try { 27 | await fs.unlinkSync(tesss) 28 | } catch (err) { 29 | await delay(2500) 30 | conn.fakeReply(m.chat, `TWIBBON Tidak ditemukan`, '0@s.whatsapp.net', text) 31 | } 32 | // await fs.unlinkSync(image) 33 | } 34 | handler.help = ["twibbon "] 35 | handler.tags = ["fun"] 36 | handler.command = /^twibbon|twb/i 37 | export default handler 38 | 39 | const delay = time => new Promise(res => setTimeout(res, time)) 40 | 41 | function pickRandom() { 42 | return Math.floor(Math.random() * 100) + 10; 43 | } 44 | -------------------------------------------------------------------------------- /plugins/game-caklontong.js: -------------------------------------------------------------------------------- 1 | import { caklontong } from '@bochilteam/scraper' 2 | 3 | let timeout = 120000 4 | let poin = 4999 5 | let handler = async (m, { conn, usedPrefix }) => { 6 | conn.caklontong = conn.caklontong ? conn.caklontong : {} 7 | let id = m.chat 8 | if (id in conn.caklontong) return conn.reply(m.chat, 'Masih ada soal belum terjawab di chat ini', conn.caklontong[id][0]) 9 | let json = await caklontong() 10 | let caption = ` 11 | ${json.soal} 12 | Timeout *${(timeout / 1000).toFixed(2)} detik* 13 | Ketik ${usedPrefix}calo untuk bantuan 14 | Bonus: ${poin} XP 15 | `.trim() 16 | conn.caklontong[id] = [ 17 | await conn.sendButton(m.chat, caption, author, null, [['Bantuan', `${usedPrefix}calo`]], m), 18 | json, poin, 19 | setTimeout(async () => { 20 | if (conn.caklontong[id]) await conn.sendButton(m.chat, `Waktu habis!\nJawabannya adalah *${json.jawaban}*\n${json.deskripsi}`, author, null, [['Cak Lontong', `${usedPrefix}caklontong`]], conn.caklontong[id][0]) 21 | delete conn.caklontong[id] 22 | }, timeout) 23 | ] 24 | } 25 | handler.help = ['caklontong'] 26 | handler.tags = ['game'] 27 | handler.command = /^caklontong/i 28 | 29 | export default handler -------------------------------------------------------------------------------- /plugins/game-caklontong_ans.js: -------------------------------------------------------------------------------- 1 | import similarity from 'similarity' 2 | const threshold = 0.72 3 | export async function before(m) { 4 | let id = m.chat 5 | if (!m.quoted || !m.quoted.fromMe || !m.quoted.isBaileys || !m.text || !/Ketik.*calo/i.test(m.quoted.text) || /.*(calo|bantuan)/i.test(m.text)) 6 | return !0 7 | this.caklontong = this.caklontong ? this.caklontong : {} 8 | if (!(id in this.caklontong)) 9 | return m.reply('Soal itu telah berakhir') 10 | if (m.quoted.id == this.caklontong[id][0].id) { 11 | let json = JSON.parse(JSON.stringify(this.caklontong[id][1])) 12 | if (m.text.toLowerCase() == json.jawaban.toLowerCase().trim()) { 13 | global.db.data.users[m.sender].exp += this.caklontong[id][2] 14 | await this.sendButton(m.chat, `*Benar!* +${this.caklontong[id][2]} XP\n${json.deskripsi}`, author, null, [['Cak Lontong', '.caklontong']], m) 15 | clearTimeout(this.caklontong[id][3]) 16 | delete this.caklontong[id] 17 | } else if (similarity(m.text.toLowerCase(), json.jawaban.toLowerCase().trim()) >= threshold) 18 | m.reply(`*Dikit Lagi!*`) 19 | else 20 | m.reply(`*Salah!*`) 21 | } 22 | return !0 23 | } 24 | export const exp = 0 -------------------------------------------------------------------------------- /plugins/game-caklontong_hint.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn }) => { 2 | conn.caklontong = conn.caklontong ? conn.caklontong : {} 3 | let id = m.chat 4 | if (!(id in conn.caklontong)) throw false 5 | let json = conn.caklontong[id][1] 6 | let ans = json.jawaban 7 | let clue = ans.replace(/[AIUEO]/gi, '_') 8 | m.reply('```' + clue + '```') 9 | } 10 | handler.command = /^calo$/i 11 | 12 | handler.limit = true 13 | 14 | export default handler -------------------------------------------------------------------------------- /plugins/game-family100.js: -------------------------------------------------------------------------------- 1 | import { family100 } from '@bochilteam/scraper' 2 | const winScore = 4999 3 | async function handler(m) { 4 | this.game = this.game ? this.game : {} 5 | let id = 'family100_' + m.chat 6 | if (id in this.game) { 7 | this.reply(m.chat, 'Masih ada kuis yang belum terjawab di chat ini', this.game[id].msg) 8 | throw false 9 | } 10 | const json = await family100() 11 | let caption = ` 12 | *Soal:* ${json.soal} 13 | Terdapat *${json.jawaban.length}* jawaban${json.jawaban.find(v => v.includes(' ')) ? ` 14 | (beberapa jawaban terdapat spasi) 15 | `: ''} 16 | +${winScore} XP tiap jawaban benar 17 | `.trim() 18 | this.game[id] = { 19 | id, 20 | msg: await this.sendButton(m.chat, caption, author, null, [['Nyerah', 'nyerah']], m), 21 | ...json, 22 | terjawab: Array.from(json.jawaban, () => false), 23 | winScore, 24 | } 25 | } 26 | handler.help = ['family100'] 27 | handler.tags = ['game'] 28 | handler.command = /^family100$/i 29 | 30 | export default handler -------------------------------------------------------------------------------- /plugins/game-family100_answer.js: -------------------------------------------------------------------------------- 1 | import similarity from 'similarity' 2 | const threshold = 0.72 // semakin tinggi nilai, semakin mirip 3 | export async function before(m) { 4 | this.game = this.game ? this.game : {} 5 | let id = 'family100_' + m.chat 6 | if (!(id in this.game)) 7 | return !0 8 | let room = this.game[id] 9 | let text = m.text.toLowerCase().replace(/[^\w\s\-]+/, '') 10 | let isSurrender = /^((me)?nyerah|surr?ender)$/i.test(m.text) 11 | if (!isSurrender) { 12 | let index = room.jawaban.indexOf(text) 13 | if (index < 0) { 14 | if (Math.max(...room.jawaban.filter((_, index) => !room.terjawab[index]).map(jawaban => similarity(jawaban, text))) >= threshold) 15 | m.reply('Dikit lagi!') 16 | return !0 17 | } 18 | if (room.terjawab[index]) 19 | return !0 20 | let users = global.db.data.users[m.sender] 21 | room.terjawab[index] = m.sender 22 | users.exp += room.winScore 23 | } 24 | let isWin = room.terjawab.length === room.terjawab.filter(v => v).length 25 | let caption = ` 26 | *Soal:* ${room.soal} 27 | Terdapat *${room.jawaban.length}* jawaban${room.jawaban.find(v => v.includes(' ')) ? ` 28 | (beberapa jawaban terdapat spasi) 29 | ` : ''} 30 | ${isWin ? `*SEMUA JAWABAN TERJAWAB*` : isSurrender ? '*MENYERAH!*' : ''} 31 | ${Array.from(room.jawaban, (jawaban, index) => { 32 | return isSurrender || room.terjawab[index] ? `(${index + 1}) ${jawaban} ${room.terjawab[index] ? '@' + room.terjawab[index].split('@')[0] : ''}`.trim() : false 33 | }).filter(v => v).join('\n')} 34 | ${isSurrender ? '' : `+${room.winScore} XP tiap jawaban benar`} 35 | `.trim() 36 | const msg = await this.sendButton(m.chat, caption, author, null, [[`${(isWin || isSurrender) ? 'Family 100' : 'Nyerah'}`, `${(isWin || isSurrender) ? '.family100' : 'nyerah'}`]], null, { 37 | mentions: this.parseMention(caption) 38 | }) 39 | room.msg = msg 40 | if (isWin || isSurrender) 41 | delete this.game[id] 42 | return !0 43 | } -------------------------------------------------------------------------------- /plugins/game-math_answer.js: -------------------------------------------------------------------------------- 1 | let handler = m => m 2 | handler.before = async function (m) { 3 | if (!/^-?[0-9]+(\.[0-9]+)?$/.test(m.text)) return !0 4 | let id = m.chat 5 | if (!m.quoted || !m.quoted.fromMe || !m.text || !/^Berapa hasil dari/i.test(m.quoted.text)) return !0 6 | this.math = this.math ? this.math : {} 7 | if (!(id in this.math)) return conn.sendButton(m.chat, 'Soal itu telah berakhir', author, null, [['math', '/math']], m) 8 | if (m.quoted.id == this.math[id][0].id) { 9 | let math = JSON.parse(JSON.stringify(this.math[id][1])) 10 | if (m.text == math.result) { 11 | global.db.data.users[m.sender].exp += math.bonus 12 | clearTimeout(this.math[id][3]) 13 | delete this.math[id] 14 | conn.sendButton(m.chat, `*Jawaban Benar!*\n+${math.bonus} XP`, author, null, [['again', `/math ${math.mode}`]], m) 15 | } else { 16 | if (--this.math[id][2] == 0) { 17 | clearTimeout(this.math[id][3]) 18 | delete this.math[id] 19 | conn.sendButton(m.chat, `*Kesempatan habis!*\nJawaban: *${math.result}*`, author, null, [['again', `/math ${math.mode}`]], m) 20 | } else m.reply(`*Jawaban Salah!*\nMasih ada ${this.math[id][2]} kesempatan`) 21 | } 22 | } 23 | return !0 24 | } 25 | 26 | export default handler -------------------------------------------------------------------------------- /plugins/game-siapakahaku.js: -------------------------------------------------------------------------------- 1 | import { siapakahaku } from '@bochilteam/scraper' 2 | 3 | let timeout = 120000 4 | let poin = 4999 5 | let handler = async (m, { conn, usedPrefix }) => { 6 | conn.siapakahaku = conn.siapakahaku ? conn.siapakahaku : {} 7 | let id = m.chat 8 | if (id in conn.siapakahaku) { 9 | conn.reply(m.chat, 'Masih ada soal belum terjawab di chat ini', conn.siapakahaku[id][0]) 10 | throw false 11 | } 12 | const json = await siapakahaku() 13 | let caption = ` 14 | Siapakah aku? ${json.soal} 15 | Timeout *${(timeout / 1000).toFixed(2)} detik* 16 | Ketik ${usedPrefix}who untuk bantuan 17 | Bonus: ${poin} XP 18 | `.trim() 19 | conn.siapakahaku[id] = [ 20 | await conn.sendButton(m.chat, caption, author, ['hint', `${usedPrefix}who`], m), 21 | json, poin, 22 | setTimeout(() => { 23 | if (conn.siapakahaku[id]) conn.sendButton(m.chat, `Waktu habis!\nJawabannya adalah *${json.jawaban}*`, author, ['siapahaku', '/siapakahaku'], conn.siapakahaku[id][0]) 24 | delete conn.siapakahaku[id] 25 | }, timeout) 26 | ] 27 | } 28 | handler.help = ['siapakahaku'] 29 | handler.tags = ['game'] 30 | handler.command = /^siapa(kah)?aku/i 31 | 32 | export default handler -------------------------------------------------------------------------------- /plugins/game-siapakahaku_ans.js: -------------------------------------------------------------------------------- 1 | import similarity from 'similarity' 2 | const threshold = 0.72 3 | let handler = m => m 4 | handler.before = async function (m) { 5 | let id = m.chat 6 | if (!m.quoted || !m.quoted.fromMe || !m.quoted.isBaileys || !/Ketik.*who/i.test(m.quoted.text)) return !0 7 | this.siapakahaku = this.siapakahaku ? this.siapakahaku : {} 8 | if (!(id in this.siapakahaku)) return conn.sendButton(m.chat, 'Soal itu telah berakhir', author, ['siapakahaku', '/siapakahaku'], m) 9 | if (m.quoted.id == this.siapakahaku[id][0].id) { 10 | let json = JSON.parse(JSON.stringify(this.siapakahaku[id][1])) 11 | // m.reply(JSON.stringify(json, null, '\t')) 12 | if (m.text.toLowerCase() == json.jawaban.toLowerCase().trim()) { 13 | global.db.data.users[m.sender]. 14 | exp += this.siapakahaku[id][2] 15 | conn.sendButton(m.chat, `*Benar!*\n+${this.siapakahaku[id][2]} XP`, author, ['siapakahaku', '/siapakahaku'], m) 16 | clearTimeout(this.siapakahaku[id][3]) 17 | delete this.siapakahaku[id] 18 | } else if (similarity(m.text.toLowerCase(), json.jawaban.toLowerCase().trim()) >= threshold) m.reply(`*Dikit Lagi!*`) 19 | else m.reply(`*Salah!*`) 20 | } 21 | return !0 22 | } 23 | handler.exp = 0 24 | 25 | export default handler 26 | -------------------------------------------------------------------------------- /plugins/game-siapakahaku_hint.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn }) => { 2 | conn.siapakahaku = conn.siapakahaku ? conn.siapakahaku : {} 3 | let id = m.chat 4 | if (!(id in conn.siapakahaku)) throw false 5 | let json = conn.siapakahaku[id][1] 6 | let ans = json.jawaban 7 | let clue = ans.replace(/[bcdfghjklmnpqrstvwxyz]/ig, '_') 8 | m.reply('```' + clue + '```') 9 | } 10 | handler.command = /^who$/i 11 | 12 | handler.limit = true 13 | 14 | export default handler -------------------------------------------------------------------------------- /plugins/game-tebakgambar.js: -------------------------------------------------------------------------------- 1 | import { tebakgambar } from '@bochilteam/scraper' 2 | 3 | let timeout = 120000 4 | let poin = 4999 5 | let handler = async (m, { conn, usedPrefix }) => { 6 | conn.tebakgambar = conn.tebakgambar ? conn.tebakgambar : {} 7 | let id = m.chat 8 | if (id in conn.tebakgambar) { 9 | conn.sendButton(m.chat, 'Masih ada soal belum terjawab di chat ini', author, null, buttons, conn.tebakgambar[id][0]) 10 | throw false 11 | } 12 | let json = await tebakgambar() 13 | // if (!json.status) throw json 14 | let caption = ` 15 | Timeout *${(timeout / 1000).toFixed(2)} detik* 16 | Ketik ${usedPrefix}hint untuk hint 17 | Bonus: ${poin} XP 18 | `.trim() 19 | conn.tebakgambar[id] = [ 20 | await conn.sendButton(m.chat, caption, author, json.img, buttons, m), 21 | json, poin, 22 | setTimeout(() => { 23 | if (conn.tebakgambar[id]) conn.sendButton(m.chat, `Waktu habis!\nJawabannya adalah *${json.jawaban}*`, author, null, [ 24 | ['tebakgambar', '/tebakgambar'] 25 | ], conn.tebakgambar[id][0]) 26 | delete conn.tebakgambar[id] 27 | }, timeout) 28 | ] 29 | } 30 | handler.help = ['tebakgambar'] 31 | handler.tags = ['game'] 32 | handler.command = /^tebakgambar/i 33 | 34 | export default handler 35 | 36 | const buttons = [ 37 | ['hint', '/hint'], 38 | ['nyerah', 'menyerah'] 39 | ] -------------------------------------------------------------------------------- /plugins/game-tebakgambar_answer.js: -------------------------------------------------------------------------------- 1 | import similarity from 'similarity' 2 | const threshold = 0.72 3 | export async function before(m) { 4 | let id = m.chat 5 | if (!m.quoted || !m.quoted.fromMe || !m.quoted.isBaileys || !m.text || !/Ketik.*hint/i.test(m.quoted.text) || /.*hint/i.test(m.text)) 6 | return !0 7 | this.tebakgambar = this.tebakgambar ? this.tebakgambar : {} 8 | if (!(id in this.tebakgambar)) 9 | return conn.sendButton(m.chat, 'Soal itu telah berakhir', author, null, buttonTebakgambar, m) 10 | if (m.quoted.id == this.tebakgambar[id][0].id) { 11 | let isSurrender = /^((me)?nyerah|surr?ender)$/i.test(m.text) 12 | if (isSurrender) { 13 | clearTimeout(this.tebakgambar[id][3]) 14 | delete this.tebakgambar[id] 15 | return conn.sendButton(m.chat, '*Yah Menyerah :( !*', author, null, buttonTebakgambar, m) 16 | } 17 | let json = JSON.parse(JSON.stringify(this.tebakgambar[id][1])) 18 | // m.reply(JSON.stringify(json, null, '\t')) 19 | if (m.text.toLowerCase() == json.jawaban.toLowerCase().trim()) { 20 | global.db.data.users[m.sender].exp += this.tebakgambar[id][2] 21 | conn.sendButton(m.chat, `*Benar!*\n+${this.tebakgambar[id][2]} XP`, author, null, buttonTebakgambar, m) 22 | clearTimeout(this.tebakgambar[id][3]) 23 | delete this.tebakgambar[id] 24 | } else if (similarity(m.text.toLowerCase(), json.jawaban.toLowerCase().trim()) >= threshold) 25 | m.reply(`*Dikit Lagi!*`) 26 | else 27 | conn.sendButton(m.chat, `*Salah!*`, author, null, [ 28 | ['hint', '/hint'], 29 | ['nyerah', 'menyerah'] 30 | ], m) 31 | } 32 | return !0 33 | } 34 | export const exp = 0 35 | 36 | const buttonTebakgambar = [ 37 | ['tebakgambar', '/tebakgambar'] 38 | ] -------------------------------------------------------------------------------- /plugins/game-tebakgambar_hint.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn }) => { 2 | conn.tebakgambar = conn.tebakgambar ? conn.tebakgambar : {} 3 | let id = m.chat 4 | if (!(id in conn.tebakgambar)) throw false 5 | let json = conn.tebakgambar[id][1] 6 | conn.sendButton(m.chat, '```' + json.jawaban.replace(/[bcdfghjklmnpqrstvwxyz]/ig, '_') + '```', author, null, [ 7 | ['nyerah', 'menyerah'] 8 | ], m) 9 | } 10 | handler.command = /^hint$/i 11 | 12 | handler.limit = true 13 | 14 | export default handler -------------------------------------------------------------------------------- /plugins/games-tebakkata.js: -------------------------------------------------------------------------------- 1 | import { tebakkata } from '@bochilteam/scraper' 2 | 3 | let timeout = 120000 4 | let poin = 4999 5 | let handler = async (m, { conn, usedPrefix }) => { 6 | conn.tebakkata = conn.tebakkata ? conn.tebakkata : {} 7 | let id = m.chat 8 | if (id in conn.tebakkata) { 9 | conn.reply(m.chat, 'Masih ada soal belum terjawab di chat ini', conn.tebakkata[id][0]) 10 | throw false 11 | } 12 | const json = await tebakkata() 13 | let caption = ` 14 | ${json.soal} 15 | Timeout *${(timeout / 1000).toFixed(2)} detik* 16 | Ketik ${usedPrefix}teka untuk bantuan 17 | Bonus: ${poin} XP 18 | `.trim() 19 | conn.tebakkata[id] = [ 20 | await conn.sendButton(m.chat, caption, author, ['hint', `${usedPrefix}teka`], m), 21 | json, poin, 22 | setTimeout(() => { 23 | if (conn.tebakkata[id]) conn.sendButton(m.chat, `Waktu habis!\nJawabannya adalah *${json.jawaban}*`, author, ['tebakkata', `${usedPrefix}tebakkata`], conn.tebakkata[id][0]) 24 | delete conn.tebakkata[id] 25 | }, timeout) 26 | ] 27 | } 28 | handler.help = ['tebakkata'] 29 | handler.tags = ['game'] 30 | handler.command = /^tebakkata/i 31 | 32 | export default handler -------------------------------------------------------------------------------- /plugins/games-tebakkata_ans.js: -------------------------------------------------------------------------------- 1 | import similarity from 'similarity' 2 | const threshold = 0.72 3 | export async function before(m) { 4 | let id = m.chat 5 | if (!m.quoted || !m.quoted.fromMe || !m.quoted.isBaileys || !m.text || !/Ketik.*teka/i.test(m.quoted.text) || /.*(hint|teka)/i.test(m.text)) 6 | return !0 7 | this.tebakkata = this.tebakkata ? this.tebakkata : {} 8 | if (!(id in this.tebakkata)) 9 | return conn.sendButton(m.chat, 'Soal itu telah berakhir', author, ['tebakkata', '/tebakkata'], m) 10 | if (m.quoted.id == this.tebakkata[id][0].id) { 11 | let json = JSON.parse(JSON.stringify(this.tebakkata[id][1])) 12 | // m.reply(JSON.stringify(json, null, '\t')) 13 | if (m.text.toLowerCase() == json.jawaban.toLowerCase().trim()) { 14 | global.db.data.users[m.sender].exp += this.tebakkata[id][2] 15 | conn.sendButton(m.chat, `*Benar!*\n+${this.tebakkata[id][2]} XP`, author, ['tebakkata', '/tebakkata'], m) 16 | clearTimeout(this.tebakkata[id][3]) 17 | delete this.tebakkata[id] 18 | } else if (similarity(m.text.toLowerCase(), json.jawaban.toLowerCase().trim()) >= threshold) 19 | m.reply(`*Dikit Lagi!*`) 20 | else 21 | m.reply(`*Salah!*`) 22 | } 23 | return !0 24 | } 25 | export const exp = 0 -------------------------------------------------------------------------------- /plugins/games-tebakkata_hint.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn }) => { 2 | conn.tebakkata = conn.tebakkata ? conn.tebakkata : {} 3 | let id = m.chat 4 | if (!(id in conn.tebakkata)) throw false 5 | let json = conn.tebakkata[id][1] 6 | let ans = json.jawaban.trim() 7 | let clue = ans.replace(/[AIUEO]/gi, '_') 8 | m.reply('```' + clue + '```') 9 | } 10 | handler.command = /^teka$/i 11 | 12 | handler.limit = true 13 | 14 | export default handler -------------------------------------------------------------------------------- /plugins/games-tictactoe.js: -------------------------------------------------------------------------------- 1 | import TicTacToe from '../lib/tictactoe.js' 2 | 3 | let handler = async (m, { conn, usedPrefix, command, text }) => { 4 | conn.game = conn.game ? conn.game : {} 5 | if (Object.values(conn.game).find(room => room.id.startsWith('tictactoe') && [room.game.playerX, room.game.playerO].includes(m.sender))) throw 'Kamu masih didalam game' 6 | let room = Object.values(conn.game).find(room => room.state === 'WAITING' && (text ? room.name === text : true)) 7 | // m.reply('[WIP Feature]') 8 | if (room) { 9 | m.reply('Partner ditemukan!') 10 | room.o = m.chat 11 | room.game.playerO = m.sender 12 | room.state = 'PLAYING' 13 | let arr = room.game.render().map(v => { 14 | return { 15 | X: '❌', 16 | O: '⭕', 17 | 1: '1️⃣', 18 | 2: '2️⃣', 19 | 3: '3️⃣', 20 | 4: '4️⃣', 21 | 5: '5️⃣', 22 | 6: '6️⃣', 23 | 7: '7️⃣', 24 | 8: '8️⃣', 25 | 9: '9️⃣', 26 | }[v] 27 | }) 28 | let str = ` 29 | Room ID: ${room.id} 30 | ${arr.slice(0, 3).join('')} 31 | ${arr.slice(3, 6).join('')} 32 | ${arr.slice(6).join('')} 33 | Menunggu @${room.game.currentTurn.split('@')[0]} 34 | Ketik *nyerah* untuk nyerah 35 | `.trim() 36 | if (room.x !== room.o) await conn.sendButton(room.x, str, author, ['Nyerah', 'nyerah'], m, { 37 | mentions: conn.parseMention(str) 38 | }) 39 | await conn.sendButton(room.o, str, author, ['Nyerah', 'nyerah'], m, { 40 | mentions: conn.parseMention(str) 41 | }) 42 | } else { 43 | room = { 44 | id: 'tictactoe-' + (+new Date), 45 | x: m.chat, 46 | o: '', 47 | game: new TicTacToe(m.sender, 'o'), 48 | state: 'WAITING' 49 | } 50 | if (text) room.name = text 51 | m.reply('Menunggu partner' + (text ? ` mengetik command dibawah ini 52 | ${usedPrefix}${command} ${text}` : '')) 53 | conn.game[room.id] = room 54 | } 55 | } 56 | 57 | handler.help = ['tictactoe', 'ttt'].map(v => v + ' [custom room name]') 58 | handler.tags = ['game'] 59 | handler.command = /^(tictactoe|t{3})$/ 60 | 61 | export default handler -------------------------------------------------------------------------------- /plugins/gitclone.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | const regex = /(?:https|git)(?::\/\/|@)github\.com[\/:]([^\/:]+)\/(.+)/i 3 | let handler = async (m, { args, usedPrefix, command }) => { 4 | if (!args[0]) throw `Example user ${usedPrefix}${command} https://github.com/BochilGaming/games-wabot` 5 | if (!regex.test(args[0])) throw 'link salah!' 6 | let [_, user, repo] = args[0].match(regex) || [] 7 | repo = repo.replace(/.git$/, '') 8 | let url = `https://api.github.com/repos/${user}/${repo}/zipball` 9 | let filename = (await fetch(url, { method: 'HEAD' })).headers.get('content-disposition').match(/attachment; filename=(.*)/)[1] 10 | // 'attachment; filename=Nurutomo-wabot-aq-v2.5.1-251-g836cccd.zip' 11 | m.reply(`*Mohon tunggu, sedang mengirim repository..*`) 12 | conn.sendFile(m.chat, url, filename, null, m) 13 | } 14 | handler.help = ['gitclone '] 15 | handler.tags = ['downloader'] 16 | handler.command = /gitclone/i 17 | 18 | handler.limit = true 19 | 20 | export default handler 21 | -------------------------------------------------------------------------------- /plugins/google.js: -------------------------------------------------------------------------------- 1 | import { googleIt } from '@bochilteam/scraper' 2 | let handler = async (m, { conn, command, args }) => { 3 | const fetch = (await import('node-fetch')).default 4 | let full = /f$/i.test(command) 5 | let text = args.join` ` 6 | if (!text) return conn.reply(m.chat, 'Tidak ada teks untuk di cari', m) 7 | let url = 'https://google.com/search?q=' + encodeURIComponent(text) 8 | let search = await googleIt(text) 9 | let msg = search.articles.map(({ 10 | // header, 11 | title, 12 | url, 13 | description 14 | }) => { 15 | return `*${title}*\n_${url}_\n_${description}_` 16 | }).join('\n\n') 17 | try { 18 | let ss = await (await fetch(global.API('nrtm', '/api/ssweb', { delay: 1000, url, full }))).arrayBuffer() 19 | if (//i.test(ss.toBuffer().toString())) throw '' 20 | await conn.sendFile(m.chat, ss, 'screenshot.png', url + '\n\n' + msg, m) 21 | } catch (e) { 22 | m.reply(msg) 23 | } 24 | } 25 | handler.help = ['google', 'googlef'].map(v => v + ' ') 26 | handler.tags = ['internet'] 27 | handler.command = /^googlef?$/i 28 | 29 | 30 | export default handler -------------------------------------------------------------------------------- /plugins/group-admin.js: -------------------------------------------------------------------------------- 1 | import { areJidsSameUser } from '@adiwajshing/baileys' 2 | let handler = async (m, { conn, participants, text, usedPrefix, command }) => { 3 | if (!text) throw `Tag Member nya\nContoh: *${usedPrefix + command}* @frieren` 4 | let users = m.mentionedJid[0] ? m.mentionedJid[0] : m.quoted ? m.quoted.sender : text.replace(/[^0-9]/g, '')+'@s.whatsapp.net' 5 | if (/promote/i.test(command)) { 6 | await conn.groupParticipantsUpdate(m.chat, [users], 'promote') 7 | await m.reply(`Success ${command}`) 8 | } else if (/demote/i.test(command)) { 9 | await conn.groupParticipantsUpdate(m.chat, [users], 'demote') 10 | await m.reply(`Success ${command}`) 11 | } else if (/add/i.test(command)) { 12 | await conn.groupParticipantsUpdate(m.chat, [users], 'add') 13 | await m.reply(`Success ${command}`) 14 | } else if (/kick/i.test(command)) { 15 | await conn.groupParticipantsUpdate(m.chat, [users], 'remove') 16 | await m.reply(`Success ${command}`) 17 | } 18 | } 19 | handler.help = ['promote @user', 'demote @user', 'kick @user'] 20 | handler.tags = ['group'] 21 | handler.command = /^promote|demote|kick$/i 22 | handler.group = true 23 | 24 | handler.owner = true 25 | handler.botAdmin = true 26 | 27 | export default handler 28 | -------------------------------------------------------------------------------- /plugins/group-info: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, participants, groupMetadata }) => { 2 | const pp = await conn.profilePictureUrl(m.chat, 'image').catch(_ => null) || './src/avatar_contact.png' 3 | const { isBanned, welcome, detect, sWelcome, sBye, sPromote, sDemote, antiLink, delete: del } = global.db.data.chats[m.chat] 4 | const groupAdmins = participants.filter(p => p.admin) 5 | const listAdmin = groupAdmins.map((v, i) => `${i + 1}. @${v.id.split('@')[0]}`).join('\n') 6 | const owner = groupMetadata.owner || groupAdmins.find(p => p.admin === 'superadmin')?.id || m.chat.split`-`[0] + '@s.whatsapp.net' 7 | let text = `*「 Group Information 」*\n 8 | *ID:* 9 | ${groupMetadata.id} 10 | *Name:* 11 | ${groupMetadata.subject} 12 | *Description:* 13 | ${groupMetadata.desc?.toString() || 'unknown'} 14 | *Total Members:* 15 | ${participants.length} Members 16 | *Group Owner:* 17 | @${owner.split('@')[0]} 18 | *Group Admins:* 19 | ${listAdmin} 20 | *Group Settings:* 21 | ${isBanned ? '✅' : '❌'} Banned 22 | ${welcome ? '✅' : '❌'} Welcome 23 | ${detect ? '✅' : '❌'} Detect 24 | ${del ? '❌' : '✅'} Anti Delete 25 | ${antiLink ? '✅' : '❌'} Anti Link 26 | *Message Settings:* 27 | Welcome: ${sWelcome} 28 | Bye: ${sBye} 29 | Promote: ${sPromote} 30 | Demote: ${sDemote} 31 | `.trim() 32 | conn.sendFile(m.chat, pp, 'pp.jpg', text, m, false, { mentions: [...groupAdmins.map(v => v.id), owner] }) 33 | } 34 | 35 | handler.help = ['infogrup'] 36 | handler.tags = ['group'] 37 | handler.command = /^(gro?upinfo|info(gro?up|gc))$/i 38 | 39 | handler.group = true 40 | 41 | export default handler 42 | -------------------------------------------------------------------------------- /plugins/group-info.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, participants, groupMetadata }) => { 2 | const pp = await conn.profilePictureUrl(m.chat, 'image').catch(_ => null) || './src/avatar_contact.png' 3 | const { isBanned, welcome, detect, sWelcome, sBye, sPromote, sDemote, antiLink, delete: del } = global.db.data.chats[m.chat] 4 | const groupAdmins = participants.filter(p => p.admin) 5 | const listAdmin = groupAdmins.map((v, i) => `${i + 1}. @${v.id.split('@')[0]}`).join('\n') 6 | const owner = groupMetadata.owner || groupAdmins.find(p => p.admin === 'superadmin')?.id || m.chat.split`-`[0] + '@s.whatsapp.net' 7 | let text = `*「 Group Information 」*\n 8 | *ID:* 9 | ${groupMetadata.id} 10 | *Name:* 11 | ${groupMetadata.subject} 12 | *Description:* 13 | ${groupMetadata.desc?.toString() || 'unknown'} 14 | *Total Members:* 15 | ${participants.length} Members 16 | *Group Owner:* 17 | @${owner.split('@')[0]} 18 | *Group Admins:* 19 | ${listAdmin} 20 | *Group Settings:* 21 | ${isBanned ? '✅' : '❌'} Banned 22 | ${welcome ? '✅' : '❌'} Welcome 23 | ${detect ? '✅' : '❌'} Detect 24 | ${del ? '❌' : '✅'} Anti Delete 25 | ${antiLink ? '✅' : '❌'} Anti Link 26 | *Message Settings:* 27 | Welcome: ${sWelcome} 28 | Bye: ${sBye} 29 | Promote: ${sPromote} 30 | Demote: ${sDemote} 31 | `.trim() 32 | conn.sendFile(m.chat, pp, 'pp.jpg', text, m, false, { mentions: [...groupAdmins.map(v => v.id), owner] }) 33 | } 34 | 35 | handler.help = ['infogrup'] 36 | handler.tags = ['group'] 37 | handler.command = /^(gro?upinfo|info(gro?up|gc))$/i 38 | 39 | handler.group = true 40 | 41 | export default handler -------------------------------------------------------------------------------- /plugins/group-leavegc.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, args, command }) => { 2 | let chat = Object.keys(conn.chats).filter(v => v.endsWith('g.us')) 3 | if (command.endsWith('all') || command.endsWith('semua')) { 4 | for (let id of chat) { // perulangan 5 | await conn.groupLeave(id) 6 | await delay(2000) // jeda 2 detik 7 | } 8 | await m.reply('Berhasil!') 9 | } else if (args[0] || args.length > 5) { 10 | let ada = chat.find(bot => bot == args[0]) // Apakah botnya ada disitu 11 | if (!ada) throw 'id salah/bot tidak ada digrup itu' 12 | await conn.groupLeave(args[0]) 13 | await m.reply('Berhasil!') 14 | } else { 15 | if (!m.isGroup) return global.dfail('group', m, conn) 16 | await conn.groupLeave(m.chat) 17 | } 18 | 19 | } 20 | 21 | handler.help = ['gc', 'gcall', 'group'].map(v => 'leave' + v) 22 | handler.tags = ['group'] 23 | handler.command = /^leaveg(c|ro?up)(all|semua)?$/i 24 | 25 | handler.rowner = true 26 | 27 | export default handler 28 | 29 | const delay = time => new Promise(res => setTimeout(res, time)) 30 | -------------------------------------------------------------------------------- /plugins/group-link.js: -------------------------------------------------------------------------------- 1 | import { areJidsSameUser } from '@adiwajshing/baileys' 2 | let handler = async (m, { conn, args }) => { 3 | let group = m.chat 4 | if (/^[0-9]{5,16}-?[0-9]+@g\.us$/.test(args[0])) group = args[0] 5 | if (!/^[0-9]{5,16}-?[0-9]+@g\.us$/.test(group)) throw 'Hanya bisa dibuka di grup' 6 | let groupMetadata = await conn.groupMetadata(group) 7 | if (!groupMetadata) throw 'groupMetadata is undefined :\\' 8 | if (!('participants' in groupMetadata)) throw 'participants is not defined :(' 9 | let me = groupMetadata.participants.find(user => areJidsSameUser(user.id, conn.user.id)) 10 | if (!me) throw 'Aku tidak ada di grup itu :(' 11 | if (!me.admin) throw 'Aku bukan admin T_T' 12 | m.reply('https://chat.whatsapp.com/' + await conn.groupInviteCode(group)) 13 | } 14 | handler.help = ['linkgroup'] 15 | handler.tags = ['group'] 16 | handler.command = /^link(gro?up)?$/i 17 | 18 | 19 | export default handler -------------------------------------------------------------------------------- /plugins/group-pengumuman.js: -------------------------------------------------------------------------------- 1 | import { generateWAMessageFromContent } from '@adiwajshing/baileys' 2 | let handler = async (m, { conn, text, participants }) => { 3 | let users = participants.map(u => conn.decodeJid(u.id)) 4 | let q = m.quoted ? m.quoted : m 5 | let c = m.quoted ? m.quoted : m.msg 6 | const msg = conn.cMod(m.chat, 7 | generateWAMessageFromContent(m.chat, { 8 | [c.toJSON ? q.mtype : 'extendedTextMessage']: c.toJSON ? c.toJSON() : { 9 | text: c || '' 10 | } 11 | }, { 12 | quoted: m, 13 | userJid: conn.user.id 14 | }), 15 | text || q.text, conn.user.jid, { mentions: users } 16 | ) 17 | await conn.relayMessage(m.chat, msg.message, { messageId: msg.key.id }) 18 | } 19 | handler.help = ['pengumuman', 'announce', 'hidetag'].map(v => v + ' [teks]') 20 | handler.tags = ['group'] 21 | handler.command = /^(pengumuman|announce|hiddentag|hidetag)$/i 22 | 23 | handler.group = true 24 | handler.admin = true 25 | 26 | export default handler 27 | 28 | -------------------------------------------------------------------------------- /plugins/group-settings.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, args, usedPrefix, command }) => { 2 | let isClose = { // Switch Case Like :v 3 | 'open': 'not_announcement', 4 | 'close': 'announcement', 5 | }[(args[0] || '')] 6 | if (isClose === undefined) 7 | throw ` 8 | *Format salah! Contoh :* 9 | *○ ${usedPrefix + command} close* 10 | *○ ${usedPrefix + command} open* 11 | `.trim() 12 | await conn.groupSettingUpdate(m.chat, isClose) 13 | } 14 | handler.help = ['group *open / close*'] 15 | handler.tags = ['group'] 16 | handler.command = /^(group)$/i 17 | 18 | handler.admin = true 19 | handler.botAdmin = true 20 | 21 | export default handler 22 | -------------------------------------------------------------------------------- /plugins/group-tagall.js: -------------------------------------------------------------------------------- 1 | 2 | let handler = async(m, { conn, usedPrefix: _p, text, participants }) => { 3 | let user = global.db.data.users[m.sender] 4 | let teks = `${text ? text : '*––––––『 Tag All 』––––––*'}\n${readMore}` 5 | for (let mem of participants) { 6 | teks += `\n@${mem.id.split('@')[0]}` 7 | } 8 | await conn.sendMessage(m.chat, { text: teks, mentions: participants.map(a => a.id) }, ) 9 | } 10 | handler.help = ['tagall '] 11 | handler.tags = ['group'] 12 | handler.command = /^(tagall)$/i 13 | 14 | handler.group = true 15 | handler.admin = true 16 | 17 | export default handler 18 | 19 | const more = String.fromCharCode(8206) 20 | const readMore = more.repeat(4001) 21 | -------------------------------------------------------------------------------- /plugins/group-tagme.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, text }) => { 2 | let tag = `@${m.sender.replace(/@.+/, '')}` 3 | let mentionedJid = [m.sender] 4 | conn.reply(m.chat, tag, m, { contextInfo: { mentionedJid }}) 5 | } 6 | handler.help = ['tagme'] 7 | handler.tags = ['group'] 8 | handler.command = /^tagme$/i 9 | 10 | handler.group = false 11 | 12 | export default handler -------------------------------------------------------------------------------- /plugins/image-gimage.js: -------------------------------------------------------------------------------- 1 | import { googleImage } from '@bochilteam/scraper' 2 | let handler = async (m, { conn, text, usedPrefix, command }) => { 3 | if (!text) throw `Use example ${usedPrefix}${command} Minecraft` 4 | const res = await googleImage(text) 5 | conn.sendFile(m.chat, res.getRandom(), 'gimage.jpg', ` 6 | *── 「 GOOGLE IMAGE 」 ──* 7 | 8 | Result from *${text}* 9 | `.trim(), m) 10 | } 11 | handler.help = ['gimage ', 'image '] 12 | handler.tags = ['internet', 'tools'] 13 | handler.command = /^(gimage|image)$/i 14 | 15 | export default handler -------------------------------------------------------------------------------- /plugins/image-pinterest.js: -------------------------------------------------------------------------------- 1 | import { pinterest } from '@bochilteam/scraper' 2 | 3 | let handler = async(m, { conn, text, usedPrefix, command }) => { 4 | if (!text) throw `Example use ${usedPrefix + command} minecraft` 5 | const json = await pinterest(text) 6 | conn.sendFile(m.chat, json.getRandom(), 'pinterest.jpg', ` 7 | *Hasil pencarian* 8 | ${text} 9 | `.trim(), m) 10 | } 11 | handler.help = ['pinterest '] 12 | handler.tags = ['internet'] 13 | handler.command = /^(pinterest)$/i 14 | 15 | export default handler -------------------------------------------------------------------------------- /plugins/image-wallpaper.js: -------------------------------------------------------------------------------- 1 | import { wallpaper, wallpaperv2 } from '@bochilteam/scraper' 2 | let handler = async (m, { conn, text, usedPrefix, command }) => { 3 | if (!text) throw `Use example ${usedPrefix}${command} Minecraft` 4 | const res = await (/2/.test(command) ? wallpaperv2 : wallpaper)(text) 5 | const img = res[Math.floor(Math.random() * res.length)] 6 | conn.sendFile(m.chat, img, 'wallpaper.jpg', `Result from *${text}*`, m) 7 | } 8 | handler.help = ['', '2'].map(v => 'wallpaper' + v + ' ') 9 | handler.tags = ['downloader'] 10 | 11 | handler.command = /^(wallpaper2?)$/i 12 | 13 | export default handler -------------------------------------------------------------------------------- /plugins/info-grouplist.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn }) => { 2 | let txt = '' 3 | for (let [jid, chat] of Object.entries(conn.chats).filter(([jid, chat]) => jid.endsWith('@g.us') && chat.isChats)) txt += `${await conn.getName(jid)}\n🪪${jid} [${chat?.metadata?.read_only ? 'Left' : 'Joined'}]\n\n` 4 | m.reply(`List Groups: 5 | ${txt} 6 | `.trim()) 7 | } 8 | handler.help = ['groups', 'grouplist'] 9 | handler.tags = ['info'] 10 | handler.command = /^(group(s|list))$/i 11 | 12 | export default handler -------------------------------------------------------------------------------- /plugins/internet-fetch.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | import { format } from 'util' 3 | let handler = async (m, { text }) => { 4 | if (!/^https?:\/\//.test(text)) throw 'Awali *URL* dengan http:// atau https://' 5 | let _url = new URL(text) 6 | let url = global.API(_url.origin, _url.pathname, Object.fromEntries(_url.searchParams.entries()), 'APIKEY') 7 | let res = await fetch(url) 8 | if (res.headers.get('content-length') > 100 * 1024 * 1024 * 1024) { 9 | // delete res 10 | throw `Content-Length: ${res.headers.get('content-length')}` 11 | } 12 | if (!/text|json/.test(res.headers.get('content-type'))) return conn.sendFile(m.chat, url, 'file', text, m) 13 | let txt = await res.buffer() 14 | try { 15 | txt = format(JSON.parse(txt + '')) 16 | } catch (e) { 17 | txt = txt + '' 18 | } finally { 19 | m.reply(txt.slice(0, 65536) + '') 20 | } 21 | } 22 | handler.help = ['fetch', 'get'].map(v => v + ' ') 23 | handler.tags = ['internet'] 24 | handler.command = /^(fetch|get)$/i 25 | 26 | export default handler -------------------------------------------------------------------------------- /plugins/internet-kbbi.js: -------------------------------------------------------------------------------- 1 | import { kbbi } from '@bochilteam/scraper' 2 | 3 | let handler = async (m, { text, usedPrefix, command }) => { 4 | if (!text) throw `Example use ${usedPrefix}${command} halo` 5 | const res = await kbbi(text) 6 | m.reply(` 7 | ${res.map(v => ` 8 | *📌${v.title}* 9 | 10 | ${v.means.map(v => '- ' + v).join('\n`')} 11 | `).join('\n').trim()} 12 | 13 | Note: 14 | p = Partikel: kelas kata yang meliputi kata depan, kata sambung, kata seru, kata sandang, ucapan salam 15 | n = Nomina: kata benda 16 | `.trim()) 17 | } 18 | handler.help = ['kbbi '] 19 | handler.tags = ['internet'] 20 | handler.command = /^kbbi$/i 21 | 22 | export default handler -------------------------------------------------------------------------------- /plugins/internet-lewd.js: -------------------------------------------------------------------------------- 1 | // lewd 2 | import fetch from 'node-fetch' 3 | 4 | let handler = async(m, { conn }) => { 5 | let img = await fetch(`https://storage.caliph71.xyz/img/lewd/${gr()+'.png'}`).then(a => a.buffer()) 6 | await conn.sendFile(m.chat, img, 'lewn.png', '', m) 7 | } 8 | handler.help = ['lewd'] 9 | handler.tags = ['internet'] 10 | handler.command = /^lewd$/i 11 | export default handler 12 | function gr() { 13 | return Math.floor(Math.random() * 400) + 10; 14 | } 15 | -------------------------------------------------------------------------------- /plugins/jadwalsholat.js: -------------------------------------------------------------------------------- 1 | import { jadwalsholat } from '@bochilteam/scraper' 2 | let handler = async (m, { text, usedPrefix, command }) => { 3 | if (!text) throw `Use example ${usedPrefix}${command} semarang` 4 | const res = await jadwalsholat(text) 5 | m.reply(` 6 | Jadwal Sholat *${text}* 7 | 8 | ${Object.entries(res.today).map(([name, data]) => `*Sholat ${name}:* ${data}`).join('\n').trim()} 9 | `.trim()) 10 | } 11 | handler.help = ['salat '] 12 | handler.tags = ['quran'] 13 | handler.command = /^(jadwal)?s(a|o|ha|ho)lat$/i 14 | 15 | export default handler -------------------------------------------------------------------------------- /plugins/join.js: -------------------------------------------------------------------------------- 1 | let linkRegex = /chat.whatsapp.com\/([0-9A-Za-z]{20,24})( [0-9]{1,3})?/i 2 | 3 | let handler = async (m, { conn, text, isOwner }) => { 4 | let [_, code, expired] = text.match(linkRegex) || [] 5 | if (!code) throw 'Link invalid' 6 | let res = await conn.groupAcceptInvite(code) 7 | expired = Math.floor(Math.min(999, Math.max(1, isOwner ? isNumber(expired) ? parseInt(expired) : 0 : 3))) 8 | m.reply(`Berhasil join grup ${res}${expired ? ` selama ${expired} hari` : ''}`) 9 | let chats = global.db.data.chats[res] 10 | if (!chats) chats = global.db.data.chats[res] = {} 11 | if (expired) chats.expired = +new Date() + expired * 1000 * 60 * 60 * 24 12 | } 13 | handler.help = ['join '] 14 | handler.tags = ['premium'] 15 | handler.owner = true 16 | handler.command = /^join$/i 17 | handler.owner = true 18 | export default handler 19 | 20 | const isNumber = (x) => (x = parseInt(x), typeof x === 'number' && !isNaN(x)) 21 | -------------------------------------------------------------------------------- /plugins/levelup.js: -------------------------------------------------------------------------------- 1 | import { canLevelUp, xpRange } from '../lib/levelling.js' 2 | import { levelup } from '../lib/canvas.js' 3 | 4 | let handler = async (m, { conn }) => { 5 | let user = global.db.data.users[m.sender] 6 | if (!canLevelUp(user.level, user.exp, global.multiplier)) { 7 | let { min, xp, max } = xpRange(user.level, global.multiplier) 8 | throw ` 9 | Level *${user.level} (${user.exp - min}/${xp})* 10 | Kurang *${max - user.exp}* lagi! 11 | `.trim() 12 | } 13 | let before = user.level * 1 14 | while (canLevelUp(user.level, user.exp, global.multiplier)) user.level++ 15 | if (before !== user.level) { 16 | let teks = `Selamat ${conn.getName(m.sender)} naik 🧬level` 17 | let str = ` 18 | ${teks} 19 | • 🧬Level Sebelumnya : ${before} 20 | • 🧬Level Baru : ${user.level} 21 | • Pada Jam : ${new Date().toLocaleString('id-ID')} 22 | *_Semakin sering berinteraksi dengan bot Semakin Tinggi level kamu_* 23 | `.trim() 24 | try { 25 | const img = await levelup(teks, user.level) 26 | conn.sendFile(m.chat, img, 'levelup.jpg', str, m) 27 | } catch (e) { 28 | m.reply(str) 29 | } 30 | } 31 | } 32 | 33 | handler.help = ['levelup'] 34 | handler.tags = ['xp'] 35 | 36 | handler.command = /^level(|up)$/i 37 | 38 | export default handler -------------------------------------------------------------------------------- /plugins/lyrics.js: -------------------------------------------------------------------------------- 1 | import { lyrics, lyricsv2 } from '@bochilteam/scraper' 2 | 3 | let handler = async (m, { conn, text, usedPrefix, command }) => { 4 | let teks = text ? text : m.quoted && m.quoted.text ? m.quoted.text : '' 5 | if (!teks) throw `Use example ${usedPrefix}${command} hallo` 6 | const result = await lyricsv2(teks).catch(async _ => await lyrics(teks)) 7 | m.reply(` 8 | Lyrics *${result.title}* 9 | Author ${result.author} 10 | 11 | 12 | ${result.lyrics} 13 | 14 | 15 | Url ${result.link} 16 | `.trim()) 17 | } 18 | 19 | handler.help = ['lirik'].map(v => v + ' ') 20 | handler.tags = ['internet'] 21 | handler.command = /^(lirik|lyrics|lyric)$/i 22 | 23 | export default handler -------------------------------------------------------------------------------- /plugins/nulis-nulis.js: -------------------------------------------------------------------------------- 1 | import { format } from 'util' 2 | // let path = require('path') 3 | import { spawn } from 'child_process' 4 | 5 | // Font By MFarelS:V 6 | let fontPath = 'src/font/Zahraaa.ttf' 7 | let handler = async (m, { conn, args }) => { 8 | if (!global.support.convert && 9 | !global.support.magick && 10 | !global.support.gm) return handler.disabled = true // Disable if doesnt support 11 | let inputPath = 'src/kertas/magernulis1.jpg' 12 | let d = new Date() 13 | let tgl = d.toLocaleDateString('id-Id') 14 | let hari = d.toLocaleDateString('id-Id', { weekday: 'long' }) 15 | let teks = args.join` ` 16 | // conn.reply(m.chat, util.format({fontPath, inputPath, outputPath, tgl, hari, teks}), m) 17 | let bufs = [] 18 | const [_spawnprocess, ..._spawnargs] = [...(global.support.gm ? ['gm'] : global.support.magick ? ['magick'] : []), 19 | 'convert', 20 | inputPath, 21 | '-font', 22 | fontPath, 23 | '-size', 24 | '1024x784', 25 | '-pointsize', 26 | '20', 27 | '-interline-spacing', 28 | '1', 29 | '-annotate', 30 | '+806+78', 31 | hari, 32 | '-font', 33 | fontPath, 34 | '-size', 35 | '1024x784', 36 | '-pointsize', 37 | '18', 38 | '-interline-spacing', 39 | '1', 40 | '-annotate', 41 | '+806+102', 42 | tgl, 43 | '-font', 44 | fontPath, 45 | '-size', 46 | '1024x784', 47 | '-pointsize', 48 | '20', 49 | '-interline-spacing', 50 | '-7.5', 51 | '-annotate', 52 | '+344+142', 53 | teks, 54 | 'jpg:-' 55 | ] 56 | spawn(_spawnprocess, _spawnargs) 57 | .on('error', e => m.reply(format(e))) 58 | .on('close', () => { 59 | conn.sendFile(m.chat, Buffer.concat(bufs), 'nulis.jpg', 'Hati² ketahuan:v', m) 60 | }) 61 | .stdout.on('data', chunk => bufs.push(chunk)) 62 | } 63 | handler.help = ['n'].map(v => v + 'ulis ') 64 | handler.tags = ['nulis'] 65 | handler.command = /^nulis$/i 66 | 67 | 68 | export default handler 69 | 70 | // BY MFARELS NJEENK 71 | // https://GitHub.com/MFarelS/ -------------------------------------------------------------------------------- /plugins/nulis-nulis2.js: -------------------------------------------------------------------------------- 1 | import { format } from 'util' 2 | // let path = require('path') 3 | import { spawn } from 'child_process' 4 | 5 | // Font By MFarelS:V 6 | let fontPath = 'src/font/Zahraaa.ttf' 7 | let handler = async (m, { conn, args }) => { 8 | if (!global.support.convert && 9 | !global.support.magick && 10 | !global.support.gm) return handler.disabled = true // Disable if doesnt support 11 | let inputPath = 'src/kertas/magernulis1.jpg' 12 | let d = new Date 13 | let tgl = d.toLocaleDateString('id-Id') 14 | let hari = d.toLocaleDateString('id-Id', { weekday: 'long' }) 15 | let teks = args.join` ` 16 | // conn.reply(m.chat, util.format({fontPath, inputPath, outputPath, tgl, hari, teks}), m) 17 | let bufs = [] 18 | const [_spawnprocess, ..._spawnargs] = [...(global.support.gm ? ['gm'] : global.support.magick ? ['magick'] : []), 19 | 'convert', 20 | inputPath, 21 | '-font', 22 | fontPath, 23 | '-fill', 24 | 'blue', 25 | '-size', 26 | '1024x784', 27 | '-pointsize', 28 | '20', 29 | '-interline-spacing', 30 | '1', 31 | '-annotate', 32 | '+806+78', 33 | hari, 34 | '-font', 35 | fontPath, 36 | '-fill', 37 | 'blue', 38 | '-size', 39 | '1024x784', 40 | '-pointsize', 41 | '18', 42 | '-interline-spacing', 43 | '1', 44 | '-annotate', 45 | '+806+102', 46 | tgl, 47 | '-font', 48 | fontPath, 49 | '-fill', 50 | 'blue', 51 | '-size', 52 | '1024x784', 53 | '-pointsize', 54 | '20', 55 | '-interline-spacing', 56 | '-7.5', 57 | '-annotate', 58 | '+344+142', 59 | teks, 60 | 'jpg:-' 61 | ] 62 | spawn(_spawnprocess, _spawnargs) 63 | .on('error', e => m.reply(format(e))) 64 | .on('close', () => { 65 | conn.sendFile(m.chat, Buffer.concat(bufs), 'nulis.jpg', 'Hati² ketahuan:v', m) 66 | }) 67 | .stdout.on('data', chunk => bufs.push(chunk)) 68 | } 69 | handler.help = ['n'].map(v => v + 'ulis2 ') 70 | handler.tags = ['tools'] 71 | handler.command = /^nulis2$/i 72 | 73 | export default handler 74 | 75 | // BY MFARELS 76 | // https://GitHub.com/MFarelS/ -------------------------------------------------------------------------------- /plugins/nulis.js: -------------------------------------------------------------------------------- 1 | import { format } from 'util' 2 | // let path = require('path') 3 | import { spawn } from 'child_process' 4 | 5 | // Font By MFarelS:V 6 | let fontPath = 'src/font/Zahraaa.ttf' 7 | let handler = async (m, { conn, args }) => { 8 | if (!global.support.convert && 9 | !global.support.magick && 10 | !global.support.gm) return handler.disabled = true // Disable if doesnt support 11 | let inputPath = 'src/kertas/magernulis1.jpg' 12 | let d = new Date() 13 | let tgl = d.toLocaleDateString('id-Id') 14 | let hari = d.toLocaleDateString('id-Id', { weekday: 'long' }) 15 | let teks = args.join` ` 16 | // conn.reply(m.chat, util.format({fontPath, inputPath, outputPath, tgl, hari, teks}), m) 17 | let bufs = [] 18 | const [_spawnprocess, ..._spawnargs] = [...(global.support.gm ? ['gm'] : global.support.magick ? ['magick'] : []), 19 | 'convert', 20 | inputPath, 21 | '-font', 22 | fontPath, 23 | '-size', 24 | '1024x784', 25 | '-pointsize', 26 | '20', 27 | '-interline-spacing', 28 | '1', 29 | '-annotate', 30 | '+806+78', 31 | hari, 32 | '-font', 33 | fontPath, 34 | '-size', 35 | '1024x784', 36 | '-pointsize', 37 | '18', 38 | '-interline-spacing', 39 | '1', 40 | '-annotate', 41 | '+806+102', 42 | tgl, 43 | '-font', 44 | fontPath, 45 | '-size', 46 | '1024x784', 47 | '-pointsize', 48 | '20', 49 | '-interline-spacing', 50 | '-7.5', 51 | '-annotate', 52 | '+344+142', 53 | teks, 54 | 'jpg:-' 55 | ] 56 | spawn(_spawnprocess, _spawnargs) 57 | .on('error', e => m.reply(format(e))) 58 | .on('close', () => { 59 | conn.sendFile(m.chat, Buffer.concat(bufs), 'nulis.jpg', 'Hati² ketahuan:v', m) 60 | }) 61 | .stdout.on('data', chunk => bufs.push(chunk)) 62 | } 63 | handler.help = ['n'].map(v => v + 'ulis ') 64 | handler.tags = ['nulis'] 65 | handler.command = /^nulis$/i 66 | 67 | 68 | export default handler 69 | 70 | // BY MFARELS NJEENK 71 | // https://GitHub.com/MFarelS/ -------------------------------------------------------------------------------- /plugins/nulis2.js: -------------------------------------------------------------------------------- 1 | import { format } from 'util' 2 | // let path = require('path') 3 | import { spawn } from 'child_process' 4 | 5 | // Font By MFarelS:V 6 | let fontPath = 'src/font/Zahraaa.ttf' 7 | let handler = async (m, { conn, args }) => { 8 | if (!global.support.convert && 9 | !global.support.magick && 10 | !global.support.gm) return handler.disabled = true // Disable if doesnt support 11 | let inputPath = 'src/kertas/magernulis1.jpg' 12 | let d = new Date 13 | let tgl = d.toLocaleDateString('id-Id') 14 | let hari = d.toLocaleDateString('id-Id', { weekday: 'long' }) 15 | let teks = args.join` ` 16 | // conn.reply(m.chat, util.format({fontPath, inputPath, outputPath, tgl, hari, teks}), m) 17 | let bufs = [] 18 | const [_spawnprocess, ..._spawnargs] = [...(global.support.gm ? ['gm'] : global.support.magick ? ['magick'] : []), 19 | 'convert', 20 | inputPath, 21 | '-font', 22 | fontPath, 23 | '-fill', 24 | 'blue', 25 | '-size', 26 | '1024x784', 27 | '-pointsize', 28 | '20', 29 | '-interline-spacing', 30 | '1', 31 | '-annotate', 32 | '+806+78', 33 | hari, 34 | '-font', 35 | fontPath, 36 | '-fill', 37 | 'blue', 38 | '-size', 39 | '1024x784', 40 | '-pointsize', 41 | '18', 42 | '-interline-spacing', 43 | '1', 44 | '-annotate', 45 | '+806+102', 46 | tgl, 47 | '-font', 48 | fontPath, 49 | '-fill', 50 | 'blue', 51 | '-size', 52 | '1024x784', 53 | '-pointsize', 54 | '20', 55 | '-interline-spacing', 56 | '-7.5', 57 | '-annotate', 58 | '+344+142', 59 | teks, 60 | 'jpg:-' 61 | ] 62 | spawn(_spawnprocess, _spawnargs) 63 | .on('error', e => m.reply(format(e))) 64 | .on('close', () => { 65 | conn.sendFile(m.chat, Buffer.concat(bufs), 'nulis.jpg', 'Hati² ketahuan:v', m) 66 | }) 67 | .stdout.on('data', chunk => bufs.push(chunk)) 68 | } 69 | handler.help = ['n'].map(v => v + 'ulis2 ') 70 | handler.tags = ['tools'] 71 | handler.command = /^nulis2$/i 72 | 73 | export default handler 74 | 75 | // BY MFARELS 76 | // https://GitHub.com/MFarelS/ -------------------------------------------------------------------------------- /plugins/owner-add.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | /** 3 | * @type {import('@adiwajshing/baileys')} 4 | */ 5 | const { getBinaryNodeChild, getBinaryNodeChildren } = (await import('@adiwajshing/baileys')).default 6 | let handler = async (m, { conn, text, participants }) => { 7 | let _participants = participants.map(user => user.id) 8 | let users = (await Promise.all( 9 | text.split(',') 10 | .map(v => v.replace(/[^0-9]/g, '')) 11 | .filter(v => v.length > 4 && v.length < 20 && !_participants.includes(v + '@s.whatsapp.net')) 12 | .map(async v => [ 13 | v, 14 | await conn.onWhatsApp(v + '@s.whatsapp.net') 15 | ]) 16 | )).filter(v => v[1][0]?.exists).map(v => v[0] + '@c.us') 17 | const response = await conn.query({ 18 | tag: 'iq', 19 | attrs: { 20 | type: 'set', 21 | xmlns: 'w:g2', 22 | to: m.chat, 23 | }, 24 | content: users.map(jid => ({ 25 | tag: 'add', 26 | attrs: {}, 27 | content: [{ tag: 'participant', attrs: { jid } }] 28 | })) 29 | }) 30 | const pp = await conn.profilePictureUrl(m.chat).catch(_ => null) 31 | const jpegThumbnail = pp ? await (await fetch(pp)).buffer() : Buffer.alloc(0) 32 | const add = getBinaryNodeChild(response, 'add') 33 | const participant = getBinaryNodeChildren(add, 'participant') 34 | for (const user of participant.filter(item => item.attrs.error == 403)) { 35 | const jid = user.attrs.jid 36 | const content = getBinaryNodeChild(user, 'add_request') 37 | const invite_code = content.attrs.code 38 | const invite_code_exp = content.attrs.expiration 39 | let teks = `Mengundang @${jid.split('@')[0]} menggunakan invite...` 40 | m.reply(teks, null, { 41 | mentions: conn.parseMention(teks) 42 | }) 43 | await conn.sendGroupV4Invite(m.chat, jid, invite_code, invite_code_exp, await conn.getName(m.chat), 'Invitation to join my WhatsApp group', jpegThumbnail) 44 | } 45 | } 46 | handler.help = ['add', '+'].map(v => 'o' + v + ' @user') 47 | handler.tags = ['owner'] 48 | handler.command = /^(oadd|o\+)$/i 49 | 50 | handler.owner = true 51 | handler.group = true 52 | handler.botAdmin = true 53 | 54 | 55 | export default handler 56 | 57 | -------------------------------------------------------------------------------- /plugins/owner-addprem.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, text, usedPrefix, command }) => { 2 | let who 3 | if (m.isGroup) who = m.mentionedJid[0] ? m.mentionedJid[0] : m.quoted ? m.quoted.sender : false 4 | else who = m.chat 5 | let user = db.data.users[who] 6 | if (!who) throw `tag or mention someone!` 7 | let txt = text.replace('@' + who.split`@`[0], '').trim() 8 | if (!txt) throw `where the number of days?` 9 | if (isNaN(txt)) return m.reply(`only number!\n\nexample:\n${usedPrefix + command} @${m.sender.split`@`[0]} 7`) 10 | var jumlahHari = 86400000 * txt 11 | var now = new Date() * 1 12 | if (now < user.premiumTime) user.premiumTime += jumlahHari 13 | else user.premiumTime = now + jumlahHari 14 | user.premium = true 15 | m.reply(`✔️ Success 16 | 📛 *Name:* ${user.name} 17 | 📆 *Days:* ${txt} days 18 | 📉 *Countdown:* ${user.premiumTime - now}`) 19 | } 20 | handler.help = ['addprem [@user] '] 21 | handler.tags = ['owner'] 22 | handler.command = /^(add|tambah|\+)p(rem)?$/i 23 | 24 | handler.group = true 25 | handler.rowner = true 26 | 27 | export default handler -------------------------------------------------------------------------------- /plugins/owner-banchat.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { participants }) => { 2 | // if (participants.map(v=>v.jid).includes(global.conn.user.jid)) { 3 | global.db.data.chats[m.chat].isBanned = true 4 | m.reply('Done!') 5 | // } else m.reply('Ada nomor host disini...') 6 | } 7 | handler.help = ['banchat'] 8 | handler.tags = ['owner'] 9 | handler.command = /^banchat$/i 10 | 11 | handler.owner = true 12 | 13 | export default handler -------------------------------------------------------------------------------- /plugins/owner-delprem.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { usedPrefix, command, text }) => { 2 | let who 3 | if (m.isGroup) who = m.mentionedJid[0] ? m.mentionedJid[0] : m.quoted ? m.quoted.sender : text ? text.replace(/[^0-9]/g, '') + '@s.whatsapp.net' : false 4 | else who = text ? text.replace(/[^0-9]/g, '') + '@s.whatsapp.net' : m.chat 5 | let user = db.data.users[who] 6 | if (!who) return m.reply(`tag or mention someone!\n\nexample:\n${usedPrefix + command} @${m.sender.split`@`[0]}`) 7 | user.premium = false 8 | user.premiumTime = 0 9 | m.reply(`✔️ successfully removed *${user.name}* from premium user`) 10 | } 11 | handler.help = ['delprem [@user]'] 12 | handler.tags = ['owner'] 13 | handler.command = /^(-|del)p(rem)?$/i 14 | 15 | handler.group = true 16 | handler.rowner = true 17 | 18 | export default handler -------------------------------------------------------------------------------- /plugins/owner-exec.js: -------------------------------------------------------------------------------- 1 | import syntaxerror from 'syntax-error' 2 | import { format } from 'util' 3 | import { fileURLToPath } from 'url' 4 | import { dirname } from 'path' 5 | import { createRequire } from 'module' 6 | 7 | const __dirname = dirname(fileURLToPath(import.meta.url)) 8 | const require = createRequire(__dirname) 9 | 10 | let handler = async (m, _2) => { 11 | let { conn, usedPrefix, noPrefix, args, groupMetadata } = _2 12 | let _return 13 | let _syntax = '' 14 | let _text = (/^=/.test(usedPrefix) ? 'return ' : '') + noPrefix 15 | let old = m.exp * 1 16 | try { 17 | let i = 15 18 | let f = { 19 | exports: {} 20 | } 21 | let exec = new (async () => { }).constructor('print', 'm', 'handler', 'require', 'conn', 'Array', 'process', 'args', 'groupMetadata', 'module', 'exports', 'argument', _text) 22 | _return = await exec.call(conn, (...args) => { 23 | if (--i < 1) return 24 | console.log(...args) 25 | return conn.reply(m.chat, format(...args), m) 26 | }, m, handler, require, conn, CustomArray, process, args, groupMetadata, f, f.exports, [conn, _2]) 27 | } catch (e) { 28 | let err = syntaxerror(_text, 'Execution Function', { 29 | allowReturnOutsideFunction: true, 30 | allowAwaitOutsideFunction: true, 31 | sourceType: 'module' 32 | }) 33 | if (err) _syntax = '```' + err + '```\n\n' 34 | _return = e 35 | } finally { 36 | conn.reply(m.chat, _syntax + format(_return), m) 37 | m.exp = old 38 | } 39 | } 40 | handler.help = ['> ', '=> '] 41 | handler.tags = ['advanced'] 42 | handler.customPrefix = /^=?> / 43 | handler.command = /(?:)/i 44 | 45 | handler.rowner = true 46 | 47 | export default handler 48 | 49 | class CustomArray extends Array { 50 | constructor(...args) { 51 | if (typeof args[0] == 'number') return super(Math.min(args[0], 10000)) 52 | else return super(...args) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /plugins/owner-exec2.js: -------------------------------------------------------------------------------- 1 | import cp, { exec as _exec } from 'child_process' 2 | import { promisify } from 'util' 3 | let exec = promisify(_exec).bind(cp) 4 | let handler = async (m, { conn, isOwner, command, text }) => { 5 | if (global.conn.user.jid != conn.user.jid) return 6 | m.reply('Executing...') 7 | let o 8 | try { 9 | o = await exec(command.trimStart() + ' ' + text.trimEnd()) 10 | } catch (e) { 11 | o = e 12 | } finally { 13 | let { stdout, stderr } = o 14 | if (stdout.trim()) m.reply(stdout) 15 | if (stderr.trim()) m.reply(stderr) 16 | } 17 | } 18 | handler.customPrefix = /^[$] / 19 | handler.command = new RegExp 20 | handler.rowner = true 21 | export default handler 22 | -------------------------------------------------------------------------------- /plugins/owner-getdb.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | let handler = async (m, { conn, text }) => { 3 | m.reply('Tunggu Sebentar, Proses Getting File database.json') 4 | let databasenya = await fs.readFileSync('./database.json') 5 | return await conn.sendMessage(m.chat, { document: databasenya, mimetype: 'application/json', fileName: 'database.json' }, { quoted: m }) 6 | } 7 | handler.help = ['getdb'] 8 | handler.tags = ['host'] 9 | handler.command = /^(getdb)$/i 10 | 11 | handler.rowner = true 12 | 13 | export default handler 14 | -------------------------------------------------------------------------------- /plugins/owner-getsesi.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | let handler = async (m, { conn, text }) => { 3 | m.reply('Tunggu Sebentar, Proses Getting File session.data.json') 4 | let sesi = await fs.readFileSync('./session.data.json') 5 | return await conn.sendMessage(m.chat, { document: sesi, mimetype: 'application/json', fileName: 'session.data.json' }, { quoted: m }) 6 | } 7 | handler.help = ['getsessi'] 8 | handler.tags = ['host'] 9 | handler.command = /^(g(et)?ses?si(on)?(data.json)?)$/i 10 | 11 | handler.rowner = true 12 | 13 | export default handler -------------------------------------------------------------------------------- /plugins/owner-order.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, text, usedPrefix, command }) => { 2 | if (!text) throw `kalo kamu nemu pesan eror, lapor pake perintah ini\n\ncontoh:\n${usedPrefix + command} selamat siang owner, sy menemukan eror seperti berikut ` 3 | if (text.length < 1 ) throw `Laporan terlalu pendek, minimal 10 karakter!` 4 | if (text.length > 1000) throw `Laporan terlalu panjang, maksimal 1000 karakter!` 5 | let teks = `${command.toUpperCase()}\n📮 : ${text}\n*wa.me/${m.sender.split`@`[0]}*` 6 | conn.reply(global.ownernumber + '@s.whatsapp.net', m.quoted ? teks + m.quoted.text : teks, null, { 7 | contextInfo: { 8 | mentionedJid: [m.sender] 9 | } 10 | }) 11 | m.reply('☑️ Pesan Telah terkirim ke Owner!\n_*Menunggu confirmasi Dari Owner...*_') 12 | } 13 | handler.command = /^(say)$/i 14 | export default handler 15 | 16 | -------------------------------------------------------------------------------- /plugins/owner-setbio.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, text }) => { 2 | if (!text) throw `Penggunaan:\n${usedPrefix + command} \n\nContoh:\n${usedPrefix + command} tes` 3 | try { 4 | await conn.setStatus(text) 5 | m.reply('Berhasil!') 6 | } catch (e) { 7 | console.log(e) 8 | throw `Eror` 9 | } 10 | } 11 | handler.help = ['setbotbio '] 12 | handler.tags = ['owner'] 13 | handler.command = /^(setbotbio)$/i 14 | 15 | handler.owner = true 16 | 17 | export default handler -------------------------------------------------------------------------------- /plugins/owner-setppbot.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, args }) => { 2 | let bot = conn.user.jid 3 | let q = m.quoted ? m.quoted : m 4 | let mime = (q.msg || q).mimetype || '' 5 | if (/image/.test(mime)) { 6 | let img = await q.download() 7 | if (!img) throw `Foto tidak ditemukan` 8 | conn.updateProfilePicture(bot, img) 9 | conn.fakeReply(m.chat, `SUKSES MENGANTI FOTO PROFILE`, '0@s.whatsapp.net', 'PHOTO PROFILE UPDATE') 10 | } 11 | } 12 | handler.help = ['setpp'] 13 | handler.tags = ['owner'] 14 | handler.command = /^setpp$/i 15 | 16 | handler.rowner = true 17 | export default handler 18 | -------------------------------------------------------------------------------- /plugins/owner-unbanchat.js: -------------------------------------------------------------------------------- 1 | let handler = async (m) => { 2 | global.db.data.chats[m.chat].isBanned = false 3 | m.reply('Done!') 4 | } 5 | handler.help = ['unbanchat'] 6 | handler.tags = ['owner'] 7 | handler.command = /^unbanchat$/i 8 | handler.owner = true 9 | 10 | export default handler -------------------------------------------------------------------------------- /plugins/photo-canvas.js: -------------------------------------------------------------------------------- 1 | 2 | import fetch from 'node-fetch' 3 | import uploadImage from '../lib/uploadImage.js' 4 | 5 | 6 | let handler = async (m, { conn, command, usedPrefix}) => { 7 | if (command == 'komunis') command = 'comrade' 8 | let q = m.quoted ? m.quoted : m 9 | let mime = (q.msg || q).mimetype || q.mediaType || '' 10 | if (!mime) throw `Reply Foto/Kirim foto dengan caption *${usedPrefix + command}*` 11 | if (!/image\/(jpe?g|png)/.test(mime)) throw `Mime ${mime} tidak support` 12 | try { 13 | let msg = await conn.fakeReply(m.chat, `Proses Kak...`, '0@s.whatsapp.net', command) 14 | let img = await q.download?.() 15 | let upld = await uploadImage(img) 16 | let res = await fetch(`https://some-random-api.ml/canvas/${command}?avatar=${upld}`) 17 | let fii = await res.buffer() 18 | conn.sendFile(m.chat, fii, '', 'Sudah jadi kak ```>_<```', m) 19 | await conn.sendMessage(m.chat, { delete: msg.key }) 20 | } catch (err) { 21 | let msg = await conn.fakeReply(m.chat, `*ERROR !*`, '0@s.whatsapp.net', command) 22 | } 23 | } 24 | handler.help = ['wasted', 'glass', 'gay', 'passed', 'jail', 'comrade / komunis', 'pixelate', 'blur', 'greyscale', 'invert', 'brightness', 'threshold', 'sepia', 'red'] 25 | handler.tags = ['canvas'] 26 | handler.command = /^wasted|glaass|gay|passed|jail|comrade|komunis|pixelate|blur|greyscale|invert|brightness|threshold|sepia|red$/i 27 | export default handler 28 | 29 | -------------------------------------------------------------------------------- /plugins/premium.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, usedPrefix }) => conn.sendButton(m.chat, `“Silahkan chat owner”`, author, ['ඩOwner', `${usedPrefix}owner`], m) 2 | 3 | handler.help = ['premium'] 4 | handler.tags = ['quotes'] 5 | handler.command = /^(premium)$/i 6 | 7 | export default handler 8 | -------------------------------------------------------------------------------- /plugins/quotes-dare.js: -------------------------------------------------------------------------------- 1 | import { dare } from '@bochilteam/scraper' 2 | 3 | let handler = async (m, { conn, usedPrefix }) => conn.sendButton(m.chat, await dare(), author, [ 4 | ['Dare', `${usedPrefix}dare`], 5 | ['Truth', `${usedPrefix}truth`] 6 | ], m) 7 | 8 | handler.help = ['dare'] 9 | handler.tags = ['quotes', 'fun'] 10 | handler.command = /^(dare)$/i 11 | 12 | export default handler 13 | -------------------------------------------------------------------------------- /plugins/quotes-truth.js: -------------------------------------------------------------------------------- 1 | import { truth } from '@bochilteam/scraper' 2 | 3 | let handler = async (m, { conn, usedPrefix }) => conn.sendButton(m.chat, await truth(), author, [ 4 | ['Truth', `${usedPrefix}truth`], 5 | ['Dare', `${usedPrefix}dare`] 6 | ], m) 7 | 8 | handler.help = ['truth'] 9 | handler.tags = ['quotes', 'fun'] 10 | handler.command = /^(truth)$/i 11 | 12 | export default handler -------------------------------------------------------------------------------- /plugins/rpg-daily.js: -------------------------------------------------------------------------------- 1 | const rewards = { 2 | exp: 9999, 3 | money: 4999, 4 | potion: 5, 5 | } 6 | const cooldown = 86400000 7 | let handler = async (m,{ conn} ) => { 8 | let user = global.db.data.users[m.sender] 9 | if (new Date - user.lastclaim < cooldown) throw `You have already claimed this daily claim!, wait for *${((user.lastclaim + cooldown) - new Date()).toTimeString()}*` 10 | let text = '' 11 | for (let reward of Object.keys(rewards)) { 12 | if (!(reward in user)) continue 13 | user[reward] += rewards[reward] 14 | text += `*+${rewards[reward]}* ${global.rpg.emoticon(reward)}${reward}\n` 15 | } 16 | conn.sendButton(m.chat,'*––––––『 DAILY 』––––––*', text.trim(), null, [['Inventory', '.inv'], ['Weekly', '.weekly']],m) 17 | user.lastclaim = new Date * 1 18 | } 19 | handler.help = ['daily', 'claim'] 20 | handler.tags = ['xp'] 21 | handler.command = /^(daily|claim)$/i 22 | 23 | handler.cooldown = cooldown 24 | 25 | export default handler -------------------------------------------------------------------------------- /plugins/rpg-heal.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { args, usedPrefix }) => { 2 | let user = global.db.data.users[m.sender] 3 | if (user.health >= 100) return m.reply(` 4 | Your ❤️health is full! 5 | `.trim()) 6 | let buf = user.cat 7 | let buff = (buf == 0 ? '5' : '' || buf == 1 ? '10' : '' || buf == 2 ? '15' : '' || buf == 3 ? '20' : '' || buf == 4 ? '25' : '' || buf == 5 ? '30' : '' || buf == 6 ? '35' : '' || buf == 7 ? '40' : '' || buf == 8 ? '45' : '' || buf == 9 ? '50' : '' || buf == 10 ? '100' : '' || buf == 11 ? '100' : '') 8 | const heal = 15 + (buff * 4) 9 | let count = Math.max(1, Math.min(Number.MAX_SAFE_INTEGER, (isNumber(args[0]) && parseInt(args[0]) || Math.round((100 - user.health) / heal)))) * 1 10 | if (user.potion < count) return m.reply(` 11 | Your 🥤Potion is not enough, you only have *${user.potion}* 🥤Potion 12 | type *${usedPrefix}buy potion ${count - user.potion}* to buy 🥤Potion 13 | `.trim()) 14 | user.potion -= count * 1 15 | user.health += heal * count 16 | m.reply(` 17 | Successful use of *${count}* 🥤Potion(s) 18 | `.trim()) 19 | } 20 | 21 | handler.help = ['heal'] 22 | handler.tags = ['rpg'] 23 | handler.command = /^(heal)$/i 24 | 25 | export default handler 26 | 27 | function isNumber(number) { 28 | if (!number) return number 29 | number = parseInt(number) 30 | return typeof number == 'number' && !isNaN(number) 31 | } -------------------------------------------------------------------------------- /plugins/rpg-monthly.js: -------------------------------------------------------------------------------- 1 | const rewards = { 2 | exp: 50000, 3 | money: 49999, 4 | potion: 10, 5 | mythic: 3, 6 | legendary: 1 7 | } 8 | 9 | const cooldown = 2592000000 10 | let handler = async (m) => { 11 | let user = global.db.data.users[m.sender] 12 | if (new Date - user.lastmonthly < cooldown) throw `You have already claimed this monthly claim, wait for *${((user.lastmonthly + cooldown) - new Date()).toTimeString()}*` 13 | let text = '' 14 | for (let reward of Object.keys(rewards)) if (reward in user) { 15 | user[reward] += rewards[reward] 16 | text += `*+${rewards[reward]}* ${rpg.emoticon(reward)}${reward}\n` 17 | } 18 | conn.sendButton(m.chat,'*––––––『 MONTHLY 』––––––*', text.trim(), null, [['Inventory', '.inv'], ['Menu', '.menu']],m) 19 | user.lastmonthly = new Date * 1 20 | } 21 | handler.help = ['monthly'] 22 | handler.tags = ['rpg'] 23 | handler.command = /^(monthly)$/i 24 | 25 | handler.cooldown = cooldown 26 | 27 | export default handler -------------------------------------------------------------------------------- /plugins/rpg-weekly.js: -------------------------------------------------------------------------------- 1 | const rewards = { 2 | exp: 15000, 3 | money: 35999, 4 | potion: 9, 5 | } 6 | const cooldown = 604800000 7 | let handler = async (m) => { 8 | let user = global.db.data.users[m.sender] 9 | if (new Date - user.lastweekly < cooldown) throw `You have already claimed this daily claim!, wait for *${((user.lastweekly + cooldown) - new Date()).toTimeString()}*` 10 | let text = '' 11 | for (let reward of Object.keys(rewards)) { 12 | if (!(reward in user)) continue 13 | user[reward] += rewards[reward] 14 | text += `*+${rewards[reward]}* ${global.rpg.emoticon(reward)}${reward}\n` 15 | } 16 | conn.sendButton(m.chat,'*––––––『 WEEKLY 』––––––*', text.trim(), null, [['Inventory', '.inv'], ['Monthly', '.monthly']],m) 17 | user.lastweekly = new Date * 1 18 | } 19 | handler.help = ['weekly'] 20 | handler.tags = ['rpg'] 21 | handler.command = /^(weekly)$/i 22 | 23 | handler.cooldown = cooldown 24 | 25 | export default handler -------------------------------------------------------------------------------- /plugins/siegrin.js: -------------------------------------------------------------------------------- 1 | siegrin turu 2 | -------------------------------------------------------------------------------- /plugins/sticker-attp.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, text }) => { 2 | let teks = text ? text : m.quoted && m.quoted.text ? m.quoted.text : m.text 3 | conn.sendFile(m.chat, global.API('xteam', '/attp', { file: '', text: teks }), 'attp.webp', '', m, false, { asSticker: true }) 4 | } 5 | handler.help = ['attp '] 6 | handler.tags = ['sticker'] 7 | 8 | handler.command = /^attp$/i 9 | 10 | export default handler -------------------------------------------------------------------------------- /plugins/sticker-colong.js: -------------------------------------------------------------------------------- 1 | // 2 | let { MessageType } = (await import('@adiwajshing/baileys')).default 3 | import { sticker } from '../lib/sticker.js' 4 | let handler = async (m, { conn, args }) => { 5 | let stiker = false 6 | try { 7 | let q = m.quoted ? m.quoted : m 8 | let mime = (q.msg || q).mimetype || '' 9 | if (/image|video/.test(mime)) { 10 | let img = await q.download() 11 | if (!img) throw 'Reply stiker nya!' 12 | stiker = await sticker(img, false, '🍀', '🎮 • Discord :\n⤷ https://discord.gg/WEJQjugTY7') 13 | } else if (args[0]) stiker = await sticker(false, args[0], '🍀', '🎮 • Discord :\n⤷ https://discord.gg/WEJQjugTY7') 14 | } finally { 15 | if (stiker) conn.sendFile(m.chat, stiker, 'sticker.webp', '', m) 16 | else throw 'Conversion failed' 17 | } 18 | } 19 | handler.help = ['colong'] 20 | handler.tags = ['sticker'] 21 | handler.command = /^colong$/i 22 | handler.owner = true 23 | 24 | export default handler -------------------------------------------------------------------------------- /plugins/sticker-getexif.js: -------------------------------------------------------------------------------- 1 | import { format } from 'util' 2 | const { default: { Image } } = await import('node-webpmux') 3 | 4 | let handler = async (m) => { 5 | if (!m.quoted) return m.reply('Tag stikernya!') 6 | if (/sticker/.test(m.quoted.mtype)) { 7 | let img = new Image() 8 | await img.load(await m.quoted.download()) 9 | m.reply(format(JSON.parse(img.exif.slice(22).toString()))) 10 | } 11 | } 12 | handler.help = ['getexif'] 13 | handler.tags = ['sticker'] 14 | 15 | handler.command = ['getexif'] 16 | 17 | export default handler -------------------------------------------------------------------------------- /plugins/sticker-meme.js: -------------------------------------------------------------------------------- 1 | import uploadImage from '../lib/uploadImage.js' 2 | import { sticker } from '../lib/sticker.js' 3 | let handler = async (m, { conn, text, usedPrefix, command }) => { 4 | let [atas, bawah] = text.split`|` 5 | let q = m.quoted ? m.quoted : m 6 | let mime = (q.msg || q).mimetype || '' 7 | if (!mime) throw `balas gambar dengan perintah\n\n${usedPrefix + command} <${atas ? atas : 'teks atas'}>|<${bawah ? bawah : 'teks bawah'}>` 8 | if (!/image\/(jpe?g|png)/.test(mime)) throw `_*Mime ${mime} tidak didukung!*_` 9 | let img = await q.download() 10 | let url = await uploadImage(img) 11 | let meme = `https://api.memegen.link/images/custom/${encodeURIComponent(atas ? atas : '')}/${encodeURIComponent(bawah ? bawah : '')}.png?background=${url}` 12 | let stiker = await sticker(false, meme, global.packname, global.author) 13 | if (stiker) await conn.sendFile(m.chat, stiker, '', author, m, '', { asSticker: 1 }) 14 | } 15 | handler.help = ['smeme |'] 16 | handler.tags = ['sticker'] 17 | handler.command = /^(smeme)$/i 18 | 19 | handler.limit = true 20 | 21 | export default handler 22 | -------------------------------------------------------------------------------- /plugins/sticker-sticker.js: -------------------------------------------------------------------------------- 1 | import { sticker } from '../lib/sticker.js' 2 | import uploadFile from '../lib/uploadFile.js' 3 | import uploadImage from '../lib/uploadImage.js' 4 | import { webp2png } from '../lib/webp2mp4.js' 5 | 6 | let handler = async (m, { conn, args, usedPrefix, command }) => { 7 | let stiker = false 8 | try { 9 | let q = m.quoted ? m.quoted : m 10 | let mime = (q.msg || q).mimetype || q.mediaType || '' 11 | if (/webp|image|video/g.test(mime)) { 12 | if (/video/g.test(mime)) if ((q.msg || q).seconds > 11) return m.reply('Maksimal 10 detik!') 13 | let img = await q.download?.() 14 | if (!img) throw `balas gambar/video/stiker dengan perintah ${usedPrefix + command}` 15 | let out 16 | try { 17 | stiker = await sticker(img, false, global.packname, global.author) 18 | } catch (e) { 19 | console.error(e) 20 | } finally { 21 | if (!stiker) { 22 | if (/webp/g.test(mime)) out = await webp2png(img) 23 | else if (/image/g.test(mime)) out = await uploadImage(img) 24 | else if (/video/g.test(mime)) out = await uploadFile(img) 25 | if (typeof out !== 'string') out = await uploadImage(img) 26 | stiker = await sticker(false, out, global.packname, global.author) 27 | } 28 | } 29 | } else if (args[0]) { 30 | if (isUrl(args[0])) stiker = await sticker(false, args[0], global.packname, global.author) 31 | else return m.reply('URL tidak valid!') 32 | } 33 | } catch (e) { 34 | console.error(e) 35 | if (!stiker) stiker = e 36 | } finally { 37 | if (stiker) conn.sendFile(m.chat, stiker, 'sticker.webp', '', m) 38 | else throw 'Conversion failed' 39 | } 40 | } 41 | handler.help = ['stiker (caption|reply media)', 'stiker ', 'stikergif (caption|reply media)', 'stikergif '] 42 | handler.tags = ['sticker'] 43 | handler.command = /^s(tic?ker)?(gif)?(wm)?$/i 44 | 45 | export default handler 46 | 47 | const isUrl = (text) => { 48 | return text.match(new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)(jpe?g|gif|png)/, 'gi')) 49 | } 50 | -------------------------------------------------------------------------------- /plugins/sticker-stickerLLT.js: -------------------------------------------------------------------------------- 1 | import { sticker } from '../lib/sticker.js' 2 | import { stickerLine, stickerTelegram } from '@bochilteam/scraper' 3 | 4 | let handler = async (m, { conn, args, usedPrefix, command }) => { 5 | // TODO: add stickerly 6 | const isTele = /tele/i.test(command) 7 | if (!args[0]) throw `*Perintah ini untuk mengambil stiker dari ${isTele ? 'Tele' : 'Line'}*\n\nContoh penggunaan:\n${usedPrefix + command} spongebob` 8 | const json = await (isTele ? stickerTelegram : stickerLine)(args[0]) 9 | m.reply(` 10 | *Total stiker:* ${(json[0]?.stickers || json).length} 11 | `.trim()) 12 | for (let data of (json[0]?.stickers || json)) { 13 | const stiker = await sticker(false, data.sticker || data, global.packname, global.author) 14 | await conn.sendFile(m.chat, stiker, 'sticker.webp', '', m).catch(console.error) 15 | await delay(1500) 16 | } 17 | 18 | } 19 | handler.help = ['stikerline '] 20 | handler.tags = ['sticker'] 21 | handler.command = /^(stic?ker(line|tele(gram)?))$/i 22 | 23 | handler.limit = true 24 | 25 | export default handler 26 | 27 | const delay = time => new Promise(res => setTimeout(res, time)) -------------------------------------------------------------------------------- /plugins/sticker-toimg.js: -------------------------------------------------------------------------------- 1 | import { spawn } from 'child_process' 2 | import { format } from 'util' 3 | 4 | let handler = async (m, { conn, usedPrefix, command }) => { 5 | if (!global.support.convert && 6 | !global.support.magick && 7 | !global.support.gm) return handler.disabled = true // Disable if doesnt support 8 | const notStickerMessage = `Reply sticker with command *${usedPrefix + command}*` 9 | if (!m.quoted) throw notStickerMessage 10 | let q = m.quoted 11 | if (/sticker/.test(q.mediaType)) { 12 | let sticker = await q.download() 13 | if (!sticker) throw sticker 14 | let bufs = [] 15 | const [_spawnprocess, ..._spawnargs] = [...(global.support.gm ? ['gm'] : global.support.magick ? ['magick'] : []), 'convert', 'webp:-', 'png:-'] 16 | let im = spawn(_spawnprocess, _spawnargs) 17 | im.on('error', e => m.reply(format(e))) 18 | im.stdout.on('data', chunk => bufs.push(chunk)) 19 | im.stdin.write(sticker) 20 | im.stdin.end() 21 | im.on('exit', () => { 22 | conn.sendFile(m.chat, Buffer.concat(bufs), 'image.png', author, m) 23 | }) 24 | } else throw notStickerMessage 25 | } 26 | handler.help = ['toimg2 (reply)'] 27 | handler.tags = ['sticker'] 28 | handler.command = /^toimg2$/i 29 | 30 | export default handler 31 | -------------------------------------------------------------------------------- /plugins/sticker-toimg2.js: -------------------------------------------------------------------------------- 1 | import { webp2png } from '../lib/webp2mp4.js' 2 | let handler = async (m, { conn, usedPrefix, command }) => { 3 | const notStickerMessage = `Reply sticker with command *${usedPrefix + command}*` 4 | if (!m.quoted) throw notStickerMessage 5 | const q = m.quoted || m 6 | let mime = q.mediaType || '' 7 | if (!/sticker/.test(mime)) throw notStickerMessage 8 | let media = await q.download() 9 | let out = await webp2png(media).catch(_ => null) || Buffer.alloc(0) 10 | await conn.sendFile(m.chat, out, 'out.png', '*DONE*', m) 11 | } 12 | handler.help = ['toimg (reply)'] 13 | handler.tags = ['sticker'] 14 | handler.command = ['toimg'] 15 | 16 | export default handler 17 | -------------------------------------------------------------------------------- /plugins/sticker-tovideo.js: -------------------------------------------------------------------------------- 1 | import { webp2mp4 } from '../lib/webp2mp4.js' 2 | let handler = async (m, { conn, usedPrefix, command }) => { 3 | const notStickerMessage = `Reply sticker with command *${usedPrefix + command}*` 4 | if (!m.quoted) throw notStickerMessage 5 | const q = m.quoted || m 6 | let mime = q.mediaType || '' 7 | if (!/sticker/.test(mime)) throw notStickerMessage 8 | let media = await q.download() 9 | let out = await webp2mp4(media).catch(_ => null) || Buffer.alloc(0) 10 | await conn.sendFile(m.chat, out, 'out.mp4', '*DONE*', m) 11 | } 12 | handler.help = ['tovideo (reply)'] 13 | handler.tags = ['sticker'] 14 | handler.command = ['tovideo'] 15 | 16 | export default handler 17 | -------------------------------------------------------------------------------- /plugins/sticker-ttp.js: -------------------------------------------------------------------------------- 1 | import { sticker } from '../lib/sticker.js' 2 | 3 | let handler = async (m, { conn, text }) => { 4 | let teks = text ? text : m.quoted && m.quoted.text ? m.quoted.text : m.text 5 | let stiker = await sticker(null, global.API('xteam', '/ttp', { file: '', text: teks }), global.packname, global.author) 6 | if (stiker) return conn.sendFile(m.chat, stiker, 'sticker.webp', '', m) 7 | throw stiker.toString() 8 | } 9 | handler.help = ['ttp '] 10 | handler.tags = ['sticker'] 11 | 12 | handler.command = /^ttp$/i 13 | 14 | export default handler -------------------------------------------------------------------------------- /plugins/sticker-wm.js: -------------------------------------------------------------------------------- 1 | import { addExif } from '../lib/sticker.js' 2 | 3 | 4 | let handler = async (m, { conn, text }) => { 5 | if (!m.quoted) throw 'Quoted the sticker!' 6 | let stiker = false 7 | try { 8 | let [packname, ...author] = text.split('|') 9 | author = (author || []).join('|') 10 | let mime = m.quoted.mimetype || '' 11 | if (!/webp/.test(mime)) throw 'Reply sticker!' 12 | let img = await m.quoted.download() 13 | if (!img) throw 'Reply a sticker!' 14 | stiker = await addExif(img, packname || '', author || '') 15 | } catch (e) { 16 | console.error(e) 17 | if (Buffer.isBuffer(e)) stiker = e 18 | } finally { 19 | if (stiker) conn.sendFile(m.chat, stiker, 'wm.webp', '', m, false, { asSticker: true }) 20 | else throw 'Conversion failed' 21 | } 22 | } 23 | handler.help = ['wm |'] 24 | handler.tags = ['sticker'] 25 | handler.command = /^wm$/i 26 | 27 | export default handler 28 | -------------------------------------------------------------------------------- /plugins/tool-calc.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, text }) => { 2 | let id = m.chat 3 | conn.math = conn.math ? conn.math : {} 4 | if (id in conn.math) { 5 | clearTimeout(conn.math[id][3]) 6 | delete conn.math[id] 7 | m.reply('Hmmm...ngecheat?') 8 | } 9 | let val = text 10 | .replace(/[^0-9\-\/+*×÷πEe()piPI/]/g, '') 11 | .replace(/×/g, '*') 12 | .replace(/÷/g, '/') 13 | .replace(/π|pi/gi, 'Math.PI') 14 | .replace(/e/gi, 'Math.E') 15 | .replace(/\/+/g, '/') 16 | .replace(/\++/g, '+') 17 | .replace(/-+/g, '-') 18 | let format = val 19 | .replace(/Math\.PI/g, 'π') 20 | .replace(/Math\.E/g, 'e') 21 | .replace(/\//g, '÷') 22 | .replace(/\*×/g, '×') 23 | try { 24 | console.log(val) 25 | let result = (new Function('return ' + val))() 26 | if (!result) throw result 27 | m.reply(`*${format}* = _${result}_`) 28 | } catch (e) { 29 | if (e == undefined) throw 'Isinya?' 30 | throw 'Format salah, hanya 0-9 dan Simbol -, +, *, /, ×, ÷, π, e, (, ) yang disupport' 31 | } 32 | } 33 | handler.help = ['calc '] 34 | handler.tags = ['tools'] 35 | handler.command = /^(calc(ulat(e|or))?|kalk(ulator)?)$/i 36 | handler.exp = 5 37 | 38 | export default handler -------------------------------------------------------------------------------- /plugins/tool-delete.js: -------------------------------------------------------------------------------- 1 | let handler = function (m) { 2 | if (!m.quoted) throw false 3 | let { chat, fromMe, isBaileys } = m.quoted 4 | if (!fromMe) throw false 5 | if (!isBaileys) throw 'Pesan tersebut bukan dikirim oleh bot!' 6 | conn.sendMessage(chat, { delete: m.quoted.vM.key }) 7 | } 8 | handler.help = ['del', 'delete'] 9 | handler.tags = ['tools'] 10 | 11 | handler.command = /^del(ete)?$/i 12 | 13 | export default handler 14 | -------------------------------------------------------------------------------- /plugins/tool-getPlugins.js: -------------------------------------------------------------------------------- 1 | import { 2 | readdirSync, 3 | statSync, 4 | unlinkSync, 5 | existsSync, 6 | readFileSync, 7 | writeFileSync 8 | } from 'fs'; 9 | let handler = async (m, { usedPrefix, command, text }) => { 10 | let ar = Object.keys(plugins) 11 | let ar1 = ar.map(v => v.replace('.js', '')) 12 | if (!text) throw `uhm.. teksnya mana?\n\ncontoh:\n${usedPrefix + command} menu` 13 | if (!ar1.includes(text)) return m.reply(`'${text}' tidak ditemukan!\n\n${ar1.map(v => ' ' + v).join`\n`}`) 14 | m.reply(readFileSync('./plugins/' + text + '.js', 'utf-8')) 15 | } 16 | handler.help = ['getplugin'].map(v => v + ' ') 17 | handler.tags = ['owner'] 18 | handler.command = /^(getplugin|gp)$/i 19 | 20 | handler.rowner = true 21 | 22 | export default handler 23 | -------------------------------------------------------------------------------- /plugins/tool-hlh.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { command, text }) => { 2 | let ter = command[1].toLowerCase() 3 | let txt = m.quoted ? m.quoted.text ? m.quoted.text : text ? text : m.text : text ? text : m.text 4 | await m.reply(txt.replace(/[aiueo]/g, ter).replace(/[AIUEO]/g, ter.toUpperCase())) 5 | } 6 | handler.help = [...'aiueo'].map(v => `h${v}l${v}h `) 7 | handler.tags = ['tools'] 8 | handler.command = /^h([aiueo])l\1h/i 9 | 10 | export default handler -------------------------------------------------------------------------------- /plugins/tool-qrcode.js: -------------------------------------------------------------------------------- 1 | 2 | import { toDataURL } from 'qrcode' 3 | 4 | let handler = async (m, { conn, text }) => conn.sendFile(m.chat, await toDataURL(text.slice(0, 2048), { scale: 8 }), 'qrcode.png', '¯\\_(ツ)_/¯', m) 5 | 6 | handler.help = ['', 'code'].map(v => 'qr' + v + ' ') 7 | handler.tags = ['tools'] 8 | handler.command = /^qr(code)?$/i 9 | 10 | 11 | export default handler -------------------------------------------------------------------------------- /plugins/tool-react.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, usedPrefix: _p, args, text, usedPrefix}) => { 2 | 3 | if (!m.quoted) throw 'Balas Chatnya !' 4 | if (text.length > 2) throw 'Cuma Untuk 1 Emoji!' 5 | if (!text) throw `📍 Contoh Penggunaan :\n${usedPrefix}react 🗿` 6 | conn.relayMessage(m.chat, { reactionMessage: { 7 | key: { 8 | id: m.quoted.id, 9 | remoteJid: m.chat, 10 | fromMe: true 11 | }, 12 | text: `${text}`}}, { messageId: m.id }) 13 | } 14 | handler.help = ['react '] 15 | handler.tags = ['tools'] 16 | handler.command = /^(react)$/i 17 | 18 | export default handler -------------------------------------------------------------------------------- /plugins/tool-readmore.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn, text }) => { 2 | let [l, r] = text.split`|` 3 | if (!l) l = '' 4 | if (!r) r = '' 5 | conn.reply(m.chat, l + readMore + r, m) 6 | } 7 | handler.help = ['readmore', 'spoiler'].map(v => v + ' |') 8 | handler.tags = ['tools'] 9 | handler.command = /^(spoiler|hidetext|readmore|selengkapnya)$/i 10 | 11 | export default handler 12 | 13 | const more = String.fromCharCode(8206) 14 | const readMore = more.repeat(4001) -------------------------------------------------------------------------------- /plugins/tool-readviewonce.js: -------------------------------------------------------------------------------- 1 | let { downloadContentFromMessage } = (await import('@adiwajshing/baileys')); 2 | 3 | let handler = async (m, { conn }) => { 4 | if (!m.quoted) throw 'where\'s message?' 5 | if (m.quoted.mtype !== 'viewOnceMessage') throw 'Itu bukan pesan viewOnce' 6 | let msg = m.quoted.message 7 | let type = Object.keys(msg)[0] 8 | let media = await downloadContentFromMessage(msg[type], type == 'imageMessage' ? 'image' : 'video') 9 | let buffer = Buffer.from([]) 10 | for await (const chunk of media) { 11 | buffer = Buffer.concat([buffer, chunk]) 12 | } 13 | if (/video/.test(type)) { 14 | return conn.sendFile(m.chat, buffer, 'media.mp4', msg[type].caption || '', m) 15 | } else if (/image/.test(type)) { 16 | return conn.sendFile(m.chat, buffer, 'media.jpg', msg[type].caption || '', m) 17 | } 18 | } 19 | 20 | handler.help = ['readviewonce'] 21 | handler.tags = ['tools'] 22 | handler.command = /^readviewonce/i 23 | 24 | export default handler 25 | -------------------------------------------------------------------------------- /plugins/tool-savefile.js: -------------------------------------------------------------------------------- 1 | import { 2 | readdirSync, 3 | statSync, 4 | unlinkSync, 5 | existsSync, 6 | readFileSync, 7 | writeFileSync 8 | } from 'fs'; 9 | let handler = async (m, { text, usedPrefix, command }) => { 10 | if (!text) throw `uhm.. teksnya mana?\n\npenggunaan:\n${usedPrefix + command} \n\ncontoh:\n${usedPrefix + command} plugins/menu.js` 11 | if (!m.quoted.text) throw `balas pesan nya!` 12 | let path = `${text}` 13 | await writeFileSync(path, m.quoted.text) 14 | m.reply(`tersimpan di ${path}`) 15 | } 16 | handler.help = ['sf'].map(v => v + ' ') 17 | handler.tags = ['owner'] 18 | handler.command = /^sf$/i 19 | 20 | handler.rowner = true 21 | 22 | export default handler 23 | 24 | -------------------------------------------------------------------------------- /plugins/tool-sendquote.js: -------------------------------------------------------------------------------- 1 | async function handler(m) { 2 | if (!m.quoted) throw 'reply pesan!' 3 | let q = await m.getQuotedObj() 4 | if (!q.quoted) throw 'pesan yang anda reply tidak mengandung reply!' 5 | await q.quoted.copyNForward(m.chat, true) 6 | } 7 | handler.command = /^q$/i 8 | 9 | export default handler -------------------------------------------------------------------------------- /plugins/tool-styletext.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | import { JSDOM } from 'jsdom' 3 | let handler = async (m, { conn, text }) => { 4 | conn.reply(m.chat, Object.entries(await stylizeText(text ? text : m.quoted && m.quoted.text ? m.quoted.text : m.text)).map(([name, value]) => `*${name}*\n${value}`).join`\n\n`, m) 5 | } 6 | handler.help = ['style'].map(v => v + ' ') 7 | handler.tags = ['tools'] 8 | handler.command = /^(style(text)?)$/i 9 | 10 | handler.exp = 0 11 | 12 | export default handler 13 | 14 | async function stylizeText(text) { 15 | let res = await fetch('http://qaz.wtf/u/convert.cgi?text=' + encodeURIComponent(text)) 16 | let html = await res.text() 17 | let dom = new JSDOM(html) 18 | let table = dom.window.document.querySelector('table').children[0].children 19 | let obj = {} 20 | for (let tr of table) { 21 | let name = tr.querySelector('.aname').innerHTML 22 | let content = tr.children[1].textContent.replace(/^\n/, '').replace(/\n$/, '') 23 | obj[name + (obj[name] ? ' Reversed' : '')] = content 24 | } 25 | return obj 26 | } -------------------------------------------------------------------------------- /plugins/tool-tourl.js: -------------------------------------------------------------------------------- 1 | import uploadFile from '../lib/uploadFile.js' 2 | import uploadImage from '../lib/uploadImage.js' 3 | 4 | let handler = async (m) => { 5 | let q = m.quoted ? m.quoted : m 6 | let mime = (q.msg || q).mimetype || '' 7 | if (!mime) throw 'No media found' 8 | let media = await q.download() 9 | let isTele = /image\/(png|jpe?g|gif)|video\/mp4/.test(mime) 10 | let link = await (isTele ? uploadImage : uploadFile)(media) 11 | m.reply(`📮 *L I N K :* 12 | ${link} 13 | 📊 *S I Z E :* ${media.length} Byte 14 | 📛 *E x p i r e d :* ${isTele ? 'No Expiry Date' : 'Unknown'}`) 15 | } 16 | handler.help = ['upload (reply media)', 'tourl (reply media)'] 17 | handler.tags = ['tools'] 18 | handler.command = /^(tourl|upload)$/i 19 | 20 | export default handler -------------------------------------------------------------------------------- /plugins/tool-tts.js: -------------------------------------------------------------------------------- 1 | import gtts from 'node-gtts' 2 | import { readFileSync, unlinkSync } from 'fs' 3 | import { join } from 'path' 4 | 5 | const defaultLang = 'id' 6 | let handler = async (m, { conn, args, usedPrefix, command }) => { 7 | 8 | let lang = args[0] 9 | let text = args.slice(1).join(' ') 10 | if ((args[0] || '').length !== 2) { 11 | lang = defaultLang 12 | text = args.join(' ') 13 | } 14 | if (!text && m.quoted?.text) text = m.quoted.text 15 | 16 | let res 17 | try { res = await tts(text, lang) } 18 | catch (e) { 19 | m.reply(e + '') 20 | text = args.join(' ') 21 | if (!text) throw `Use example ${usedPrefix}${command} en hello world` 22 | res = await tts(text, defaultLang) 23 | } finally { 24 | if (res) conn.sendFile(m.chat, res, 'tts.opus', null, m, true) 25 | } 26 | } 27 | handler.help = ['tts '] 28 | handler.tags = ['tools'] 29 | handler.command = /^g?tts$/i 30 | 31 | export default handler 32 | 33 | function tts(text, lang = 'id') { 34 | console.log(lang, text) 35 | return new Promise((resolve, reject) => { 36 | try { 37 | let tts = gtts(lang) 38 | let filePath = join(global.__dirname(import.meta.url), '../tmp', (1 * new Date) + '.wav') 39 | tts.save(filePath, text, () => { 40 | resolve(readFileSync(filePath)) 41 | unlinkSync(filePath) 42 | }) 43 | } catch (e) { reject(e) } 44 | }) 45 | } -------------------------------------------------------------------------------- /plugins/totalfeature.js: -------------------------------------------------------------------------------- 1 | let handler = async (m, { conn }) => { 2 | let totalfeatures = Object.values(global.plugins).filter( 3 | (v) => v.help && v.tags 4 | ).length; 5 | conn.fakeReply(m.chat, `*total features: ${totalfeatures}*`, '0@s.whatsapp.net', '🅵🅴🅰🆃🆄🆁🅴') 6 | } 7 | 8 | handler.help = ['totalfeature'] 9 | handler.tags = ['info'] 10 | handler.command = ['totalfeature'] 11 | 12 | export default handler 13 | -------------------------------------------------------------------------------- /plugins/wikipedia.js: -------------------------------------------------------------------------------- 1 | import { wikipedia } from '@bochilteam/scraper' 2 | let handler = async (m, { text, usedPrefix, command }) => { 3 | if (!text) throw `Contoh penggunaan ${usedPrefix}${command} Minecraft` 4 | let json = await wikipedia(text) 5 | m.reply(` 6 | *${json.title}* 7 | ${json.img} 8 | 9 | ${json.articles} 10 | `.trim()) 11 | } 12 | handler.help = ['wikipedia'].map(v => v + ' ') 13 | handler.tags = ['internet'] 14 | handler.command = /^(wiki|wikipedia)$/i 15 | 16 | export default handler 17 | -------------------------------------------------------------------------------- /plugins/youtube-play.js: -------------------------------------------------------------------------------- 1 | import { youtubeSearch } from '@bochilteam/scraper' 2 | let handler = async (m, { conn, command, text, usedPrefix }) => { 3 | if (!text) throw `Use example ${usedPrefix}${command} Minecraft` 4 | let vid = (await youtubeSearch(text)).video[0] 5 | if (!vid) throw 'Video/Audio Tidak ditemukan' 6 | let { title, description, thumbnail, videoId, durationH, viewH, publishedTime } = vid 7 | const url = 'https://www.youtube.com/watch?v=' + videoId 8 | await conn.sendHydrated(m.chat, ` 9 | 📌 *Title:* ${title} 10 | 🔗 *Url:* ${url} 11 | 🖹 *Description:* ${description} 12 | ⏲️ *Published:* ${publishedTime} 13 | ⌚ *Duration:* ${durationH} 14 | 👁️ *Views:* ${viewH} 15 | *JANGAN DISPAMM* 16 | `.trim(), author, thumbnail, url, '📺Go To Youtube!', null, null, [ 17 | ['Audio 🎧', `${usedPrefix}yta ${url} yes`], 18 | ['Video 🎥', `${usedPrefix}ytv ${url} yes`], 19 | ['Cancel 🗿', `${usedPrefix}del`] 20 | ], m) 21 | } 22 | handler.help = ['play', 'play2'].map(v => v + ' ') 23 | handler.tags = ['downloader'] 24 | handler.command = /^play2?$/i 25 | 26 | handler.exp = 0 27 | handler.limit = 3 28 | 29 | export default handler 30 | 31 | -------------------------------------------------------------------------------- /plugins/youtube-yta.js: -------------------------------------------------------------------------------- 1 | let limit = 99 2 | import fetch from 'node-fetch' 3 | import { youtubedl, youtubedlv2, youtubedlv3 } from '@bochilteam/scraper'; 4 | let handler = async (m, { conn, args, isPrems, isOwner }) => { 5 | if (!args || !args[0]) throw 'Uhm... urlnya mana?' 6 | let chat = global.db.data.chats[m.chat] 7 | const isY = /y(es)/gi.test(args[1]) 8 | const { thumbnail, audio: _audio, title } = await youtubedl(args[0]).catch(async _ => await youtubedlv2(args[0])).catch(async _ => await youtubedlv3(args[0])) 9 | const limitedSize = (isPrems || isOwner ? 99 : limit) * 1024 10 | let audio, source, link, lastError, isLimit 11 | for (let i in _audio) { 12 | try { 13 | audio = _audio[i] 14 | isLimit = limitedSize < audio.fileSize 15 | if (isLimit) continue 16 | link = await audio.download() 17 | if (link) source = await (await fetch(link)).arrayBuffer() 18 | if (source instanceof ArrayBuffer) break 19 | } catch (e) { 20 | audio = link = source = null 21 | lastError = e 22 | continue 23 | } 24 | } 25 | if (!(source instanceof ArrayBuffer) || !link) throw 'Error: ' + (lastError || 'Can\'t download audio') 26 | if (!isY && !isLimit) conn.sendFile(m.chat, thumbnail, 'thumbnail.jpg', ` 27 | *📌Title:* ${title} 28 | *🗎 Filesize:* ${audio.fileSizeH} 29 | *${isLimit ? 'Pakai ' : ''}Link:* ${link} 30 | `.trim(), m) 31 | if (!isLimit) conn.sendFile(m.chat, source, title + '.mp3', ` 32 | *📌Title:* ${title} 33 | *🗎 Filesize:* ${audio.fileSizeH} 34 | `.trim(), m, null, { 35 | asDocument: true 36 | }) 37 | } 38 | handler.help = ['mp3', 'a'].map(v => 'yt' + v + ` `) 39 | handler.tags = ['downloader'] 40 | handler.command = /^yt(a|mp3)$/i 41 | 42 | handler.exp = 0 43 | 44 | export default handler -------------------------------------------------------------------------------- /plugins/youtube-yts.js: -------------------------------------------------------------------------------- 1 | import { youtubeSearch } from '@bochilteam/scraper' 2 | let handler = async (m, { text }) => { 3 | if (!text) throw 'Cari apa?' 4 | const { video, channel } = await youtubeSearch(text) 5 | let teks = [...video, ...channel].map(v => { 6 | switch (v.type) { 7 | case 'video': return ` 8 | 📌 *${v.title}* (${v.url}) 9 | ⌚ Duration: ${v.durationH} 10 | ⏲️ Uploaded ${v.publishedTime} 11 | 👁️ ${v.view} views 12 | `.trim() 13 | case 'channel': return ` 14 | 📌 *${v.channelName}* (${v.url}) 15 | 🧑‍🤝‍🧑 _${v.subscriberH} (${v.subscriber}) Subscriber_ 16 | 🎥 ${v.videoCount} video 17 | `.trim() 18 | } 19 | }).filter(v => v).join('\n\n========================\n\n') 20 | m.reply(teks) 21 | } 22 | handler.help = ['', 'earch'].map(v => 'yts' + v + ' ') 23 | handler.tags = ['tools'] 24 | handler.command = /^yts(earch)?$/i 25 | 26 | export default handler 27 | -------------------------------------------------------------------------------- /plugins/youtube-ytv.js: -------------------------------------------------------------------------------- 1 | let limit = 70 2 | import fetch from 'node-fetch' 3 | import { youtubedl, youtubedlv2, youtubedlv3 } from '@bochilteam/scraper'; 4 | let handler = async (m, { conn, args, isPrems, isOwner }) => { 5 | if (!args || !args[0]) throw 'Uhm... urlnya mana?' 6 | let chat = global.db.data.chats[m.chat] 7 | let isY = /y(es)/gi.test(args[1]) 8 | const { thumbnail, video: _video, title } = await youtubedl(args[0]).catch(async _ => await youtubedlv2(args[0])).catch(async _ => await youtubedlv3(args[0])) 9 | const limitedSize = (isPrems || isOwner ? 99 : limit) * 1024 10 | let video, source, link, lastError, isLimit 11 | for (let i in _video) { 12 | try { 13 | video = _video[i] 14 | isLimit = limitedSize < video.fileSize 15 | if (isLimit) continue 16 | link = await video.download() 17 | if (link) source = await (await fetch(link)).arrayBuffer() 18 | if (source instanceof ArrayBuffer) break 19 | } catch (e) { 20 | video = source = link = null 21 | lastError = e 22 | continue 23 | } 24 | } 25 | if (!(source instanceof ArrayBuffer) || !link) throw 'Error: ' + (lastError || 'Can\'t download video') 26 | if (!isY && !isLimit) conn.sendFile(m.chat, thumbnail, 'thumbnail.jpg', ` 27 | *📌Title:* ${title} 28 | *🗎 Filesize:* ${video.fileSizeH} 29 | *${isLimit ? 'Pakai ' : ''}Link:* ${link} 30 | `.trim(), m) 31 | let _thumb = {} 32 | try { _thumb = { thumbnail: await (await fetch(thumbnail)).buffer() } } 33 | catch (e) { } 34 | if (!isLimit) conn.sendFile(m.chat, link, title + '.mp4', ` 35 | *📌Title:* ${title} 36 | *🗎 Filesize:* ${video.fileSizeH} 37 | `.trim(), m, false, { 38 | ..._thumb, 39 | asDocument: chat.useDocument 40 | }) 41 | } 42 | handler.help = ['mp4', 'v', ''].map(v => 'yt' + v + ` `) 43 | handler.tags = ['downloader'] 44 | handler.command = /^yt(v|mp4)?$/i 45 | 46 | handler.exp = 0 47 | 48 | 49 | export default handler 50 | 51 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | import { createServer } from 'http' 3 | import path from 'path' 4 | import { Socket } from 'socket.io' 5 | import { toBuffer } from 'qrcode' 6 | import fetch from 'node-fetch' 7 | 8 | function connect(conn, PORT) { 9 | let app = global.app = express() 10 | console.log(app) 11 | let server = global.server = createServer(app) 12 | // app.use(express.static(path.join(__dirname, 'views'))) 13 | let _qr = 'invalid' 14 | 15 | conn.ev.on('connection.update', function appQR({ qr }) { 16 | if (qr) _qr = qr 17 | }) 18 | 19 | app.use(async (req, res) => { 20 | res.setHeader('content-type', 'image/png') 21 | res.end(await toBuffer(_qr)) 22 | }) 23 | 24 | // let io = new Socket(server) 25 | // io.on('connection', socket => { 26 | // let { unpipeEmit } = pipeEmit(conn, socket, 'conn-') 27 | // socket.on('disconnect', unpipeEmit) 28 | // }) 29 | 30 | server.listen(PORT, () => { 31 | console.log('App listened on port', PORT) 32 | if (opts['keepalive']) keepAlive() 33 | }) 34 | } 35 | 36 | function pipeEmit(event, event2, prefix = '') { 37 | let old = event.emit 38 | event.emit = function (event, ...args) { 39 | old.emit(event, ...args) 40 | event2.emit(prefix + event, ...args) 41 | } 42 | return { 43 | unpipeEmit() { 44 | event.emit = old 45 | } 46 | } 47 | } 48 | 49 | function keepAlive() { 50 | const url = `https://${process.env.REPL_SLUG}.${process.env.REPL_OWNER}.repl.co` 51 | if (/(\/\/|\.)undefined\./.test(url)) return 52 | setInterval(() => { 53 | fetch(url).catch(console.error) 54 | }, 5 * 1000 * 60) 55 | } 56 | 57 | 58 | export default connect 59 | -------------------------------------------------------------------------------- /session.data.json: -------------------------------------------------------------------------------- 1 | ganti pake session MD 2 | -------------------------------------------------------------------------------- /src/Aesthetic/Aesthetic_000.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/Aesthetic/Aesthetic_000.jpeg -------------------------------------------------------------------------------- /src/Aesthetic/Aesthetic_001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/Aesthetic/Aesthetic_001.jpg -------------------------------------------------------------------------------- /src/Aesthetic/Aesthetic_002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/Aesthetic/Aesthetic_002.jpg -------------------------------------------------------------------------------- /src/avatar_contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/avatar_contact.png -------------------------------------------------------------------------------- /src/bab2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/bab2.pdf -------------------------------------------------------------------------------- /src/font/212BabyGirl.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/212BabyGirl.otf -------------------------------------------------------------------------------- /src/font/212LeahleeSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/212LeahleeSans.ttf -------------------------------------------------------------------------------- /src/font/99HandWritting.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/99HandWritting.ttf -------------------------------------------------------------------------------- /src/font/ACallingFontDby7NTypes.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/ACallingFontDby7NTypes.otf -------------------------------------------------------------------------------- /src/font/ACasualHandwrittenPenNoncommercial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/ACasualHandwrittenPenNoncommercial.ttf -------------------------------------------------------------------------------- /src/font/ADayinSeptember.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/ADayinSeptember.otf -------------------------------------------------------------------------------- /src/font/ASMelanieHandwritting.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/ASMelanieHandwritting.ttf -------------------------------------------------------------------------------- /src/font/Alittlesunshine.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Alittlesunshine.ttf -------------------------------------------------------------------------------- /src/font/And-This-Happened.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/And-This-Happened.ttf -------------------------------------------------------------------------------- /src/font/AvenirCondensedHand.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/AvenirCondensedHand.ttf -------------------------------------------------------------------------------- /src/font/Avocados.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Avocados.ttf -------------------------------------------------------------------------------- /src/font/BabyDoll.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/BabyDoll.ttf -------------------------------------------------------------------------------- /src/font/BattleOfKingsRegular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/BattleOfKingsRegular.ttf -------------------------------------------------------------------------------- /src/font/BrayNotes.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/BrayNotes.ttf -------------------------------------------------------------------------------- /src/font/Convered-By-Your-Grace.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Convered-By-Your-Grace.ttf -------------------------------------------------------------------------------- /src/font/Edoms-Handwritting-Normal.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Edoms-Handwritting-Normal.ttf -------------------------------------------------------------------------------- /src/font/Futura Bold Italic font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Bold Italic font.ttf -------------------------------------------------------------------------------- /src/font/Futura Bold font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Bold font.ttf -------------------------------------------------------------------------------- /src/font/Futura Book Italic font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Book Italic font.ttf -------------------------------------------------------------------------------- /src/font/Futura Book font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Book font.ttf -------------------------------------------------------------------------------- /src/font/Futura Extra Black font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Extra Black font.ttf -------------------------------------------------------------------------------- /src/font/Futura Heavy Italic font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Heavy Italic font.ttf -------------------------------------------------------------------------------- /src/font/Futura Heavy font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Heavy font.ttf -------------------------------------------------------------------------------- /src/font/Futura Light Italic font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Light Italic font.ttf -------------------------------------------------------------------------------- /src/font/Futura Light font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Light font.ttf -------------------------------------------------------------------------------- /src/font/Futura Medium Italic font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura Medium Italic font.ttf -------------------------------------------------------------------------------- /src/font/Futura XBlk BT.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura XBlk BT.ttf -------------------------------------------------------------------------------- /src/font/Futura-CondensedLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Futura-CondensedLight.otf -------------------------------------------------------------------------------- /src/font/GloriaHallelujah-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/GloriaHallelujah-Regular.ttf -------------------------------------------------------------------------------- /src/font/HandwritingCR-2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/HandwritingCR-2.ttf -------------------------------------------------------------------------------- /src/font/Kempton-Demo-Handwritting.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Kempton-Demo-Handwritting.ttf -------------------------------------------------------------------------------- /src/font/MyHandsareHoldingYou.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/MyHandsareHoldingYou.ttf -------------------------------------------------------------------------------- /src/font/My_handwriting.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/My_handwriting.ttf -------------------------------------------------------------------------------- /src/font/Nadeznas-Handwritting.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Nadeznas-Handwritting.ttf -------------------------------------------------------------------------------- /src/font/Roboto-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-Black.ttf -------------------------------------------------------------------------------- /src/font/Roboto-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-BlackItalic.ttf -------------------------------------------------------------------------------- /src/font/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-Bold.ttf -------------------------------------------------------------------------------- /src/font/Roboto-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-BoldItalic.ttf -------------------------------------------------------------------------------- /src/font/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-Italic.ttf -------------------------------------------------------------------------------- /src/font/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-Light.ttf -------------------------------------------------------------------------------- /src/font/Roboto-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-LightItalic.ttf -------------------------------------------------------------------------------- /src/font/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-Medium.ttf -------------------------------------------------------------------------------- /src/font/Roboto-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-MediumItalic.ttf -------------------------------------------------------------------------------- /src/font/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-Regular.ttf -------------------------------------------------------------------------------- /src/font/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-Thin.ttf -------------------------------------------------------------------------------- /src/font/Roboto-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Roboto-ThinItalic.ttf -------------------------------------------------------------------------------- /src/font/ShadowsIntoLight-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/ShadowsIntoLight-Regular.ttf -------------------------------------------------------------------------------- /src/font/Zahraaa.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/Zahraaa.ttf -------------------------------------------------------------------------------- /src/font/angelina.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/angelina.ttf -------------------------------------------------------------------------------- /src/font/futur.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/futur.ttf -------------------------------------------------------------------------------- /src/font/futura light bt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/futura light bt.ttf -------------------------------------------------------------------------------- /src/font/futura medium bt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/futura medium bt.ttf -------------------------------------------------------------------------------- /src/font/futura medium condensed bt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/futura medium condensed bt.ttf -------------------------------------------------------------------------------- /src/font/level_c.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/level_c.otf -------------------------------------------------------------------------------- /src/font/michellehandwritting.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/michellehandwritting.ttf -------------------------------------------------------------------------------- /src/font/texts.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/font/texts.otf -------------------------------------------------------------------------------- /src/kertas/magernulis1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/kertas/magernulis1.jpg -------------------------------------------------------------------------------- /src/level_c.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/level_c.otf -------------------------------------------------------------------------------- /src/lvlup_template.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/lvlup_template.jpg -------------------------------------------------------------------------------- /src/s_pgsd_penjas_0701098_chapter3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/s_pgsd_penjas_0701098_chapter3.pdf -------------------------------------------------------------------------------- /src/squidGame_GLRL.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/squidGame_GLRL.mp3 -------------------------------------------------------------------------------- /src/squidGame_GLRL_Scan.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/squidGame_GLRL_Scan.mp3 -------------------------------------------------------------------------------- /src/squidGame_GLRL_Shoot.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/squidGame_GLRL_Shoot.mp3 -------------------------------------------------------------------------------- /src/temp/File: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/texts.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/src/texts.otf -------------------------------------------------------------------------------- /temp/.file: -------------------------------------------------------------------------------- 1 | kosong 2 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import path, { dirname } from 'path' 3 | import assert from 'assert' 4 | import { spawn } from 'child_process' 5 | import syntaxError from 'syntax-error' 6 | import { fileURLToPath } from 'url' 7 | import { createRequire } from 'module' 8 | 9 | const __filename = fileURLToPath(import.meta.url) 10 | const __dirname = dirname(__filename) 11 | const require = createRequire(__dirname) 12 | 13 | let folders = ['.', ...Object.keys(require(path.join(__dirname, './package.json')).directories)] 14 | let files = [] 15 | for (let folder of folders) 16 | for (let file of fs.readdirSync(folder).filter(v => v.endsWith('.js'))) 17 | files.push(path.resolve(path.join(folder, file))) 18 | for (let file of files) { 19 | if (file == __filename) continue 20 | console.error('Checking', file) 21 | const error = syntaxError(fs.readFileSync(file, 'utf8'), file, { 22 | sourceType: 'module', 23 | allowReturnOutsideFunction: true, 24 | allowAwaitOutsideFunction: true 25 | }) 26 | if (error) assert.ok(error.length < 1, file + '\n\n' + error) 27 | assert.ok(file) 28 | console.log('Done', file) 29 | } 30 | -------------------------------------------------------------------------------- /thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/thumbnail.jpg -------------------------------------------------------------------------------- /views/img/dark/balloon_centered_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_centered_normal.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_centered_pressed.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_centered_pressed.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_centered_shadow.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_centered_shadow.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_incoming_frame.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_incoming_frame.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_incoming_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_incoming_normal.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_incoming_normal_ext.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_incoming_normal_ext.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_incoming_normal_stkr.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_incoming_normal_stkr.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_incoming_pressed.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_incoming_pressed.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_incoming_pressed_ext.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_incoming_pressed_ext.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_live_location_incoming_frame.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_live_location_incoming_frame.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_live_location_outgoing_frame.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_live_location_outgoing_frame.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_outgoing_frame.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_outgoing_frame.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_outgoing_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_outgoing_normal.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_outgoing_normal_ext.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_outgoing_normal_ext.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_outgoing_normal_stkr.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_outgoing_normal_stkr.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_outgoing_pressed.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_outgoing_pressed.9.png -------------------------------------------------------------------------------- /views/img/dark/balloon_outgoing_pressed_ext.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/dark/balloon_outgoing_pressed_ext.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_centered_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_centered_normal.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_centered_pressed.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_centered_pressed.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_centered_shadow.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_centered_shadow.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_incoming_frame.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_incoming_frame.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_incoming_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_incoming_normal.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_incoming_normal_ext.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_incoming_normal_ext.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_incoming_normal_stkr.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_incoming_normal_stkr.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_incoming_pressed.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_incoming_pressed.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_incoming_pressed_ext.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_incoming_pressed_ext.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_live_location_incoming_frame.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_live_location_incoming_frame.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_live_location_outgoing_frame.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_live_location_outgoing_frame.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_outgoing_frame.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_outgoing_frame.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_outgoing_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_outgoing_normal.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_outgoing_normal_ext.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_outgoing_normal_ext.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_outgoing_normal_stkr.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_outgoing_normal_stkr.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_outgoing_pressed.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_outgoing_pressed.9.png -------------------------------------------------------------------------------- /views/img/light/balloon_outgoing_pressed_ext.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siegrin/CloudBot/da799ffb84e48b75944af64ce8d16644db67c5c1/views/img/light/balloon_outgoing_pressed_ext.9.png -------------------------------------------------------------------------------- /views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Web 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 |
26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /views/index.js: -------------------------------------------------------------------------------- 1 | window.onload = () => { 2 | let chat = document.querySelector('div.container-fluid') 3 | function addMsg(obj) { 4 | let html = document.createElement('span') 5 | html.className = 'msg' 6 | html.innerHTML = obj 7 | chat.appendChild(html) 8 | } 9 | 10 | window.onclick = () => addMsg(12) 11 | } 12 | -------------------------------------------------------------------------------- /views/style.css: -------------------------------------------------------------------------------- 1 | span.msg { 2 | } 3 | 4 | --------------------------------------------------------------------------------