├── .gitignore ├── database.js ├── package.json ├── README.md └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea -------------------------------------------------------------------------------- /database.js: -------------------------------------------------------------------------------- 1 | const {Pool} = require('pg'); 2 | 3 | const proConfig = { 4 | connectionString: process.env.DATABASE_URL, 5 | ssl: { 6 | rejectUnauthorized: false 7 | } 8 | } 9 | 10 | const pool = new Pool(proConfig); 11 | 12 | module.exports = { 13 | query: (text, params) => pool.query(text, params) 14 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-whatsapp-bot", 3 | "version": "0.1.0", 4 | "description": "Simple Whatsapp Bot - Node Js - Heroku - Baileys", 5 | "main": "index.js", 6 | "directories": { 7 | "lib": "lib" 8 | }, 9 | "scripts": { 10 | "start": "node index.js" 11 | }, 12 | "keywords": [], 13 | "author": "Karma", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@adiwajshing/baileys": "github:adiwajshing/baileys", 17 | "wa-sticker-formatter": "^3.6.0", 18 | "async": "^3.2.0", 19 | "child_process": "^1.0.2", 20 | "express": "^4.17.1", 21 | "fluent-ffmpeg": "^2.1.2", 22 | "fs": "0.0.1-security", 23 | "pg": "^8.5.1" 24 | }, 25 | "homepage": "https://github.com/karmaisgreat/simple-whatsapp-bot#readme", 26 | "devDependencies": {}, 27 | "repository": { 28 | "type": "git", 29 | "url": "git+https://github.com/karmaisgreat/simple-whatsapp-bot.git" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/karmaisgreat/simple-whatsapp-bot/issues" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Simple Whatsapp Bot - Node Js - Heroku - Baileys 3 | 4 | **_Requirements :_** 5 | 6 | - Heroku account 7 | - Heroku CLI 8 | - Git 9 | 10 | # Instructions:- 11 | 12 | ## Git Setup 13 | ### Download and install git from (https://git-scm.com/downloads) 14 | 15 | ## Heroku Setup 16 | 17 | 1. Create account on heroku. (https://signup.heroku.com/) 18 | 19 | 2. After login on heroku dashboard create an app on heroku (https://dashboard.heroku.com/apps) 20 | 21 | 3. In the 'Resources' tab search for 'Heroku Postgres' in Add-ons and add it to your heroku app. 22 | 23 | 4. In the 'Deploy' section download Heroku CLI or from (https://devcenter.heroku.com/articles/heroku-cli#download-and-install) 24 | 25 | ## Heroku CLI 26 | 27 | 1. After downloading and installing Heroku CLI in your system login to heroku cli using `heroku login` in command prompt or powershell. 28 | 2. Add ffmpeg (*for sticker support*) in your heroku app using `heroku buildpacks:add https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git -a ` 29 | 3. After adding ffmpeg now add 'Heroku Buildpack for Node.js' using `heroku buildpacks:add https://github.com/heroku/heroku-buildpack-nodejs.git -a ` 30 | 4. Now download or clone the `simple-whatsapp-bot` repo from (https://github.com/karmaisgreat/simple-whatsapp-bot) 31 | 5. Now enter in `simple-whatsapp-bot` directory using `cd simple-whatsapp-bot` in command prompt or terminal. 32 | 6. Now init the git using `git init` 33 | 7. Create the remote region using `heroku git:remote -a ` 34 | 8. Now deploy the repo in your heroku app using : 35 | - `git add .` 36 | - `git commit -am "first commit"` 37 | - `git push heroku master` 38 | 9. Now after the deploy process is completed use `heroku logs -a --tail` to get real time logs from heroku app. 39 | 10. In real time logs it will automatically ask you for login using qr code just simple scan the qr code using your whatsapp web section, and you are done. 40 | 11. Scan QR code with you phone. done! 41 | 42 | 43 | # Features:- 44 | 45 | ## Default prefix : `/` 46 | 47 | ## Commands : 48 | 49 | | Commands | Alias | Description | 50 | | :--------: | :----: | :----------------------: | 51 | | `/help` | `/acmd` | Display help message | 52 | | `/add` | - | Add member to group | 53 | | `/kick` | `/ban, /remove` | Remove member from group | 54 | | `/promote` | - | Make member admin in group | 55 | | `/demote` | - | Remove member from admin in group | 56 | | `/rename` | - | Change group subject | 57 | | `/chat ` | - | Enable/disable group chat | 58 | | `/link` | `/getlink, /grouplink` | Get invite link of group | 59 | | `/sticker` | - | Create a sticker from different media types | 60 | | `/removebot` | - | Remove bot from group | 61 | | `/source` | - | Get the bot source | 62 | 63 | 64 | # Note:- 65 | Since heroku uses:- Dyno sleeping in which if an app has a free web dyno, and that dyno receives no web traffic in a 30-minute period, it will sleep. In addition to the web dyno sleeping, the worker dyno (if present) will also sleep. and if a sleeping web dyno receives web traffic, it will become active again after a short delay (assuming your account has free dyno hours available) 66 | You can use (http://kaffeine.herokuapp.com) to ping the heroku app every 30 minutes to prevent it from sleeping. 67 | 68 | 69 | 70 | # References:- 71 | 72 | - [@Baileys](https://github.com/adiwajshing/Baileys) 73 | - [@WA-STICKER-FORMATTER](https://github.com/Alensaito1/wa-sticker-formatter) 74 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // WEB SERVER 2 | const express = require('express') 3 | const server = express() 4 | const port = process.env.PORT || 8000; 5 | server.get('/', (req, res) => {res.send('K-Bot server running...')}) 6 | server.listen(port, () => { 7 | console.clear() 8 | console.log('\nWeb-server running!\n') 9 | }) 10 | 11 | // LOAD Baileys 12 | const { 13 | WAConnection, 14 | MessageType, 15 | Presence, 16 | Mimetype, 17 | GroupSettingChange, 18 | MessageOptions, 19 | WALocationMessage, 20 | WA_MESSAGE_STUB_TYPES, 21 | ReconnectMode, 22 | ProxyAgent, 23 | waChatKey, 24 | mentionedJid, 25 | processTime, 26 | } = require('@adiwajshing/baileys') 27 | 28 | // LOAD DB CONNECTION 29 | const db = require('./database'); 30 | 31 | // LOAD ADDITIONAL NPM PACKAGES 32 | const fs = require('fs') 33 | const ffmpeg = require('fluent-ffmpeg') 34 | const WSF = require('wa-sticker-formatter') 35 | 36 | async function fetchauth() { 37 | try{ 38 | auth_result = await db.query('select * from auth;'); 39 | console.log('Fetching login data...') 40 | auth_row_count = await auth_result.rowCount; 41 | if (auth_row_count == 0) { 42 | console.log('No login data found!') 43 | } else { 44 | console.log('Login data found!') 45 | auth_obj = { 46 | clientID: auth_result.rows[0].clientid, 47 | serverToken: auth_result.rows[0].servertoken, 48 | clientToken: auth_result.rows[0].clienttoken, 49 | encKey: auth_result.rows[0].enckey, 50 | macKey: auth_result.rows[0].mackey 51 | } 52 | } 53 | } catch { 54 | console.log('Creating database...') 55 | await db.query('CREATE TABLE auth(clientID text, serverToken text, clientToken text, encKey text, macKey text);'); 56 | await fetchauth(); 57 | } 58 | 59 | } 60 | 61 | // BASIC SETTINGS 62 | prefix = '/'; 63 | source_link = 'https://github.com/karmaisgreat/simple-whatsapp-bot'; 64 | 65 | // LOAD CUSTOM FUNCTIONS 66 | const getGroupAdmins = (participants) => { 67 | admins = [] 68 | for (let i of participants) { 69 | i.isAdmin ? admins.push(i.jid) : '' 70 | } 71 | return admins 72 | } 73 | const adminHelp = (prefix, groupName) => { 74 | return ` 75 | ─「 *${groupName} Admin Commands* 」─ 76 | 77 | *${prefix}add * 78 | _Add any new member!_ 79 | 80 | *${prefix}kick <@mention>* 81 | _Kick any member out from group!_ 82 | _Alias with ${prefix}remove, ${prefix}ban_ 83 | 84 | *${prefix}promote <@mention>* 85 | _Give admin permission to a member!_ 86 | 87 | *${prefix}demote <@mention>* 88 | _Remove admin permission of a member!_ 89 | 90 | *${prefix}rename * 91 | _Change group subject!_ 92 | 93 | *${prefix}chat * 94 | _Enable/disable group chat_ 95 | _/chat on - for everyone!_ 96 | _/chat off - for admin only!_ 97 | 98 | *${prefix}link* 99 | _Get group invite link!_ 100 | _Alias with ${prefix}getlink, ${prefix}grouplink_ 101 | 102 | *${prefix}sticker* 103 | _Create a sticker from different media types!_ 104 | *Properties of sticker:* 105 | _crop_ - Used to crop the sticker size! 106 | _author_ - Add metadata in sticker! 107 | _pack_ - Add metadata in sticker! 108 | _nometadata_ - Remove all metadata from sticker! 109 | *Examples:* 110 | _${prefix}sticker pack simple-k-bot author Karma_ 111 | _${prefix}sticker crop_ 112 | _${prefix}sticker nometadata_ 113 | 114 | *${prefix}removebot* 115 | _Remove bot from group!_ 116 | 117 | *${prefix}source* 118 | _Get bot source code!_` 119 | } 120 | const getRandom = (ext) => {return `${Math.floor(Math.random() * 10000)}${ext}`} 121 | 122 | // MAIN FUNCTION 123 | async function main() { 124 | 125 | // LOADING SESSION 126 | const conn = new WAConnection() 127 | conn.logger.level = 'warn' 128 | conn.on('qr', () => {console.log('SCAN THE ABOVE QR CODE TO LOGIN!')}) 129 | await fetchauth(); //GET LOGIN DATA 130 | if (auth_row_count == 1) {conn.loadAuthInfo(auth_obj)} 131 | conn.on('connecting', () => {console.log('Connecting...')}) 132 | conn.on('open', () => { 133 | console.clear() 134 | console.log('Connected!') 135 | }) 136 | await conn.connect({timeoutMs: 30 * 1000}) 137 | const authInfo = conn.base64EncodedAuthInfo() // UPDATED LOGIN DATA 138 | load_clientID = authInfo.clientID; 139 | load_serverToken = authInfo.serverToken; 140 | load_clientToken = authInfo.clientToken; 141 | load_encKey = authInfo.encKey; 142 | load_macKey = authInfo.macKey; 143 | // INSERT / UPDATE LOGIN DATA 144 | if (auth_row_count == 0) { 145 | console.log('Inserting login data...') 146 | db.query('INSERT INTO auth VALUES($1,$2,$3,$4,$5);',[load_clientID,load_serverToken,load_clientToken,load_encKey,load_macKey]) 147 | db.query('commit;') 148 | console.log('New login data inserted!') 149 | } else { 150 | console.log('Updating login data....') 151 | db.query('UPDATE auth SET clientid = $1, servertoken = $2, clienttoken = $3, enckey = $4, mackey = $5;',[load_clientID,load_serverToken,load_clientToken,load_encKey,load_macKey]) 152 | db.query('commit;') 153 | console.log('Login data updated!') 154 | } 155 | 156 | conn.on('group-participants-update', async (anu) => { 157 | try { 158 | const mdata = await conn.groupMetadata(anu.jid) 159 | console.log(anu) 160 | if (anu.action == 'add') { 161 | num = anu.participants[0] 162 | num_split = `${num.split('@s.whatsapp.net')[0]}` 163 | console.log('Joined: ', num) 164 | } 165 | } catch (e) { 166 | console.log(e) 167 | } 168 | }) 169 | 170 | conn.on('chat-update', async (mek) => { 171 | try { 172 | if (!mek.hasNewMessage) return 173 | mek = JSON.parse(JSON.stringify(mek)).messages[0] 174 | if (!mek.message) return 175 | if (mek.key && mek.key.remoteJid == 'status@broadcast') return 176 | if (mek.key.fromMe) return 177 | const content = JSON.stringify(mek.message) 178 | global.prefix 179 | const from = mek.key.remoteJid 180 | const type = Object.keys(mek.message)[0] 181 | const { 182 | text, 183 | extendedText, 184 | contact, 185 | location, 186 | liveLocation, 187 | image, 188 | video, 189 | sticker, 190 | document, 191 | audio, 192 | product 193 | } = MessageType 194 | body = (type === 'conversation' && mek.message.conversation.startsWith(prefix)) ? mek.message.conversation : (type == 'imageMessage') && mek.message.imageMessage.caption.startsWith(prefix) ? mek.message.imageMessage.caption : (type == 'videoMessage') && mek.message.videoMessage.caption.startsWith(prefix) ? mek.message.videoMessage.caption : (type == 'extendedTextMessage') && mek.message.extendedTextMessage.text.startsWith(prefix) ? mek.message.extendedTextMessage.text : '' 195 | const command = body.slice(1).trim().split(/ +/).shift().toLowerCase() 196 | const args = body.trim().split(/ +/).slice(1) 197 | const isCmd = body.startsWith(prefix) 198 | 199 | errors = { 200 | admin_error: '_❌ ERROR: Admin permission failed! ❌_' 201 | } 202 | 203 | const botNumber = conn.user.jid 204 | const isGroup = from.endsWith('@g.us') 205 | const sender = isGroup ? mek.participant : mek.key.remoteJid 206 | const groupMetadata = isGroup ? await conn.groupMetadata(from) : '' 207 | const groupName = isGroup ? groupMetadata.subject : '' 208 | const groupMembers = isGroup ? groupMetadata.participants : '' 209 | const groupAdmins = isGroup ? getGroupAdmins(groupMembers) : '' 210 | const isBotGroupAdmins = groupAdmins.includes(botNumber) || false 211 | const isGroupAdmins = groupAdmins.includes(sender) || false 212 | 213 | const reply = (teks) => { 214 | conn.sendMessage(from, teks, text, { 215 | quoted: mek 216 | }) 217 | } 218 | 219 | const costum = (pesan, tipe, target, target2) => { 220 | conn.sendMessage(from, pesan, tipe, { 221 | quoted: { 222 | key: { 223 | fromMe: false, 224 | participant: `${target}`, 225 | ...(from ? { 226 | remoteJid: from 227 | } : {}) 228 | }, 229 | message: { 230 | conversation: `${target2}` 231 | } 232 | } 233 | }) 234 | } 235 | 236 | const isMedia = (type === 'imageMessage' || type === 'videoMessage') 237 | const isQuotedImage = type === 'extendedTextMessage' && content.includes('imageMessage') 238 | const isQuotedVideo = type === 'extendedTextMessage' && content.includes('videoMessage') 239 | const isQuotedSticker = type === 'extendedTextMessage' && content.includes('stickerMessage') 240 | if (isCmd && isGroup) console.log('[COMMAND]', command, '[FROM]', sender.split('@')[0], '[IN]', groupName) 241 | 242 | /////////////// COMMANDS \\\\\\\\\\\\\\\ 243 | 244 | switch (command) { 245 | 246 | /////////////// HELP \\\\\\\\\\\\\\\ 247 | 248 | case 'help': 249 | case 'acmd': 250 | if (!isGroup) return; 251 | await costum(adminHelp(prefix, groupName), text); 252 | break 253 | 254 | case 'link': 255 | case 'getlink': 256 | case 'grouplink': 257 | if (!isGroup) return; 258 | if (!isBotGroupAdmins) return reply(errors.admin_error); 259 | gc_invite_code = await conn.groupInviteCode(from) 260 | gc_link = `https://chat.whatsapp.com/${gc_invite_code}` 261 | conn.sendMessage(from, gc_link, text, { 262 | quoted: mek, 263 | detectLinks: true 264 | }) 265 | break; 266 | 267 | case 'source': 268 | if (!isGroup) return; 269 | conn.sendMessage(from, source_link, text, { 270 | quoted: mek, 271 | detectLinks: true 272 | }) 273 | break; 274 | 275 | 276 | case 'sticker': 277 | if (!isGroup) return; 278 | 279 | // Format should be sticker pack author 280 | var packName = "" 281 | var authorName = "" 282 | 283 | // Check if pack keyword is found in args! 284 | if(args.includes('pack') == true) { 285 | packNameDataCollection = false; 286 | for (let i = 0; i < args.length; i++) { 287 | // Enables data collection when keyword found in index! 288 | if(args[i].includes('pack') == true) { 289 | packNameDataCollection = true; 290 | } 291 | if (args[i].includes('author') == true) { 292 | packNameDataCollection = false; 293 | } 294 | // If data collection is enabled and args length is more then one it will start appending! 295 | if (packNameDataCollection == true) { 296 | packName = packName + args[i] + ' ' 297 | } 298 | } 299 | // Check if variable contain unnecessary startup word! 300 | if (packName.startsWith('pack ')) { 301 | packName = `${packName.split('pack ')[1]}` 302 | } 303 | } 304 | 305 | // Check if author keyword is found in args! 306 | if (args.includes('author') == true) { 307 | authorNameDataCollection = false; 308 | for (let i = 0; i < args.length; i++) { 309 | // Enables data collection when keyword found in index! 310 | if(args[i].includes('author') == true) { 311 | authorNameDataCollection = true; 312 | } 313 | // If data collection is enabled and args length is more then one it will start appending! 314 | if (authorNameDataCollection == true) { 315 | authorName = authorName + args[i] + ' ' 316 | } 317 | // Check if variable contain unnecessary startup word! 318 | if (authorName.startsWith('author ')) { 319 | authorName = `${authorName.split('author ')[1]}` 320 | } 321 | } 322 | } 323 | 324 | // Check if packName and authorName is empty it will pass default values! 325 | if (packName == "") { 326 | packName = "simple-whatsapp-bot" 327 | } 328 | if (authorName == "") { 329 | authorName = "github.com/karmaisgreat/simple-whatsapp-bot" 330 | } 331 | 332 | outputOptions = [`-vcodec`,`libwebp`,`-vf`,`scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease,fps=15, pad=320:320:-1:-1:color=white@0.0, split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse`]; 333 | if(args.includes('crop') == true) { 334 | outputOptions = [ 335 | `-vcodec`, 336 | `libwebp`, 337 | `-vf`, 338 | `crop=w='min(min(iw\,ih)\,500)':h='min(min(iw\,ih)\,500)',scale=500:500,setsar=1,fps=15`, 339 | `-loop`, 340 | `0`, 341 | `-ss`, 342 | `00:00:00.0`, 343 | `-t`, 344 | `00:00:10.0`, 345 | `-preset`, 346 | `default`, 347 | `-an`, 348 | `-vsync`, 349 | `0`, 350 | `-s`, 351 | `512:512` 352 | ]; 353 | } 354 | 355 | if ((isMedia && !mek.message.videoMessage || isQuotedImage)) { 356 | const encmedia = isQuotedImage ? JSON.parse(JSON.stringify(mek).replace('quotedM','m')).message.extendedTextMessage.contextInfo : mek 357 | const media = await conn.downloadAndSaveMediaMessage(encmedia) 358 | ran = getRandom('.webp') 359 | reply('⌛ Processing image... ⏳') 360 | await ffmpeg(`./${media}`) 361 | .input(media) 362 | .on('error', function (err) { 363 | fs.unlinkSync(media) 364 | console.log(`Error : ${err}`) 365 | reply('_❌ ERROR: Failed to convert image into sticker! ❌_') 366 | }) 367 | .on('end', function () { 368 | buildSticker() 369 | }) 370 | .addOutputOptions(outputOptions) 371 | .toFormat('webp') 372 | .save(ran) 373 | 374 | async function buildSticker(){ 375 | if(args.includes('nometadata') == true) { 376 | conn.sendMessage(from, fs.readFileSync(ran), sticker, {quoted: mek}) 377 | fs.unlinkSync(media) 378 | fs.unlinkSync(ran) 379 | } else { 380 | const webpWithMetadata = await WSF.setMetadata(packName, authorName, ran) 381 | conn.sendMessage(from, webpWithMetadata, MessageType.sticker) 382 | fs.unlinkSync(media) 383 | fs.unlinkSync(ran) 384 | } 385 | } 386 | 387 | } else if ((isMedia && mek.message.videoMessage.seconds < 11 || isQuotedVideo && mek.message.extendedTextMessage.contextInfo.quotedMessage.videoMessage.seconds < 11)) { 388 | const encmedia = isQuotedVideo ? JSON.parse(JSON.stringify(mek).replace('quotedM','m')).message.extendedTextMessage.contextInfo : mek 389 | const media = await conn.downloadAndSaveMediaMessage(encmedia) 390 | ran = getRandom('.webp') 391 | reply('⌛ Processing animation... ⏳') 392 | await ffmpeg(`./${media}`) 393 | .inputFormat(media.split('.')[1]) 394 | .on('error', function (err) { 395 | fs.unlinkSync(media) 396 | mediaType = media.endsWith('.mp4') ? 'video' : 'gif' 397 | reply(`_❌ ERROR: Failed to convert ${mediaType} to sticker! ❌_`) 398 | }) 399 | .on('end', function () { 400 | buildSticker() 401 | }) 402 | .addOutputOptions(outputOptions) 403 | .toFormat('webp') 404 | .save(ran) 405 | 406 | async function buildSticker(){ 407 | if(args.includes('nometadata') == true) { 408 | conn.sendMessage(from, fs.readFileSync(ran), sticker, {quoted: mek}) 409 | fs.unlinkSync(media) 410 | fs.unlinkSync(ran) 411 | } else { 412 | const webpWithMetadata = await WSF.setMetadata(packName, authorName, ran) 413 | conn.sendMessage(from, webpWithMetadata, MessageType.sticker) 414 | fs.unlinkSync(media) 415 | fs.unlinkSync(ran) 416 | } 417 | } 418 | } 419 | break; 420 | 421 | /////////////// ADMIN COMMANDS \\\\\\\\\\\\\\\ 422 | 423 | case 'add': 424 | if (!isGroup) return; 425 | if (!isGroupAdmins) return; 426 | if (!isBotGroupAdmins) return reply(errors.admin_error); 427 | if (args.length < 1) return; 428 | var num = ''; 429 | if (args.length > 1) { 430 | for (let j = 0; j < args.length; j++) { 431 | num = num + args[j] 432 | } 433 | num = `${num.replace(/ /g, '')}@s.whatsapp.net` 434 | } else { 435 | num = `${args[0].replace(/ /g, '')}@s.whatsapp.net` 436 | } 437 | if (num.startsWith('+')) { 438 | num = `${num.split('+')[1]}` 439 | } 440 | const response = await conn.groupAdd(from, [num]) 441 | get_status = `${num.split('@s.whatsapp.net')[0]}` 442 | get_status = response[`${get_status}@c.us`]; 443 | if (get_status == 400) { 444 | reply('_❌ ERROR: Invalid number! ❌_'); 445 | } 446 | if (get_status == 403) { 447 | reply('_❌ ERROR: Number has privacy on adding group! ❌_'); 448 | } 449 | if (get_status == 408) { 450 | reply('_❌ ERROR: Number has left the group recently! ❌_'); 451 | } 452 | if (get_status == 409) { 453 | reply('_❌ ERROR: Number is already exists! ❌_'); 454 | } 455 | if (get_status == 500) { 456 | reply('_❌ ERROR: Group is currently full! ❌_'); 457 | } 458 | if (get_status == 200) { 459 | reply('_✔ SUCCESS: Number added to group! ✔_'); 460 | } 461 | break; 462 | 463 | case 'kick': 464 | case 'remove': 465 | case 'ban': 466 | if (!isGroup) return; 467 | if (!isGroupAdmins) return; 468 | if (!isBotGroupAdmins) return reply(errors.admin_error); 469 | if (mek.message.extendedTextMessage === undefined || mek.message.extendedTextMessage === null) return; 470 | mentioned = mek.message.extendedTextMessage.contextInfo.mentionedJid 471 | if (groupAdmins.includes(`${mentioned}`) == true) return; 472 | if (mentioned.length > 1) { 473 | return; 474 | } else { 475 | conn.groupRemove(from, mentioned) 476 | } 477 | break; 478 | 479 | case 'promote': 480 | if (!isGroup) return; 481 | if (!isGroupAdmins) return; 482 | if (!isBotGroupAdmins) return reply(errors.admin_error); 483 | if (mek.message.extendedTextMessage === undefined || mek.message.extendedTextMessage === null) return; 484 | mentioned = mek.message.extendedTextMessage.contextInfo.mentionedJid 485 | if (groupAdmins.includes(`${mentioned}`) == true) return; 486 | if (mentioned.length > 1) { 487 | return; 488 | } else { 489 | conn.groupMakeAdmin(from, mentioned) 490 | } 491 | break; 492 | 493 | case 'demote': 494 | if (!isGroup) return; 495 | if (!isGroupAdmins) return; 496 | if (!isBotGroupAdmins) return reply(errors.admin_error); 497 | if (mek.message.extendedTextMessage === undefined || mek.message.extendedTextMessage === null) return reply('_⚠ USAGE: /demote <@mention> ⚠_'); 498 | mentioned = mek.message.extendedTextMessage.contextInfo.mentionedJid 499 | if (groupAdmins.includes(`${mentioned}`) == false) return; 500 | if (mentioned.length > 1) { 501 | return; 502 | } else { 503 | conn.groupDemoteAdmin(from, mentioned) 504 | } 505 | break; 506 | 507 | case 'chat': 508 | if (!isGroup) return; 509 | if (!isGroupAdmins) return; 510 | if (!isBotGroupAdmins) return reply(errors.admin_error); 511 | if (args.length < 1) return; 512 | if (args[0] == 'on') { 513 | conn.groupSettingChange(from, GroupSettingChange.messageSend, false); 514 | } else if (args[0] == 'off') { 515 | conn.groupSettingChange(from, GroupSettingChange.messageSend, true); 516 | } else { 517 | return; 518 | } 519 | break; 520 | 521 | case 'rename': 522 | if (!isGroup) return; 523 | if (!isGroupAdmins) return; 524 | if (!isBotGroupAdmins) return reply(errors.admin_error); 525 | if (args.length < 1) return; 526 | get_subject = ''; 527 | for (i = 0; i < args.length; i++) { 528 | get_subject = get_subject + args[i] + ' '; 529 | } 530 | conn.groupUpdateSubject(from, get_subject); 531 | break; 532 | 533 | case 'removebot': 534 | if (!isGroup) return; 535 | if (!isGroupAdmins) return; 536 | conn.groupLeave(from) 537 | break; 538 | 539 | default: 540 | break; 541 | } 542 | } catch (e) { 543 | console.log('Error : %s', e) 544 | } 545 | }) 546 | } 547 | main() --------------------------------------------------------------------------------