├── .github
├── CODE_OF_CONDUCT.md
└── workflows
│ └── greetings.yml
├── .gitignore
├── .replit
├── Dockerfile
├── LICENSE
├── Procfile
├── README.md
├── app.json
├── config.js
├── docker-compose.yml
├── handler.js
├── index.html
├── index.js
├── lib
├── cloudDBAdapter.js
├── convert.js
├── converter.js
├── database.js
├── gdrive.js
├── levelling.js
├── logs.js
├── mongoDB.js
├── print.js
├── simple.js
├── sticker.js
├── store.js
├── store2.js
├── tictactoe.d.ts
├── tictactoe.js
├── uploadFile.js
├── uploadImage.js
├── util.js
├── webp.js
├── webp2mp4.js
├── welcome.js
└── y2mate.js
├── main.js
├── me.png
├── me2.jpeg
├── package.json
├── plugins
├── _afk.js
├── _antilink.js
├── _cek.js
├── _func.js
├── _memfess-Ans.js
├── _templateResponse.js
├── _ttt.js
├── afk.js
├── ai-animediff.js
├── ai-animediff2.js
├── ai-chatgpt.js
├── anonymous_chat.js
├── anonymous_chat_.js
├── cmd-del.js
├── cmd-list.js
├── cmd-lock.js
├── cmd-set.js
├── creator.js
├── downloader-danbooru.js
├── downloader-fb.js
├── downloader-gddl.js
├── downloader-git.js
├── downloader-ig.js
├── downloader-mediafire.js
├── downloader-play.js
├── downloader-sfile.js
├── downloader-tiktok.js
├── enable.js
├── game-ttt.js
├── general-menu.js
├── general-toimg.js
├── general-tomp3.js
├── general-tomp4.js
├── group-demote.js
├── group-hidetag.js
├── group-link.js
├── group-mute.js
├── group-promote.js
├── group-revoke.js
├── group-sdesc.js
├── group-set.js
├── group-setname.js
├── group-setpp.js
├── group-tagall.js
├── image-gimage.js
├── internet-freepik.js
├── misc--pinterest.js
├── misc-bonk.js
├── misc-dashboard.js
├── misc-delete.js
├── misc-emojimix.js
├── misc-listgc.js
├── misc-memfess.js
├── misc-profile.js
├── misc-react.js
├── misc-runtime.js
├── misc-speed.js
├── misc-stats.js
├── misc-total.js
├── owner-add.js
├── owner-broadcastgc.js
├── owner-df.js
├── owner-exec.js
├── owner-exec2.js
├── owner-gp.js
├── owner-join.js
├── owner-kick.js
├── owner-pinchat.js
├── owner-setbio.js
├── owner-setpp.js
├── owner-sf.js
├── sc.js
├── setpref.js
├── sticker-null.js
├── sticker-qc.js
├── sticker-wm.js
├── sticker.js
├── tools-base64.js
├── tools-blur.js
├── tools-device.js
├── tools-enc.js
├── tools-fetch.js
├── tools-getcaption.js
├── tools-google.js
├── tools-inspect.js
├── tools-lyrics.js
├── tools-mention.js
├── tools-npm.js
├── tools-obfus.js
├── tools-ocr.js
├── tools-polling.js
├── tools-ptv.js
├── tools-qr.js
├── tools-readmore.js
├── tools-rvo.js
├── tools-sauce.js
├── tools-sendquoted.js
├── tools-ssweb.js
├── tools-style.js
├── tools-tempmail.js
├── tools-tourl.js
├── tools-tovn.js
├── tools-tts.js
├── tools-ttstalk.js
├── tools-weather.js
├── tools-webcek.js
├── tools-whatmusic.js
├── weebs-loli.js
├── weebs-ppcp.js
├── weebs-waifupics.js
├── yt-yta.js
├── yt-yts.js
└── yt-ytv.js
├── replit.nix
├── server.js
├── src
├── Aesthetic
│ ├── Aesthetic_000.jpeg
│ ├── Aesthetic_001.jpg
│ ├── Aesthetic_002.jpg
│ ├── Thumbs.db
│ └── r
├── LICENSE
├── UwU by Lua
├── avatar_contact.png
├── 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
├── level_c.otf
├── lvlup_template.jpg
├── r
├── texts.otf
└── welcome.svg
├── test.js
└── tmp
└── cro skkk
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at slavyan@secret.fyi. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/.github/workflows/greetings.yml:
--------------------------------------------------------------------------------
1 | name: Greetings
2 |
3 | on: [pull_request, issues]
4 |
5 | jobs:
6 | greeting:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/first-interaction@v1
10 | with:
11 | repo-token: ${{ secrets.GITHUB_TOKEN }}
12 | issue-message: 'Hello! Thanks for submiting the issue, we will respond to you ASAP.'
13 | pr-message: 'Hello! Thank you for contributing to this repo, we will review your commits ASAP.'
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | tmp/*
3 |
4 | # Dependency directories
5 | .git/
6 | node_modules/
7 |
8 | # data-single-auth
9 | session.data.json
10 | database.json
11 | package-lock.json
12 |
13 | #data-multi-auth
14 | data.store.json
15 | sessions/
16 |
--------------------------------------------------------------------------------
/.replit:
--------------------------------------------------------------------------------
1 | run = "clear && node ."
2 |
3 | [nix]
4 | channel = "unstable"
5 |
--------------------------------------------------------------------------------
/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
14 |
15 | COPY . .
16 |
17 | EXPOSE 5000
18 |
19 | CMD ["npm", "start"]
20 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | worker: npm start
2 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wa bot md by zoro md",
3 | "description": "Whatsapp bot. recode by lua ser ofc",
4 | "keywords": [
5 | "whatsapp bot",
6 | "nodejs"
7 | ],
8 | "repository": "https://github.com/xxirfanx/zoromd",
9 | "buildpacks": [
10 | {
11 | "url": "heroku/nodejs"
12 | },
13 | {
14 | "url": "https://github.com/DuckyTeam/heroku-buildpack-imagemagick.git"
15 | },
16 | {
17 | "url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest"
18 | },
19 | {
20 | "url": "https://github.com/clhuang/heroku-buildpack-webp-binaries.git"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk'
2 | import { fileURLToPath } from 'url'
3 | import { watchFile, unwatchFile, readFileSync } from 'fs'
4 |
5 | global.owner =
6 | [
7 | ['+91 6235 050 956', '𝖑𝖚𝖆 𝖘𝖊𝖗 𝖔𝖋𝖈', true]
8 | ]
9 | // Put your number here
10 | // [number, he creator/owner?, he developer?]
11 |
12 | global.mods = [] // Want some help?
13 | global.prems = [] // Premium user has unlimited limit
14 |
15 | // api key here okay
16 | global.xyro = 'LyrK9JMI7N' // https://api.xyroinee.xyz free limit unlimited
17 | global.apilol = 'GataDios' // https://api.lolhuman.xyz free limit unlimited by @BrunoSobrino
18 |
19 | global.APIs = { // API Prefix
20 | // name: 'https://website'
21 | nrtm: 'https://nurutomo.herokuapp.com',
22 | xteam: 'https://api.xteam.xyz'
23 | }
24 | global.APIKeys = { // APIKey Here
25 | // 'https://website': 'apikey'
26 | 'https://api.xteam.xyz': 'd90a9e986e18778b'
27 | }
28 |
29 | global.thumbnailUrl = [
30 | 'https://telegra.ph/file/81260a8b9e8cff26d2b48.jpg', 'https://telegra.ph/file/ac4928f0824a2a0492737.jpg',
31 | 'https://telegra.ph/file/6359b013bc7e52c3b346f.jpg', 'https://telegra.ph/file/d43c89a5d2da72875ec05.jpg',
32 | 'https://telegra.ph/file/7d6c0e35f9c8f52715541.jpg', 'https://telegra.ph/file/ef4b742d47e6a9115e2ff.jpg',
33 | 'https://telegra.ph/file/55e5af5f33fbd57104187.jpg', 'https://telegra.ph/file/af236598456b95884bd15.jpg',
34 | 'https://telegra.ph/file/de92ed4a729887ffc974c.jpg', 'https://telegra.ph/file/00ce42a193b1dbbf907d4.jpg'
35 | ]
36 |
37 | // Sticker WM
38 | global.packname = `「 Cʀᴇᴀᴛᴇᴅ Bʏ 𝖑𝖚𝖆 𝖘𝖊𝖗 𝖔𝖋𝖈 」`
39 | global.author = ''
40 | global.thumb = readFileSync('./me.png')
41 | global.thumb2 = readFileSync('./me2.jpeg')
42 | global.multiplier = 69 // The higher, The harder levelup
43 |
44 | //Text here
45 | global.me = 'Cʀᴇᴀᴛᴇᴅ Bʏ 𝖑𝖚𝖆 𝖘𝖊𝖗 𝖔𝖋𝖈 - 2023'
46 | global.bott = 'zoro md'
47 | global.nomorown = '916235050956'
48 | // owner put this creator.js
49 | global.str = '-------------'
50 | global.l = '「'
51 | global.r = '」'
52 | global.wait = '```「▰▰▰▱▱▱▱▱▱▱」ʟ ᴏ ᴀ ᴅ ɪ ɴ ɢ...```'
53 | global.eror = '```404 ᴇʀʀᴏʀ```'
54 |
55 | global.rpg = {
56 | emoticon(string) {
57 | string = string.toLowerCase()
58 | let emot = {
59 | level: '🧬',
60 | limit: '🌌',
61 | health: '❤️',
62 | exp: '✉️',
63 | money: '💵',
64 | potion: '🥤',
65 | diamond: '💎',
66 | common: '📦',
67 | uncommon: '🎁',
68 | mythic: '🗳️',
69 | legendary: '🗃️',
70 | pet: '🎁',
71 | trash: '🗑',
72 | armor: '🥼',
73 | sword: '⚔️',
74 | wood: '🪵',
75 | rock: '🪨',
76 | string: '🕸️',
77 | horse: '🐎',
78 | cat: '🐈',
79 | dog: '🐕',
80 | fox: '🦊',
81 | petFood: '🍖',
82 | iron: '⛓️',
83 | gold: '👑',
84 | emerald: '💚'
85 | }
86 | let results = Object.keys(emot).map(v => [v, new RegExp(v, 'gi')]).filter(v => v[1].test(string))
87 | if (!results.length) return ''
88 | else return emot[results[0][0]]
89 | }
90 | }
91 |
92 | let file = fileURLToPath(import.meta.url)
93 | watchFile(file, () => {
94 | unwatchFile(file)
95 | console.log(chalk.cyanBright("Update 'config.js'"))
96 | import(`${file}?update=${Date.now()}`)
97 | })
98 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "4.0"
2 | services:
3 | worker:
4 | build: .
5 | volumes:
6 | - .:/code
7 | - logvolume01:/var/log
8 | links:
9 | - redis
10 | redis:
11 | image: redis
12 | volumes:
13 | logvolume01: {}
14 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
whatsapp bot by zoromd
2 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | console.log('Starting Bot...')
2 |
3 | import yargs from 'yargs'; import cfonts from 'cfonts'; import { fileURLToPath } from 'url'; import { join, dirname } from 'path'; import { createRequire } from 'module'; import { createInterface } from 'readline'; import { setupMaster, fork } from 'cluster'; import { watchFile, unwatchFile } from 'fs';
4 |
5 | // https://stackoverflow.com/a/50052194
6 | const { say } = cfonts
7 | const rl = createInterface(process.stdin, process.stdout)
8 | const __dirname = dirname(fileURLToPath(import.meta.url))
9 | const require = createRequire(__dirname)
10 |
11 | say('Lightweight\nWhatsApp Bot MD', { font: 'chrome', align: 'center', gradient: ['red', 'magenta'] })
12 | say('Bot created by lua sakura', { font: 'console', align: 'center', gradient: ['red', 'magenta'] })
13 |
14 | var isRunning = false
15 | /**
16 | * Start a js file
17 | * @param {String} file `path/to/file`
18 | */
19 | function start(file) {
20 | if (isRunning) return
21 | isRunning = true
22 | let args = [join(__dirname, file), ...process.argv.slice(2)]
23 | say([process.argv[0], ...args].join(' '), { font: 'console', align: 'center', gradient: ['red', 'magenta'] })
24 | setupMaster({ exec: args[0], args: args.slice(1) })
25 | let p = fork()
26 | p.on('message', data => {
27 | console.log('[✅RECEIVED]', data)
28 | switch (data) {
29 | case 'reset':
30 | p.process.kill()
31 | isRunning = false
32 | start.apply(this, arguments)
33 | break
34 | case 'uptime':
35 | p.send(process.uptime())
36 | break
37 | }
38 | })
39 | p.on('exit', (_, code) => {
40 | isRunning = false
41 | console.error('Exited with code:', code)
42 | if (code !== 0) return start(file)
43 | watchFile(args[0], () => {
44 | unwatchFile(args[0])
45 | start(file)
46 | })
47 | })
48 | let opts = new Object(yargs(process.argv.slice(2)).exitProcess(false).parse())
49 | if (!opts['test'])
50 | if (!rl.listenerCount()) rl.on('line', line => {
51 | p.emit('message', line.trim())
52 | })
53 | // console.log(p)
54 | }
55 |
56 | start('main.js')
57 |
--------------------------------------------------------------------------------
/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/convert.js:
--------------------------------------------------------------------------------
1 | import * as fs from 'fs'
2 | import * as path from 'path'
3 | import ffmpeg from 'fluent-ffmpeg'
4 | import { exec } from 'child_process'
5 | import { addExif } from './sticker.js'
6 |
7 | function convert(file, ext1, ext2, options = []) {
8 | return new Promise(async (resolve, reject) => {
9 | let temp = path.join(__dirname(import.meta.url), '../tmp', Date.now() + '.' + ext1),
10 | out = temp + '.' + ext2;
11 | await fs.promises.writeFile(temp, file);
12 | ffmpeg(temp)
13 | .on('start', (cmd) => {
14 | console.log(cmd);
15 | })
16 | .on('error', (e) => {
17 | fs.unlinkSync(temp);
18 | reject(e);
19 | })
20 | .on('end', () => {
21 | console.log("Finish");
22 | setTimeout(() => {
23 | fs.unlinkSync(temp);
24 | fs.unlinkSync(out);
25 | }, 2000)
26 | resolve(fs.readFileSync(out));
27 | })
28 | .addOutputOptions(options)
29 | .toFormat(ext2)
30 | .save(out);
31 | });
32 | }
33 |
34 | function convert2(file, ext1, ext2, options = []) {
35 | return new Promise(async (resolve, reject) => {
36 | let temp = path.join(__dirname(import.meta.url), '../tmp', Date.now() + '.' + ext1),
37 | out = temp + '.' + ext2;
38 | await fs.promises.writeFile(temp, file);
39 | ffmpeg(temp)
40 | .on('start', (cmd) => {
41 | console.log(cmd);
42 | })
43 | .on('error', (e) => {
44 | fs.unlinkSync(temp);
45 | reject(e);
46 | })
47 | .on('end', () => {
48 | console.log("Finish");
49 | setTimeout(() => {
50 | fs.unlinkSync(temp);
51 | fs.unlinkSync(out);
52 | }, 2000)
53 | resolve(fs.readFileSync(out));
54 | })
55 | .addOutputOptions(options)
56 | .seekInput("00:00")
57 | .setDuration("00:05")
58 | .toFormat(ext2)
59 | .save(out);
60 | });
61 | }
62 |
63 | async function sticker(file, opts) {
64 | if (typeof opts.cmdType === "undefined") opts.cmdType = "1"
65 | const cmd = {
66 | 1: ["-fs 1M", "-vcodec", "libwebp", "-vf", `scale=512:512:flags=lanczos:force_original_aspect_ratio=decrease,format=rgba,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,setsar=1`],
67 | 2: ["-fs 1M", "-vcodec", "libwebp"]
68 | }
69 | /*
70 | if (opts.withPackInfo) {
71 | if (!opts.packInfo) throw Error("'packInfo' must be filled when using 'withPackInfo'");
72 | let ext = opts.isImage !== undefined || false ? "jpg" : opts.isVideo !== undefined || false ? "mp4" : null;
73 | return stickerWithExif(file, ext, opts.packInfo, cmd[parseInt(opts.cmdType)]);
74 | }
75 | */
76 | if (opts.isImage) {
77 | return convert(file, "jpg", "webp", cmd[parseInt(opts.cmdType)]);
78 | }
79 | if (opts.isVideo) {
80 | return convert2(file, "mp4", "webp", cmd[parseInt(opts.cmdType)]);
81 | }
82 | }
83 | /*
84 | function stickerWithExif(file, ext, packInfo, cmd) {
85 | return new Bluebird(async (res, rej) => {
86 | let { packname, author } = packInfo;
87 | const filename = Date.now();
88 | const stickerBuffer = ext === "jpg" ? (await convert(file, ext, "webp", cmd)) : (await convert2(file, ext, "webp", cmd));
89 | ex.create(packname !== undefined || '' ? packname : "Original", author !== undefined || '' ? author : "SMH-BOT", filename);
90 | await fs.promises.writeFile(`./temp/${filename}.webp`, stickerBuffer);
91 | run(`webpmux -set exif ./temp/${filename}.exif ./temp/${filename}.webp -o ./temp/${filename}.webp`, async (err) => {
92 | if (err) rej(err) && await Promise.all([
93 | fs.unlink(`./temp/${filename}.webp`),
94 | fs.unlink(`./temp/${filename}.exif`)
95 | ]);
96 | setTimeout(() => {
97 | fs.unlinkSync(`./temp/${filename}.exif`); fs.unlinkSync(`./temp/${filename}.webp`);
98 | }, 2000);
99 | res(fs.readFileSync(`./temp/${filename}.webp`));
100 | })
101 | });
102 | }
103 | */
104 | export {
105 | sticker
106 | }
107 |
--------------------------------------------------------------------------------
/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 | }
93 |
--------------------------------------------------------------------------------
/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 | }
38 |
--------------------------------------------------------------------------------
/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/mongoDB.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose'
2 |
3 | const { Schema, connect, model: _model } = mongoose
4 | const defaultOptions = { useNewUrlParser: true, useUnifiedTopology: true }
5 |
6 | export class mongoDB {
7 | constructor(url, options = defaultOptions) {
8 | /**
9 | * @type {string}
10 | */
11 | this.url = url
12 | /**
13 | * @type {mongoose.ConnectOptions}
14 | */
15 | this.options = options
16 | this.data = this._data = {}
17 | /**
18 | * @type {mongoose.Schema}
19 | */
20 | this._schema = {}
21 | /**
22 | * @type {mongoose.Model}
23 | */
24 | this._model = {}
25 | /**
26 | * @type {Promise}
27 | */
28 | this.db = connect(this.url, { ...this.options }).catch(console.error)
29 | }
30 | async read() {
31 | this.conn = await this.db
32 | let schema = this._schema = new Schema({
33 | data: {
34 | type: Object,
35 | required: true, //depends on whether the field is mandatory or not
36 | default: {}
37 | }
38 | })
39 | try { this._model = _model('data', schema) } catch { this._model = _model('data') }
40 | this._data = await this._model.findOne({})
41 | if (!this._data) {
42 | this.data = {}
43 | const [_, _data] = await Promise.all([
44 | this.write(this.data),
45 | this._model.findOne({})
46 | ])
47 | this._data = _data
48 | } else this.data = this._data.data
49 | return this.data
50 | }
51 |
52 | write(data) {
53 | return new Promise(async (resolve, reject) => {
54 | if (!data) return reject(data)
55 | if (!this._data) return resolve((new this._model({ data })).save())
56 | this._model.findById(this._data._id, (err, docs) => {
57 | if (err) return reject(err)
58 | if (!docs.data) docs.data = {}
59 | docs.data = data
60 | this.data = {}
61 | return docs.save(resolve)
62 | })
63 | })
64 | }
65 | }
66 |
67 | export const mongoDBV2 = class MongoDBV2 {
68 | constructor(url, options = defaultOptions) {
69 | /**
70 | * @type {string}
71 | */
72 | this.url = url
73 | /**
74 | * @type {mongoose.ConnectOptions}
75 | */
76 | this.options = options
77 | /**
78 | * @type {{ name: string, model: mongoose.Model}[]}
79 | */
80 | this.models = []
81 | /**
82 | * @type {{ [Key: string]: any }}
83 | */
84 | this.data = {}
85 | this.lists
86 | /**
87 | * @type {mongoose.Model}
88 | */
89 | this.list
90 | /**
91 | * @type {Promise}
92 | */
93 | this.db = connect(this.url, { ...this.options }).catch(console.error)
94 | }
95 | async read() {
96 | this.conn = await this.db
97 | let schema = new Schema({
98 | data: [{
99 | name: String,
100 | }]
101 | })
102 | try { this.list = _model('lists', schema) } catch (e) { this.list = _model('lists') }
103 | this.lists = await this.list.findOne({})
104 | if (!lists?.data) {
105 | await this.list.create({ data: [] })
106 | // await (new this.list({ data: [] })).save()
107 | this.lists = await this.list.findOne({})
108 | }
109 | let garbage = []
110 | for (let { name } of this.lists.data) { // get data from list
111 | /**
112 | * @type {mongoose.Model}
113 | */
114 | let collection
115 | try { collection = _model(name, new Schema({ data: Array })) } catch (e) {
116 | console.error(e)
117 | try { collection = _model(name) } catch (e) {
118 | garbage.push(name)
119 | console.error(e)
120 | }
121 | }
122 | if (collection) {
123 | this.models.push({ name, model: collection })
124 | let collectionsData = await collection.find({})
125 | this.data[name] = Object.fromEntries(collectionsData.map(v => v.data))
126 | }
127 | }
128 | try {
129 | // Delete list if not exist
130 | let del = await this.list.findById(this.lists._id)
131 | del.data = del.data.filter(v => !garbage.includes(v.name))
132 | await del.save()
133 | } catch (e) {
134 | console.error(e)
135 | }
136 |
137 | return this.data
138 | }
139 | write(data) {
140 | return new Promise(async (resolve, reject) => {
141 | if (!this.lists || !data) return reject(data || this.lists)
142 | let collections = Object.keys(data), listDoc = [], index = 0
143 | for (let key of collections) {
144 | // Update if exist
145 | if ((index = this.models.findIndex(v => v.name === key)) !== -1) {
146 | let doc = this.models[index].model
147 | await doc.deleteMany().catch(console.error) // alwasy insert, no matter delete error
148 | await doc.insertMany(Object.entries(data[key]).map(v => ({ data: v })))
149 | if (doc && key) listDoc.push({ name: key })
150 | } else { // if not exist, create new model
151 | let schema = new Schema({
152 | data: Array
153 | })
154 | /**
155 | * @type {mongoose.Model}
156 | */
157 | let doc
158 | try {
159 | doc = _model(key, schema)
160 | } catch (e) {
161 | console.error(e)
162 | doc = _model(key)
163 | }
164 | index = this.models.findIndex(v => v.name === key)
165 | this.models[index === -1 ? this.models.length : index] = { name: key, model: doc }
166 | await doc.insertMany(Object.entries(data[key]).map(v => ({ data: v })))
167 | if (doc && key) listDoc.push({ name: key })
168 | }
169 | }
170 |
171 | // save list
172 | this.list.findById(this.lists._id, function (err, doc) {
173 | if (err) return reject(err)
174 | doc.data = listDoc
175 | this.data = {}
176 | return doc.save(resolve)
177 | })
178 | return resolve(true)
179 | })
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/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/tictactoe.js:
--------------------------------------------------------------------------------
1 | class TicTacToe {
2 | constructor(playerX = 'x', playerO = 'o') {
3 | this.playerX = playerX
4 | this.playerO = playerO
5 | this._currentTurn = false
6 | this._x = 0
7 | this._o = 0
8 | this.turns = 0
9 | }
10 |
11 | get board() {
12 | return this._x | this._o
13 | }
14 |
15 | get currentTurn() {
16 | return this._currentTurn ? this.playerO : this.playerX
17 | }
18 |
19 | get enemyTurn() {
20 | return this._currentTurn ? this.playerX : this.playerO
21 | }
22 |
23 | static check(state) {
24 | for (let combo of [7, 56, 73, 84, 146, 273, 292, 448])
25 | if ((state & combo) === combo)
26 | return !0
27 | return !1
28 | }
29 |
30 | /**
31 | * ```js
32 | * TicTacToe.toBinary(1, 2) // 0b010000000
33 | * ```
34 | */
35 | static toBinary(x = 0, y = 0) {
36 | if (x < 0 || x > 2 || y < 0 || y > 2) throw new Error('invalid position')
37 | return 1 << x + (3 * y)
38 | }
39 |
40 | /**
41 | * @param player `0` is `X`, `1` is `O`
42 | *
43 | * - `-3` `Game Ended`
44 | * - `-2` `Invalid`
45 | * - `-1` `Invalid Position`
46 | * - ` 0` `Position Occupied`
47 | * - ` 1` `Sucess`
48 | * @returns {-3|-2|-1|0|1}
49 | */
50 | turn(player = 0, x = 0, y) {
51 | if (this.board === 511) return -3
52 | let pos = 0
53 | if (y == null) {
54 | if (x < 0 || x > 8) return -1
55 | pos = 1 << x
56 | } else {
57 | if (x < 0 || x > 2 || y < 0 || y > 2) return -1
58 | pos = TicTacToe.toBinary(x, y)
59 | }
60 | if (this._currentTurn ^ player) return -2
61 | if (this.board & pos) return 0
62 | this[this._currentTurn ? '_o' : '_x'] |= pos
63 | this._currentTurn = !this._currentTurn
64 | this.turns++
65 | return 1
66 | }
67 |
68 | /**
69 | * @returns {('X'|'O'|1|2|3|4|5|6|7|8|9)[]}
70 | */
71 | static render(boardX = 0, boardO = 0) {
72 | let x = parseInt(boardX.toString(2), 4)
73 | let y = parseInt(boardO.toString(2), 4) * 2
74 | return [...(x + y).toString(4).padStart(9, '0')].reverse().map((value, index) => value == 1 ? 'X' : value == 2 ? 'O' : ++index)
75 | }
76 |
77 | /**
78 | * @returns {('X'|'O'|1|2|3|4|5|6|7|8|9)[]}
79 | */
80 | render() {
81 | return TicTacToe.render(this._x, this._o)
82 | }
83 |
84 | get winner() {
85 | let x = TicTacToe.check(this._x)
86 | let o = TicTacToe.check(this._o)
87 | return x ? this.playerX : o ? this.playerO : false
88 | }
89 | }
90 |
91 | new TicTacToe().turn
92 |
93 | export default TicTacToe
94 |
--------------------------------------------------------------------------------
/lib/uploadFile.js:
--------------------------------------------------------------------------------
1 | import fetch from 'node-fetch'
2 | import { FormData, Blob } from 'formdata-node'
3 | import { fileTypeFromBuffer } from 'file-type'
4 |
5 | export default async buffer => {
6 | let { ext, mime } = await fileTypeFromBuffer(buffer)
7 | let form = new FormData()
8 | let blob = new Blob([buffer.toArrayBuffer()], { type: mime })
9 | form.append('file', blob, 'tmp.' + ext)
10 | let res = await fetch('https://ichikaa.xyz/upload', {
11 | method: 'post',
12 | body: form
13 | })
14 | if (!res.ok) throw await res.text()
15 | let img = await res.json()
16 | return img.result.url
17 | }
18 |
--------------------------------------------------------------------------------
/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 |
15 | export default async buffer => {
16 | const { ext, mime } = await fileTypeFromBuffer(buffer)
17 | let form = new FormData()
18 | const blob = new Blob([buffer.toArrayBuffer()], { type: mime })
19 | form.append('file', blob, 'tmp.' + ext)
20 | let res = await fetch('https://telegra.ph/upload', {
21 | method: 'POST',
22 | body: form
23 | })
24 | let img = await res.json()
25 | if (img.error) throw img.error
26 | return 'https://telegra.ph' + img[0].src
27 | }
28 |
--------------------------------------------------------------------------------
/lib/util.js:
--------------------------------------------------------------------------------
1 | import fetch from 'node-fetch'
2 |
3 | export const shortUrl = async (url) => {
4 | return await (await fetch(`https://tinyurl.com/api-create.php?url=${url}`)).text()
5 | }
6 |
--------------------------------------------------------------------------------
/lib/webp2mp4.js:
--------------------------------------------------------------------------------
1 | import fetch from 'node-fetch';
2 | import { FormData, Blob } from 'formdata-node';
3 | import { JSDOM } from 'jsdom';
4 | import https from 'https';
5 |
6 | let agent = new https.Agent({ rejectUnauthorized: false });
7 |
8 | /**
9 | *
10 | * @param {Buffer|String} source
11 | */
12 | async function webp2mp4(source) {
13 | let form = new FormData()
14 | let isUrl = typeof source === 'string' && /https?:\/\//.test(source)
15 | const blob = !isUrl && new Blob([source.toArrayBuffer()])
16 | form.append('new-image-url', isUrl ? blob : '')
17 | form.append('new-image', isUrl ? '' : blob, 'image.webp')
18 | let res = await fetch('https://s6.ezgif.com/webp-to-mp4', {
19 | method: 'POST',
20 | body: form,
21 | agent
22 | })
23 | let html = await res.text()
24 | let { document } = new JSDOM(html).window
25 | let form2 = new FormData()
26 | let obj = {}
27 | for (let input of document.querySelectorAll('form input[name]')) {
28 | obj[input.name] = input.value
29 | form2.append(input.name, input.value)
30 | }
31 | let res2 = await fetch('https://ezgif.com/webp-to-mp4/' + obj.file, {
32 | method: 'POST',
33 | body: form2,
34 | agent
35 | })
36 | let html2 = await res2.text()
37 | let { document: document2 } = new JSDOM(html2).window
38 | return new URL(document2.querySelector('div#output > p.outfile > video > source').src, res2.url).toString()
39 | }
40 |
41 | async function webp2png(source) {
42 | let form = new FormData()
43 | let isUrl = typeof source === 'string' && /https?:\/\//.test(source)
44 | const blob = !isUrl && new Blob([source.toArrayBuffer()])
45 | form.append('new-image-url', isUrl ? blob : '')
46 | form.append('new-image', isUrl ? '' : blob, 'image.webp')
47 | let res = await fetch('https://s6.ezgif.com/webp-to-png', {
48 | method: 'POST',
49 | body: form,
50 | agent
51 | })
52 | let html = await res.text()
53 | let { document } = new JSDOM(html).window
54 | let form2 = new FormData()
55 | let obj = {}
56 | for (let input of document.querySelectorAll('form input[name]')) {
57 | obj[input.name] = input.value
58 | form2.append(input.name, input.value)
59 | }
60 | let res2 = await fetch('https://ezgif.com/webp-to-png/' + obj.file, {
61 | method: 'POST',
62 | body: form2,
63 | agent
64 | })
65 | let html2 = await res2.text()
66 | let { document: document2 } = new JSDOM(html2).window
67 | return new URL(document2.querySelector('div#output > p.outfile > img').src, res2.url).toString()
68 | }
69 |
70 | export {
71 | webp2mp4,
72 | webp2png
73 | }
74 |
--------------------------------------------------------------------------------
/lib/y2mate.js:
--------------------------------------------------------------------------------
1 | import fetch from 'node-fetch';
2 | import { JSDOM } from 'jsdom'
3 |
4 | function post(url, formdata) {
5 | return fetch(url, {
6 | method: 'POST',
7 | headers: {
8 | accept: "*/*",
9 | 'accept-language': "en-US,en;q=0.9",
10 | 'content-type': "application/x-www-form-urlencoded; charset=UTF-8"
11 | },
12 | body: new URLSearchParams(Object.entries(formdata))
13 | })
14 | }
15 | const ytIdRegex = /(?:http(?:s|):\/\/|)(?:(?:www\.|)youtube(?:\-nocookie|)\.com\/(?:shorts\/)?(?:watch\?.*(?:|\&)v=|embed\/|v\/)|youtu\.be\/)([-_0-9A-Za-z]{11})/
16 |
17 | /**
18 | * Download YouTube Video via y2mate
19 | * @param {String} url YouTube Video URL
20 | * @param {String} quality (avaiable: `144p`, `240p`, `360p`, `480p`, `720p`, `1080p`, `1440p`, `2160p`)
21 | * @param {String} type (avaiable: `mp3`, `mp4`)
22 | * @param {String} bitrate (avaiable for video: `144`, `240`, `360`, `480`, `720`, `1080`, `1440`, `2160`)
23 | * (avaiable for audio: `128`)
24 | * @param {String} server (avaiable: `id4`, `en60`, `en61`, `en68`)
25 | */
26 | async function yt(url, quality, type, bitrate, server = 'en68') {
27 | if (!ytIdRegex.test(url)) throw 'Invalid URL'
28 | let ytId = ytIdRegex.exec(url)
29 | url = 'https://youtu.be/' + ytId[1]
30 | let res = await post(`https://www.y2mate.com/mates/${server}/analyze/ajax`, {
31 | url,
32 | q_auto: 0,
33 | ajax: 1
34 | })
35 | let json = await res.json()
36 | let { document } = (new JSDOM(json.result)).window
37 | let tables = document.querySelectorAll('table')
38 | let table = tables[{ mp4: 0, mp3: 1 }[type] || 0]
39 | let list
40 | switch (type) {
41 | case 'mp4':
42 | list = Object.fromEntries([...table.querySelectorAll('td > a[href="#"]')].filter(v => !/\.3gp/.test(v.innerHTML)).map(v => [v.innerHTML.match(/.*?(?=\()/)[0].trim(), v.parentElement.nextSibling.nextSibling.innerHTML]))
43 | break
44 | case 'mp3':
45 | list = {
46 | '128kbps': table.querySelector('td > a[href="#"]').parentElement.nextSibling.nextSibling.innerHTML
47 | }
48 | break
49 | default:
50 | list = {}
51 | }
52 | let filesize = list[quality]
53 | let id = /var k__id = "(.*?)"/.exec(document.body.innerHTML) || ['', '']
54 | let thumb = document.querySelector('img').src
55 | let title = document.querySelector('b').innerHTML
56 | let res2 = await post(`https://www.y2mate.com/mates/${server}/convert`, {
57 | type: 'youtube',
58 | _id: id[1],
59 | v_id: ytId[1],
60 | ajax: '1',
61 | token: '',
62 | ftype: type,
63 | fquality: bitrate
64 | })
65 | let json2 = await res2.json()
66 | let KB = parseFloat(filesize) * (1000 * /MB$/.test(filesize))
67 | return {
68 | dl_link: / m
2 | handler.before = m => {
3 | let user = global.DATABASE.data.users[m.sender]
4 | if (user.afk > -1) {
5 | m.reply(`
6 | You stop AFK${user.afkReason ? ' after ' + user.afkReason : ''}
7 | During ${clockString(new Date - user.afk)}
8 | `.trim())
9 | user.afk = -1
10 | user.afkReason = ''
11 | }
12 | let jids = [...new Set([...(m.mentionedJid || []), ...(m.quoted ? [m.quoted.sender] : [])])]
13 | for (let jid of jids) {
14 | let user = global.DATABASE.data.users[jid]
15 | if (!user) continue
16 | let afkTime = user.afk
17 | if (!afkTime || afkTime < 0) continue
18 | let reason = user.afkReason || ''
19 | m.reply(`
20 | Don't tag him!
21 | He is AFK ${reason ? ' with reason ' + reason : 'no reason'}
22 | During ${clockString(new Date - afkTime)}
23 | `.trim())
24 | }
25 | return true
26 | }
27 |
28 | export default handler
29 |
30 | function clockString(ms) {
31 | let h = isNaN(ms) ? '--' : Math.floor(ms / 3600000)
32 | let m = isNaN(ms) ? '--' : Math.floor(ms / 60000) % 60
33 | let s = isNaN(ms) ? '--' : Math.floor(ms / 1000) % 60
34 | return [h, m, s].map(v => v.toString().padStart(2, 0) ).join(':')
35 | }
36 |
--------------------------------------------------------------------------------
/plugins/_antilink.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created By LUA SER OFC
3 | * CopyRight 2024 MIT License
4 | * My Github : https://github.com/xxirfanx
5 | * My Instagram : https://instagram.com/luaserofc
6 | * My Youtube : https://youtube.com/@luaserofc
7 | */
8 |
9 | const linkRegex = /chat.whatsapp.com\/(?:invite\/)?([0-9A-Za-z]{20,24})/i
10 |
11 | export async function before(m, {conn, isAdmin, isBotAdmin }) {
12 | if (m.isBaileys && m.fromMe)
13 | return !0
14 | if (!m.isGroup) return !1
15 | let chat = global.db.data.chats[m.chat]
16 | let bot = global.db.data.settings[this.user.jid] || {}
17 | const isGroupLink = linkRegex.exec(m.text)
18 |
19 | if (chat.antiLink && isGroupLink && !isAdmin) {
20 | if (isBotAdmin) {
21 | const linkThisGroup = `https://chat.whatsapp.com/${await this.groupInviteCode(m.chat)}`
22 | if (m.text.includes(linkThisGroup)) return !0
23 | }
24 | await conn.reply(m.chat, `*⛽ Detected Link*
25 |
26 | We do not allow links from other groups
27 | I'm sorry *@${m.sender.split('@')[0]}* you will be expelled from the group ${isBotAdmin ? '' : '\n\n Im not an admin so I cant expel you :"v'}`, null, { mentions: [m.sender] } )
28 | if (isBotAdmin && chat.antiLink) {
29 | await conn.sendMessage(m.chat, { delete: m.key })
30 | await conn.groupParticipantsUpdate(m.chat, [m.sender], 'remove')
31 | } else if (!chat.antiLink) return //m.reply('')
32 | }
33 | return !0
34 | }
35 |
--------------------------------------------------------------------------------
/plugins/_cek.js:
--------------------------------------------------------------------------------
1 | let handler = async ( m ) => {
2 | m.reply('Hello!')
3 | }
4 |
5 | handler.command = /^(cek|tes|alive|p|a)$/i
6 |
7 | export default handler
8 |
--------------------------------------------------------------------------------
/plugins/_memfess-Ans.js:
--------------------------------------------------------------------------------
1 | export async function before(m) {
2 | if (!m.chat.endsWith('@s.whatsapp.net')) return !0;
3 | this.menfess = this.menfess ? this.menfess : {}
4 | let mf = Object.values(this.menfess).find(v => v.status === false && v.penerima == m.sender)
5 | if (!mf) return !0
6 | console.log(m)
7 | if (m.text === 'Reply' && m.quoted.mtype == 'buttonsMessage') return m.reply("Please send your reply message.");
8 | let txt = `Hai @${mf.dari.split('@')[0]}, you received this reply.\n\nReply message:\n${m.text}\n`.trim();
9 | await this.reply(mf.dari, txt, null).then(() => {
10 | m.reply('Menfess reply sent.')
11 | this.delay(1000)
12 | delete this.menfess[mf.id]
13 | return !0
14 | })
15 | }
--------------------------------------------------------------------------------
/plugins/_templateResponse.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.message.buttonsResponseMessage || m.message.templateButtonReplyMessage || m.message.listResponseMessage || m.message.interactiveResponseMessage || m.message.pollUpdateMessage || m.message.editedMessage)) return
11 |
12 | let id = (m.mtype === 'conversation') ? m.message.conversation : (m.mtype == 'imageMessage') ? m.message.imageMessage.caption : (m.mtype == 'videoMessage') ? m.message.videoMessage.caption : (m.mtype == 'extendedTextMessage') ? m.message.extendedTextMessage.text : (m.mtype == 'buttonsResponseMessage') ? m.message.buttonsResponseMessage.selectedButtonId : (m.mtype == 'listResponseMessage') ? m.message.listResponseMessage.singleSelectReply.selectedRowId : (m.mtype == 'templateButtonReplyMessage') ? m.message.templateButtonReplyMessage.selectedId : (m.mtype == 'interactiveResponseMessage') ? JSON.parse(m.msg.nativeFlowResponseMessage.paramsJson).id : (m.mtype == 'templateButtonReplyMessage') ? appenTextMessage(m.msg.selectedId, chatUpdate) : (m.mtype === 'messageContextInfo') ? (m.message.buttonsResponseMessage?.selectedButtonId || m.message.listResponseMessage?.singleSelectReply.selectedRowId || m.text) : (m.mtype === 'editedMessage') ? m.message.editedMessage.message.protocolMessage.editedMessage.conversation ? m.message.editedMessage.message.protocolMessage.editedMessage.conversation : m.message.editedMessage.message.protocolMessage.editedMessage.extendedTextMessage.text : ''
13 |
14 | try {
15 |
16 | let messages = await generateWAMessage(m.chat, { text: id, mentions: m.mentionedJid }, {
17 | userJid: this.user.id,
18 | quoted: m.quoted && m.quoted.fakeObj
19 | })
20 | messages.key.fromMe = areJidsSameUser(m.sender, this.user.id)
21 | messages.key.id = m.key.id
22 | messages.pushName = m.name
23 | if (m.isGroup)
24 | messages.key.participant = messages.participant = m.sender
25 | let msg = {
26 | ...chatUpdate,
27 | messages: [proto.WebMessageInfo.fromObject(messages)].map(v => (v.conn = this, v)),
28 | type: 'append'
29 | }
30 | this.ev.emit('messages.upsert', msg)
31 | } catch (e) {
32 | false
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/plugins/_ttt.js:
--------------------------------------------------------------------------------
1 | import { format } from 'util'
2 |
3 | let debugMode = !1
4 |
5 | let winScore = 4999
6 | let playScore = 99
7 |
8 | export async function before(m) {
9 | let ok
10 | let isWin = !1
11 | let isTie = !1
12 | let isSurrender = !1
13 | this.game = this.game ? this.game : {}
14 | let room = Object.values(this.game).find(room => room.id && room.game && room.state && room.id.startsWith('tictactoe') && [room.game.playerX, room.game.playerO].includes(m.sender) && room.state == 'PLAYING')
15 | if (room) {
16 | // m.reply(`[DEBUG]\n${parseInt(m.text)}`)
17 | if (!/^([1-9]|(me)?nyerah|surr?ender)$/i.test(m.text))
18 | return !0
19 | isSurrender = !/^[1-9]$/.test(m.text)
20 | if (m.sender !== room.game.currentTurn) { // nek wayahku
21 | if (!isSurrender)
22 | return !0
23 | }
24 | if (debugMode)
25 | m.reply('[DEBUG]\n' + require('util').format({
26 | isSurrender,
27 | text: m.text
28 | }))
29 | if (!isSurrender && 1 > (ok = room.game.turn(m.sender === room.game.playerO, parseInt(m.text) - 1))) {
30 | m.reply({
31 | '-3': 'Game has ended',
32 | '-2': 'Invalid',
33 | '-1': 'Position Invalid',
34 | 0: 'Position Invalid',
35 | }[ok])
36 | return !0
37 | }
38 | if (m.sender === room.game.winner)
39 | isWin = true
40 | else if (room.game.board === 511)
41 | isTie = true
42 | let arr = room.game.render().map(v => {
43 | return {
44 | X: '❌',
45 | O: '⭕',
46 | 1: '1️⃣',
47 | 2: '2️⃣',
48 | 3: '3️⃣',
49 | 4: '4️⃣',
50 | 5: '5️⃣',
51 | 6: '6️⃣',
52 | 7: '7️⃣',
53 | 8: '8️⃣',
54 | 9: '9️⃣',
55 | }[v]
56 | })
57 | if (isSurrender) {
58 | room.game._currentTurn = m.sender === room.game.playerX
59 | isWin = true
60 | }
61 | let winner = isSurrender ? room.game.currentTurn : room.game.winner
62 | let str = `
63 | ${arr.slice(0, 3).join('')}
64 | ${arr.slice(3, 6).join('')}
65 | ${arr.slice(6).join('')}
66 | ${isWin ? `@${winner.split('@')[0]} Win! (+${winScore} XP)` : isTie ? `Game over (+${playScore} XP)` : `turn ${['❌', '⭕'][1 * room.game._currentTurn]} (@${room.game.currentTurn.split('@')[0]})`}
67 | ❌: @${room.game.playerX.split('@')[0]}
68 | ⭕: @${room.game.playerO.split('@')[0]}
69 | Type *giveup* for giveup
70 | Room ID: ${room.id}
71 | `.trim()
72 | let users = db.data.users
73 | if ((room.game._currentTurn ^ isSurrender ? room.x : room.o) !== m.chat)
74 | room[room.game._currentTurn ^ isSurrender ? 'x' : 'o'] = m.chat
75 | const btn = isTie ? ['TicTacToe', '/ttt'] : ['giveup', 'giveup']
76 | if (room.x !== room.o)
77 | await this.reply(room.x, str, m, {
78 | mentions: this.parseMention(str)
79 | })
80 | await this.reply(room.o, str, m, {
81 | mentions: this.parseMention(str)
82 | })
83 | if (isTie || isWin) {
84 | users[room.game.playerX].exp += playScore
85 | users[room.game.playerO].exp += playScore
86 | if (isWin)
87 | users[winner].exp += winScore - playScore
88 | if (debugMode)
89 | m.reply('[DEBUG]\n' + format(room))
90 | delete this.game[room.id]
91 | }
92 | }
93 | return !0
94 | }
--------------------------------------------------------------------------------
/plugins/afk.js:
--------------------------------------------------------------------------------
1 | let handler = async (m, { text }) => {
2 | let user = global.DATABASE.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 [reason]']
10 | handler.tags = ['main']
11 | handler.command = /^afk$/i
12 |
13 | export default handler
--------------------------------------------------------------------------------
/plugins/ai-animediff.js:
--------------------------------------------------------------------------------
1 | import fetch from "node-fetch"
2 |
3 | let handler = async (m, { conn, text, usedPrefix, command }) => {
4 | let wm = global.me
5 |
6 | if (!text) throw `This command generates image from texts\n\n Example usage\n${ usedPrefix + command } 1girl, blush, megane, school uniform`
7 | await m.reply('*Processing image*')
8 | await conn.relayMessage(m.chat, { reactionMessage: { key: m.key, text: '⌛' }}, { messageId: m.key.id })
9 | try {
10 | let url = `https://api.xyroinee.xyz/api/ai/animediffusion?q=${text}&apikey=${global.xyro}`
11 | await conn.sendFile(m.chat, await(await fetch(url)).buffer(), 'image.jpg', wm, m)
12 | m.react(done)
13 | } catch (e) {
14 | console.log(e)
15 | m.reply(eror)
16 | }
17 |
18 | }
19 |
20 |
21 | handler.help = ['animediff ']
22 | handler.tags = ['ai']
23 | handler.command = /^(animediff)$/i
24 |
25 | export default handler
--------------------------------------------------------------------------------
/plugins/ai-animediff2.js:
--------------------------------------------------------------------------------
1 | /* -------------------------------------------------------*/
2 | /* [❗] [❗] [❗] */
3 | /* */
4 | /* |- [ ⚠ ] - CODE CREDITS - [ ⚠ ] -| */
5 | /* —◉ DEVELOPED BY LUA SER OFC: */
6 | /* ◉ git : (https://github.com/xxirfanx) */
7 | /* */
8 | /* [❗] [❗] [❗] */
9 | /* -------------------------------------------------------*/
10 | import fetch from "node-fetch"
11 |
12 | let handler = async (m, { conn, text, usedPrefix, command }) => {
13 | let wm = global.me
14 | if (!text) throw `This command generates image from texts\n\n Example usage\n${ usedPrefix + command } 1girl, blush, megane, school uniform`
15 | await m.reply('*Processing image*')
16 | await conn.relayMessage(m.chat, { reactionMessage: { key: m.key, text: '⌛' }}, { messageId: m.key.id })
17 | try {
18 | let ff = await fetch(`https://api.neoxr.eu/api/waifudiff?q=${text}`)
19 | let anu = await ff.json()
20 | await conn.sendFile(m.chat, anu.data.url, 'image.jpg', wm, m)
21 | m.react('🎐')
22 | } catch (e) {
23 | console.log(e)
24 | m.reply(eror)
25 | }
26 | }
27 |
28 | handler.help = ['animediff2 ']
29 | handler.tags = ['ai']
30 | handler.command = /^(animediff2)$/i
31 |
32 | export default handler
33 |
--------------------------------------------------------------------------------
/plugins/ai-chatgpt.js:
--------------------------------------------------------------------------------
1 | // made by lua ser ofc
2 | import fetch from 'node-fetch'
3 |
4 | let handler = async (m, { text, usedPrefix, command }) => {
5 | if (!text) throw `Hey is there anything I can help you with??`
6 | let order = { text: wait, mentions: [m.sender], contextInfo: { forwardingScore: 256, isForwarded: true }};
7 | let aii = await fetch(`https://api.lolhuman.xyz/api/openai?apikey=${apilol}
8 | &text=${text}&user=user-unique-en`)
9 | let oke = await aii.json()
10 | let { key } = await conn.sendMessage(m.chat, order, { quoted: m });
11 | await new Promise(resolve => setTimeout(resolve, 2000));
12 | await conn.sendMessage(m.chat, { text: `${oke.result}`, edit: key }, { quoted: m });
13 | }
14 |
15 | handler.help = ['ai', 'openai', 'gpt']
16 | handler.tags = ['ai']
17 | handler.command = /^(ai|openai|gpt)$/i
18 |
19 | export default handler
20 |
--------------------------------------------------------------------------------
/plugins/anonymous_chat.js:
--------------------------------------------------------------------------------
1 | async function handler(m, { command }) {
2 | this.anonymous = this.anonymous ? this.anonymous : {}
3 | switch (command) {
4 | case 'next':
5 | case 'leave': {
6 | let room = Object.values(this.anonymous).find(room => room.check(m.sender))
7 | if (!room) return this.reply(m.chat, '_You are not currently in anonymous chat_\n\ntype *.start* to find partners', m)
8 | m.reply('Ok')
9 | let other = room.other(m.sender)
10 | if (other) await this.reply(other, '_Partners leave chat_\n\ntype *.start* to find partners', m)
11 | delete this.anonymous[room.id]
12 | if (command === 'leave') break
13 | }
14 | case 'start': {
15 | if (Object.values(this.anonymous).find(room => room.check(m.sender))) return this.reply(m.chat, '_You are still in the anonymous chat, waiting for a partner_\n\ntype *.leave* to get out of', m)
16 | let room = Object.values(this.anonymous).find(room => room.state === 'WAITING' && !room.check(m.sender))
17 | if (room) {
18 | await this.reply(room.a, '_Partner found!_', m)
19 | room.b = m.sender
20 | room.state = 'CHATTING'
21 | await this.reply(room.b, '_Partner found!_', m)
22 | } else {
23 | let id = + new Date
24 | this.anonymous[id] = {
25 | id,
26 | a: m.sender,
27 | b: '',
28 | state: 'WAITING',
29 | check: function (who = '') {
30 | return [this.a, this.b].includes(who)
31 | },
32 | other: function (who = '') {
33 | return who === this.a ? this.b : who === this.b ? this.a : ''
34 | },
35 | }
36 | await this.reply(m.chat, '_Waiting for partners..._\n\ntype *.leave* to get out of', m)
37 | }
38 | break
39 | }
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
50 |
--------------------------------------------------------------------------------
/plugins/anonymous_chat_.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 | }
15 |
--------------------------------------------------------------------------------
/plugins/cmd-del.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 `No hash`
5 | let sticker = global.db.data.sticker
6 | if (sticker[hash] && sticker[hash].locked) throw 'You do not have permission to remove this sticker prompt'
7 | delete sticker[hash]
8 | m.reply(`Succeed!`)
9 | }
10 |
11 |
12 | handler.help = ['cmd'].map(v => 'del' + v + ' ')
13 | handler.tags = ['database']
14 | handler.command = ['delcmd']
15 | handler.premium = true
16 |
17 | export default handler
--------------------------------------------------------------------------------
/plugins/cmd-list.js:
--------------------------------------------------------------------------------
1 | let handler = async (m, { conn }) => {
2 | conn.reply(m.chat, `
3 | *LIST HASH*
4 | \`\`\`
5 | ${Object.entries(global.db.data.sticker).map(([key, value], index) => `${index + 1}. ${value.locked ? `(Locked) ${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
--------------------------------------------------------------------------------
/plugins/cmd-lock.js:
--------------------------------------------------------------------------------
1 | let handler = async (m, { conn, text, usedPrefix, command }) => {
2 | if (!m.quoted) throw 'Reply Message!'
3 | if (!m.quoted.fileSha256) throw 'SHA256 Hash Missing'
4 | let sticker = global.db.data.sticker
5 | let hash = m.quoted.fileSha256.toString('hex')
6 | if (!(hash in sticker)) throw 'Hash not found in database'
7 | sticker[hash].locked = !/^un/i.test(command)
8 | m.reply('Done!')
9 | }
10 | handler.help = ['un', ''].map(v => v + 'lockcmd')
11 | handler.tags = ['database']
12 | handler.command = /^(un)?lockcmd$/i
13 | handler.premium = true
14 |
15 | export default handler
--------------------------------------------------------------------------------
/plugins/cmd-set.js:
--------------------------------------------------------------------------------
1 | let handler = async (m, { text, usedPrefix, command }) => {
2 | global.db.data.sticker = global.db.data.sticker || {}
3 | if (!m.quoted) throw `Reply to stickers with commands *${usedPrefix + command}*`
4 | if (!m.quoted.fileSha256) throw 'SHA256 Hash Missing'
5 | if (!text) throw `Use:\n${usedPrefix + command} \n\nExample:\n${usedPrefix + command} tes`
6 | let sticker = global.db.data.sticker
7 | let hash = m.quoted.fileSha256.toString('base64')
8 | if (sticker[hash] && sticker[hash].locked) throw 'You do not have permission to change the order of this sticker'
9 | sticker[hash] = {
10 | text,
11 | mentionedJid: m.mentionedJid,
12 | creator: m.sender,
13 | at: + new Date,
14 | locked: false,
15 | }
16 | m.reply(`Succeed!`)
17 | }
18 |
19 | handler.help = handler.alias = ['cmdset']
20 | handler.tags = ['database']
21 | handler.command = /^((set|add)cmd|cmd(set|add))$/i
22 |
23 | handler.database = true
24 |
25 | export default handler
26 |
--------------------------------------------------------------------------------
/plugins/creator.js:
--------------------------------------------------------------------------------
1 | import fetch from 'node-fetch'
2 | let handler = async (m, { conn, usedPrefix, text, args, command }) => {
3 | let who = m.mentionedJid && m.mentionedJid[0] ? m.mentionedJid[0] : m.fromMe ? conn.user.jid : m.sender
4 | let pp = await conn.profilePictureUrl(who).catch(_ => thumbnailUrl.getRandom())
5 | let name = await conn.getName(who)
6 |
7 | const sentMsg = await conn.sendContactArray(m.chat, [
8 | [nomorown, `${await conn.getName(nomorown + '@s.whatsapp.net')}`, `💌 Developer Bot `, `Not Famous`, `sousakura666@gmail.com`, `🇯🇵 japan`, `📍 https://xxirfanx.github.io`, `👤 Owner zoro Bot`],
9 | [`${conn.user.jid.split('@')[0]}`, `${await conn.getName(conn.user.jid)}`, `🎈 Whatsapp Bot`, `📵 Dont Spam`, `Nothing`, `🇯🇵 japan`, `📍 https://github.com/xxirfanx/zoromd`, `Just a normal bot that sometimes has an error ☺`]
10 | ], fkontak)
11 | await conn.reply(m.chat,`Hello @${m.sender.split(`@`)[0]} Thats my owner, dont spam or i will block u`, sentMsg, {
12 | mentions: [m.sender]
13 | })
14 | }
15 |
16 | handler.help = ['owner', 'creator']
17 | handler.tags = ['info']
18 |
19 | handler.command = /^(owner|creator)$/i
20 |
21 | export default handler
22 |
--------------------------------------------------------------------------------
/plugins/downloader-fb.js:
--------------------------------------------------------------------------------
1 | import fetch from 'node-fetch'
2 | import fg from 'api-dylux'
3 |
4 |
5 | const handler = async (m, { conn, args, usedPrefix, command }) => {
6 | if (!args[0]) {
7 | throw `✳️ Please send the link of a Facebook video\n\n📌 EXAMPLE :\n*${usedPrefix + command}* https://www.facebook.com/Ankursajiyaan/videos/981948876160874/?mibextid=rS40aB7S9Ucbxw6v`;
8 | }
9 |
10 | const urlRegex = /^(?:https?:\/\/)?(?:www\.)?(?:facebook\.com|fb\.watch)\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/i;
11 | if (!urlRegex.test(args[0])) {
12 | throw '⚠️ PLEASE GIVE A VALID URL.'
13 | }
14 |
15 | await conn.relayMessage(m.chat, { reactionMessage: { key: m.key, text: '⌛' }}, { messageId: m.key.id })
16 |
17 | try {
18 | const result = await fg.fbdl(args[0]);
19 | const tex = `
20 | ⊱ ─── {* Facebook dwd *} ─── ⊰
21 | ↳ *VIDEO TITLE:* ${result.title}
22 | ⊱ ────── {⋆♬⋆} ────── ⊰`
23 |
24 | const response = await fetch(result.videoUrl)
25 | const arrayBuffer = await response.arrayBuffer()
26 | const videoBuffer = Buffer.from(arrayBuffer)
27 |
28 | conn.sendFile(m.chat, videoBuffer, 'fb.mp4', tex, m)
29 | } catch (error) {
30 | console.log(error)
31 | m.reply('⚠️ An error occurred while processing the request. Please try again later.')
32 | }
33 | }
34 |
35 | handler.help = ['facebook ']
36 | handler.tags = ['downloader']
37 | handler.command = /^((facebook|fb)(downloder|dl)?)$/i
38 |
39 | export default handler
40 |
--------------------------------------------------------------------------------
/plugins/downloader-gddl.js:
--------------------------------------------------------------------------------
1 | import fetch from 'node-fetch'
2 | import { sizeFormatter } from 'human-readable'
3 | let formatSize = sizeFormatter({
4 | std: 'JEDEC', decimalPlaces: 2, keepTrailingZeroes: false, render: (literal, symbol) => `${literal} ${symbol}B`
5 | })
6 |
7 | let handler = async (m, { conn, args }) => {
8 | if (!args[0]) throw 'Input URL'
9 | GDriveDl(args[0]).then(async (res) => {
10 | if (!res) throw res
11 | await m.reply(JSON.stringify(res, null, 2))
12 | conn.sendMessage(m.chat, { document: { url: res.downloadUrl }, fileName: res.fileName, mimetype: res.mimetype }, { quoted: m })
13 | })
14 | }
15 |
16 | handler.help = ['gdrive']
17 | handler.tags = ['downloader']
18 | handler.command = /^(gdrive)$/i
19 | handler.disabled = false
20 |
21 | export default handler
22 |
23 | async function GDriveDl(url) {
24 | let id
25 | if (!(url && url.match(/drive\.google/i))) throw 'Invalid URL'
26 | id = (url.match(/\/?id=(.+)/i) || url.match(/\/d\/(.*?)\//))[1]
27 | if (!id) throw 'ID Not Found'
28 | let res = await fetch(`https://drive.google.com/uc?id=${id}&authuser=0&export=download`, {
29 | method: 'post',
30 | headers: {
31 | 'accept-encoding': 'gzip, deflate, br',
32 | 'content-length': 0,
33 | 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
34 | 'origin': 'https://drive.google.com',
35 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
36 | 'x-client-data': 'CKG1yQEIkbbJAQiitskBCMS2yQEIqZ3KAQioo8oBGLeYygE=',
37 | 'x-drive-first-party': 'DriveWebUi',
38 | 'x-json-requested': 'true'
39 | }
40 | })
41 | let { fileName, sizeBytes, downloadUrl } = JSON.parse((await res.text()).slice(4))
42 | if (!downloadUrl) throw 'Link Download Limit!'
43 | let data = await fetch(downloadUrl)
44 | if (data.status !== 200) throw data.statusText
45 | return { downloadUrl, fileName, fileSize: formatSize(sizeBytes), mimetype: data.headers.get('content-type') }
46 | }
--------------------------------------------------------------------------------
/plugins/downloader-git.js:
--------------------------------------------------------------------------------
1 | import fetch from 'node-fetch'
2 | const regex = /(?:https|git)(?::\/\/|@)github\.com[\/:]([^\/:]+)\/(.+)/i
3 |
4 | let handler = async (m, {conn, text, args, usedPrefix, command }) => {
5 | if (!args[0]) throw `Example user ${usedPrefix}${command} xxirfanx/zoromd`
6 | let [usr, rep] = text.split`/`
7 | let url = `https://api.github.com/repos/${encodeURIComponent(usr)}/${encodeURIComponent(rep)}/zipball`
8 | let name = `${encodeURIComponent(rep)}.zip`
9 | m.reply(`D o w n l o a d i n g. . .`)
10 | conn.sendFile(m.chat, url, name, null, m)
11 | }
12 |
13 | handler.help = ['gitclone /']
14 | handler.tags = ['downloader']
15 | handler.command = /gitclone/i
16 |
17 | export default handler
--------------------------------------------------------------------------------
/plugins/downloader-ig.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created By LUA SER OFC
3 | * CopyRight 2024 MIT License
4 | * My Github : https://github.com/xxirfanx
5 | * My Instagram : https://instagram.com/luaserofc
6 | * My Youtube : https://youtube.com/@luaserofc
7 | */
8 |
9 | const ig = await import('@sasmeee/igdl');
10 | import fetch from 'node-fetch';
11 |
12 | var handler = async (m, { args, conn, usedPrefix, command }) => {
13 | if (!args[0]) throw `Ex:\n${usedPrefix}${command} Link put`;
14 |
15 | conn.reply(m.chat, 'Currently downloading video...', m);
16 |
17 | let res = await ig.default(args[0]);
18 | let media = await res[0].download_link;
19 |
20 | const response = await fetch(media)
21 | const arrayBuffer = await response.arrayBuffer()
22 | const videoBuffer = Buffer.from(arrayBuffer)
23 |
24 | if (!res) throw 'Can\'t download the post';
25 |
26 | conn.sendFile(m.chat, videoBuffer, 'ig.mp4', null, m)
27 | };
28 |
29 | handler.help = ['instagram'];
30 | handler.tags = ['downloader'];
31 | handler.command = /^(ig(dl)?|instagram(dl)?|insta)$/i;
32 |
33 | export default handler;
34 |
--------------------------------------------------------------------------------
/plugins/downloader-mediafire.js:
--------------------------------------------------------------------------------
1 | import { lookup } from 'mime-types'
2 | import { mediafiredl } from '@bochilteam/scraper'
3 |
4 | let handler = async (m, { conn, args }) => {
5 | if (!args[0]) throw 'Input URL'
6 | if (!/https?:\/\/(www\.)?mediafire\.com/.test(args[0])) throw 'Invalid URL'
7 | let res = await mediafiredl(args[0])
8 | let mimetype = await lookup(res.url)
9 | delete res.url2
10 | m.reply(Object.keys(res).map(v => `*• ${v.capitalize()}:* ${res[v]}`).join('\n') + '\n\n_Sending file..._')
11 | conn.sendMessage(m.chat, { document: { url: res.url }, fileName: res.filename, mimetype }, { quoted: m })
12 | }
13 | handler.help = handler.alias = ['mediafire']
14 | handler.tags = ['downloader']
15 | handler.command = /^(mediafire)$/i
16 |
17 | export default handler
18 |
--------------------------------------------------------------------------------
/plugins/downloader-play.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created By LUA SER OFC
3 | * CopyRight 2024 MIT License
4 | * My Github : https://github.com/xxirfanx
5 | * My Instagram : https://instagram.com/luaserofc
6 | * My Youtube : https://youtube.com/@luaserofc
7 | */
8 |
9 | import yts from 'yt-search';
10 |
11 | let handler = async (m, { conn, command, text, usedPrefix }) => {
12 | if (!text) throw ` 🦄Use example *${usedPrefix + command}* Somewhere Only We Know`;
13 | let res = await yts(text)
14 | let vid = res.videos[0]
15 | if (!vid) throw `🍊 Audio not find title song `;
16 | let { title, description, thumbnail, videoId, timestamp, views, ago, url } = vid
17 | //const url = 'https://www.youtube.com/watch?v=' + videoId
18 | m.react(`🐢`)
19 | let play = `
20 | 📺 *Title:* ${vid.title}
21 | ⌛ *Duration:* ${vid.timestamp}
22 | 👀 *Views:* ${vid.views.toLocaleString()}
23 | 📅 *Upload:* ${vid.ago}
24 | `
25 | await conn.sendButton2(m.chat, play, '> Zoro md', thumbnail, [
26 | ['🎶 MP3', `${usedPrefix}vfmp3 ${url}`]], null, null, m)
27 | }
28 |
29 | handler.help = ['play'].map((v) => v + ' ')
30 | handler.tags = ['downloader']
31 | handler.command = ['play', 'song']
32 | handler.disabled = false
33 |
34 | export default handler
35 |
--------------------------------------------------------------------------------
/plugins/downloader-sfile.js:
--------------------------------------------------------------------------------
1 | import cheerio from 'cheerio'
2 | import fetch from 'node-fetch'
3 |
4 | let handler = async (m, { conn, text }) => {
5 | if (text.match(/(https:\/\/sfile.mobi\/)/gi)) {
6 | let res = await sfileDl(text)
7 | if (!res) throw 'Error :/'
8 | await m.reply(Object.keys(res).map(v => `*• ${v.capitalize()}:* ${res[v]}`).join('\n') + '\n\n_Sending file..._')
9 | conn.sendMessage(m.chat, { document: { url: res.download }, fileName: res.filename, mimetype: res.mimetype }, { quoted: m })
10 | } else if (text) {
11 | let [query, page] = text.split`|`
12 | let res = await sfileSearch(query, page)
13 | if (!res.length) throw `Query "${text}" not found :/`
14 | res = res.map((v) => `*Title:* ${v.title}\n*Size:* ${v.size}\n*Link:* ${v.link}`).join`\n\n`
15 | m.reply(res)
16 | } else throw 'Input Query / Sfile Url!'
17 | }
18 | handler.help = handler.alias = ['sfile']
19 | handler.tags = ['downloader']
20 | handler.command = /^(sfile)$/i
21 |
22 | export default handler
23 |
24 | async function sfileSearch(query, page = 1) {
25 | let res = await fetch(`https://sfile.mobi/search.php?q=${query}&page=${page}`)
26 | let $ = cheerio.load(await res.text())
27 | let result = []
28 | $('div.list').each(function () {
29 | let title = $(this).find('a').text()
30 | let size = $(this).text().trim().split('(')[1]
31 | let link = $(this).find('a').attr('href')
32 | if (link) result.push({ title, size: size.replace(')', ''), link })
33 | })
34 | return result
35 | }
36 |
37 | async function sfileDl(url) {
38 | let res = await fetch(url)
39 | let $ = cheerio.load(await res.text())
40 | let filename = $('div.w3-row-padding').find('img').attr('alt')
41 | let mimetype = $('div.list').text().split(' - ')[1].split('\n')[0]
42 | let filesize = $('#download').text().replace(/Download File/g, '').replace(/\(|\)/g, '').trim()
43 | let download = $('#download').attr('href') + '&k=' + Math.floor(Math.random() * (15 - 10 + 1) + 10)
44 | return { filename, filesize, mimetype, download }
45 | }
46 |
--------------------------------------------------------------------------------
/plugins/downloader-tiktok.js:
--------------------------------------------------------------------------------
1 | import fg from 'api-dylux'
2 | import { tiktokdl } from '@bochilteam/scraper'
3 |
4 | let handler = async (m, { conn, text, args, usedPrefix, command}) => {
5 | if (!args[0]) throw `Enter the link of the video Tiktok`
6 | if (!args[0].match(/tiktok/gi)) throw `Verify that the link is from tiktok`
7 | let old = new Date()
8 | let txt = `∘ *Fetching* : ${((new Date - old) * 1)} ms`
9 | conn.reply(m.chat, global.wait, m, {
10 | contextInfo: { externalAdReply :{ mediaUrl: null, mediaType: 1, description: null,
11 | title: '📤| downloads By Zoro md 🌸',
12 | body: me,
13 | previewType: 0, thumbnail: thumb2, jpegThumbnail: thumb,
14 | sourceUrl: 'https://github.com/xxirfanx' }}})
15 | try {
16 | let p = await fg.tiktok(args[0])
17 | conn.sendFile(m.chat, p.play, 'tiktok.mp4', txt, m)
18 | } catch {
19 | try {
20 | const { author: { nickname }, video, description } = await tiktokdl(args[0])
21 | const url = video.no_watermark2 || video.no_watermark || 'https://tikcdn.net' + video.no_watermark_raw || video.no_watermark_hd
22 | if (!url) throw global.eror
23 | conn.sendFile(m.chat, url, 'fb.mp4', ``, m)
24 | } catch {
25 | m.reply('*☓ An unexpected error occurred*')
26 | }}}
27 |
28 | handler.help = ['tiktok'].map((v) => v + ' ');
29 | handler.tags = ['downloader'];
30 | handler.command = /^t(t|iktok(d(own(load(er)?)?|l))?|td(own(load(er)?)?|l))$/i;
31 |
32 | export default handler
33 |
--------------------------------------------------------------------------------
/plugins/enable.js:
--------------------------------------------------------------------------------
1 | let handler = async (m, { conn, usedPrefix, command, args, isOwner, isAdmin, isROwner }) => {
2 | let isEnable = /true|enable|(turn)?on|1/i.test(command)
3 | let chat =global.DATABASE.data.chats[m.chat]
4 | let user = global.DATABASE.data.users[m.sender]
5 | let bot = global.DATABASE.data.settings[conn.user.jid] || {}
6 | let type = (args[0] || '').toLowerCase()
7 | let isAll = false, isUser = false
8 | switch (type) {
9 | case 'welcome':
10 | if (!m.isGroup) {
11 | if (!isOwner) {
12 | global.dfail('group', m, conn)
13 | throw false
14 | }
15 | } else if (!isAdmin) {
16 | global.dfail('admin', m, conn)
17 | throw false
18 | }
19 | chat.welcome = isEnable
20 | break
21 | case 'delete':
22 | if (m.isGroup) {
23 | if (!(isAdmin || isOwner)) {
24 | global.dfail('admin', m, conn)
25 | throw false
26 | }
27 | }
28 | chat.delete = isEnable
29 | break
30 | case 'antidelete':
31 | if (m.isGroup) {
32 | if (!(isAdmin || isOwner)) {
33 | global.dfail('admin', m, conn)
34 | throw false
35 | }
36 | }
37 | chat.delete = !isEnable
38 | break
39 | case 'public':
40 | isAll = true
41 | if (!isROwner) {
42 | global.dfail('rowner', m, conn)
43 | throw false
44 | }
45 | global.opts['self'] = !isEnable
46 | break
47 | case 'antilink':
48 | if (m.isGroup) {
49 | if (!(isAdmin || isOwner)) {
50 | global.dfail('admin', m, conn)
51 | throw false
52 | }
53 | }
54 | chat.antiLink = isEnable
55 | break
56 | case 'restrict':
57 | isAll = true
58 | if (!isOwner) {
59 | global.dfail('owner', m, conn)
60 | throw false
61 | }
62 | bot.restrict = isEnable
63 | break
64 | case 'nyimak':
65 | isAll = true
66 | if (!isROwner) {
67 | global.dfail('rowner', m, conn)
68 | throw false
69 | }
70 | global.opts['nyimak'] = isEnable
71 | break
72 | case 'autoread':
73 | isAll = true
74 | if (!isROwner) {
75 | global.dfail('rowner', m, conn)
76 | throw false
77 | }
78 | global.opts['autoread'] = isEnable
79 | break
80 | case 'pconly':
81 | case 'privateonly':
82 | isAll = true
83 | if (!isROwner) {
84 | global.dfail('rowner', m, conn)
85 | throw false
86 | }
87 | global.opts['pconly'] = isEnable
88 | break
89 | case 'gconly':
90 | case 'grouponly':
91 | isAll = true
92 | if (!isROwner) {
93 | global.dfail('rowner', m, conn)
94 | throw false
95 | }
96 | global.opts['gconly'] = isEnable
97 | break
98 | case 'swonly':
99 | case 'statusonly':
100 | isAll = true
101 | if (!isROwner) {
102 | global.dfail('rowner', m, conn)
103 | throw false
104 | }
105 | global.opts['swonly'] = isEnable
106 | break
107 | default:
108 | if (!/[01]/.test(command)) return m.reply(`
109 | List option: welcome | delete | public | antilink | antidelete | antitoxic | autolevelup | detect | document | whitelistmycontacts | restrict | nyimak | autoread | pconly | gconly | swonly
110 | Contoh:
111 | ${usedPrefix}enable welcome
112 | ${usedPrefix}disable welcome
113 | `.trim())
114 | throw false
115 | }
116 | m.reply(`
117 | *${type}* succeeded in *${isEnable ? 'on' : 'dead'}right* ${isAll ? 'for these bots' : isUser ? '' : 'for this chat'}
118 | `.trim())
119 | }
120 | handler.help = ['en', 'dis'].map(v => v + 'able