| | import path from 'path' |
| | import { toAudio } from './converter.js' |
| | import chalk from 'chalk' |
| | import fetch from 'node-fetch' |
| | import PhoneNumber from 'awesome-phonenumber' |
| | import fs from 'fs' |
| | import util from 'util' |
| | import { fileTypeFromBuffer } from 'file-type' |
| | import { format } from 'util' |
| | import { fileURLToPath } from 'url' |
| | import logg from 'pino' |
| | import pino from'pino' |
| | import store from './store.js' |
| | let conv = await import('./sticker.js') |
| |
|
| | const __dirname = path.dirname(fileURLToPath(import.meta.url)) |
| | |
| |
|
| | |
| | |
| | |
| | const { |
| | default: _makeWaSocket, |
| | makeWALegacySocket, |
| | makeInMemoryStore, |
| | proto, |
| | downloadContentFromMessage, |
| | jidDecode, |
| | areJidsSameUser, |
| | generateForwardMessageContent, |
| | generateWAMessageFromContent, |
| | WAMessageStubType, |
| | generateWAMessage, |
| | getContentType, |
| | extractMessageContent, jidNormalizedUser |
| | } = (await import('@adiwajshing/baileys')).default |
| | |
| | import * as baileys from '@adiwajshing/baileys' |
| | |
| | export function makeWASocket(connectionOptions, options = {}) { |
| | |
| | |
| | |
| | let conn = (global.opts['legacy'] ? makeWALegacySocket : _makeWaSocket)(connectionOptions) |
| |
|
| | let sock = Object.defineProperties(conn, { |
| | chats: { |
| | value: { ...(options.chats || {}) }, |
| | writable: true |
| | }, |
| | decodeJid: { |
| | value(jid) { |
| | if (!jid || typeof jid !== 'string') return (!nullish(jid) && jid) || null |
| | return jid.decodeJid() |
| | } |
| | }, |
| | logger: { |
| | get() { |
| | return { |
| | info(...args) { |
| | console.log( |
| | chalk.bold.bgRgb(51, 204, 51)('INFO '), |
| | `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, |
| | chalk.cyan(format(...args)) |
| | ) |
| | }, |
| | error(...args) { |
| | console.log( |
| | chalk.bold.bgRgb(247, 38, 33)('ERROR '), |
| | `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, |
| | chalk.rgb(255, 38, 0)(format(...args)) |
| | ) |
| | }, |
| | warn(...args) { |
| | console.log( |
| | chalk.bold.bgRgb(255, 153, 0)('WARNING '), |
| | `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, |
| | chalk.redBright(format(...args)) |
| | ) |
| | }, |
| | trace(...args) { |
| | console.log( |
| | chalk.grey('TRACE '), |
| | `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, |
| | chalk.white(format(...args)) |
| | ) |
| | }, |
| | debug(...args) { |
| | console.log( |
| | chalk.bold.bgRgb(66, 167, 245)('DEBUG '), |
| | `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, |
| | chalk.white(format(...args)) |
| | ) |
| | } |
| | } |
| | }, |
| | enumerable: true |
| | }, |
| |
|
| | |
| |
|
| | |
| | getFile: { |
| | |
| | |
| | |
| | |
| | |
| | async value(PATH, saveToFile = false) { |
| | let res, filename |
| | const data = Buffer.isBuffer(PATH) ? PATH : PATH instanceof ArrayBuffer ? PATH.toBuffer() : /^data:.*?\/.*?;base64,/i.test(PATH) ? Buffer.from(PATH.split`,`[1], 'base64') : /^https?:\/\//.test(PATH) ? await (res = await fetch(PATH)).buffer() : fs.existsSync(PATH) ? (filename = PATH, fs.readFileSync(PATH)) : typeof PATH === 'string' ? PATH : Buffer.alloc(0) |
| | if (!Buffer.isBuffer(data)) throw new TypeError('Result is not a buffer') |
| | const type = await fileTypeFromBuffer(data) || { |
| | mime: 'application/octet-stream', |
| | ext: '.bin' |
| | } |
| | if (data && saveToFile && !filename) (filename = path.join(__dirname, '../tmp/' + new Date * 1 + '.' + type.ext), await fs.promises.writeFile(filename, data)) |
| | return { |
| | res, |
| | filename, |
| | ...type, |
| | data, |
| | deleteFile() { |
| | return filename && fs.promises.unlink(filename) |
| | } |
| | } |
| | }, |
| | enumerable: true |
| | }, |
| |
|
| | |
| | |
| | |
| | sendSticker: { |
| |
|
| | async value(jid, media, m, opts = {}) { |
| | |
| | const medias = await conn.getFile(media) |
| | return this.sendMessage(jid, await conv.sticker(medias.data, null, opts.packname || 'Whatsapp Bot', opts.author || conn.user.name), 'stickerMessage', { quoted: m, ...opts }) |
| | } |
| | }, |
| | |
| | waitEvent: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(eventName, is = () => true, maxTries = 25) { |
| | return new Promise((resolve, reject) => { |
| | let tries = 0 |
| | let on = (...args) => { |
| | if (++tries > maxTries) reject('Max tries reached') |
| | else if (is()) { |
| | conn.ev.off(eventName, on) |
| | resolve(...args) |
| | } |
| | } |
| | conn.ev.on(eventName, on) |
| | }) |
| | } |
| | }, |
| | sendFile: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async value(jid, path, filename = '', caption = '', quoted, ptt = false, options = {}) { |
| | let type = await conn.getFile(path, true) |
| | let { res, data: file, filename: pathFile } = type |
| | if (res && res.status !== 200 || file.length <= 65536) { |
| | try { throw { json: JSON.parse(file.toString()) } } |
| | catch (e) { if (e.json) throw e.json } |
| | } |
| | const fileSize = fs.statSync(pathFile).size / 1024 / 1024 |
| | if (fileSize >= 100) throw new Error('File size is too big!') |
| | let opt = {} |
| | if (quoted) opt.quoted = quoted |
| | if (!type) options.asDocument = true |
| | let mtype = '', mimetype = options.mimetype || type.mime, convert |
| | if (/webp/.test(type.mime) || (/image/.test(type.mime) && options.asSticker)) mtype = 'sticker' |
| | else if (/image/.test(type.mime) || (/webp/.test(type.mime) && options.asImage)) mtype = 'image' |
| | else if (/video/.test(type.mime)) mtype = 'video' |
| | else if (/audio/.test(type.mime)) ( |
| | convert = await toAudio(file, type.ext), |
| | file = convert.data, |
| | pathFile = convert.filename, |
| | mtype = 'audio', |
| | mimetype = options.mimetype || 'audio/ogg; codecs=opus' |
| | ) |
| | else mtype = 'document' |
| | if (options.asDocument) mtype = 'document' |
| |
|
| | delete options.asSticker |
| | delete options.asLocation |
| | delete options.asVideo |
| | delete options.asDocument |
| | delete options.asImage |
| |
|
| | let message = { |
| | ...options, |
| | caption, |
| | ptt, |
| | [mtype]: { url: pathFile }, |
| | mimetype, |
| | fileName: filename || pathFile.split('/').pop() |
| | } |
| | |
| | |
| | |
| | let m |
| | try { |
| | m = await conn.sendMessage(jid, message, { ...opt, ...options }) |
| | } catch (e) { |
| | console.error(e) |
| | m = null |
| | } finally { |
| | if (!m) m = await conn.sendMessage(jid, { ...message, [mtype]: file }, { ...opt, ...options }) |
| | file = null |
| | return m |
| | } |
| | }, |
| | enumerable: true |
| | }, |
| | sendContact: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async value(jid, data, quoted, options) { |
| | if (!Array.isArray(data[0]) && typeof data[0] === 'string') data = [data] |
| | let contacts = [] |
| | for (let [number, name] of data) { |
| | number = number.replace(/[^0-9]/g, '') |
| | let njid = number + '@s.whatsapp.net' |
| | let biz = await conn.getBusinessProfile(njid).catch(_ => null) || {} |
| | let vcard = ` |
| | BEGIN:VCARD |
| | VERSION:3.0 |
| | N:;${name.replace(/\n/g, '\\n')};;; |
| | FN:${name.replace(/\n/g, '\\n')} |
| | TEL;type=CELL;type=VOICE;waid=${number}:${PhoneNumber('+' + number).getNumber('international')}${biz.description ? ` |
| | X-WA-BIZ-NAME:${(conn.chats[njid]?.vname || conn.getName(njid) || name).replace(/\n/, '\\n')} |
| | X-WA-BIZ-DESCRIPTION:${biz.description.replace(/\n/g, '\\n')} |
| | `.trim() : ''} |
| | END:VCARD |
| | `.trim() |
| | contacts.push({ vcard, displayName: name }) |
| |
|
| | } |
| | return await conn.sendMessage(jid, { |
| | ...options, |
| | contacts: { |
| | ...options, |
| | displayName: (contacts.length >= 2 ? `${contacts.length} kontak` : contacts[0].displayName) || null, |
| | contacts, |
| | } |
| | }, { quoted, ...options }) |
| | }, |
| | enumerable: true |
| | }, |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | reply: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(jid, text = '', quoted, options) { |
| | let pp = conn.profilePictureUrl(conn.user.jid, 'image') |
| | const _uptime = process.uptime() * 1000 |
| | return Buffer.isBuffer(text) ? conn.sendFile(jid, text, 'file', '', quoted, false, options) : conn.sendMessage(jid, { ...options, |
| | text, |
| | mentions: conn.parseMention(text), |
| | |
| | mentions: conn.parseMention(text), |
| | ...options }, { |
| | quoted, |
| | ephemeralExpiration: 0, |
| | ...options |
| | }) |
| | } |
| | }, |
| | |
| | replyV2: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(jid, text = '', quoted, options) { |
| | let pp = conn.profilePictureUrl(conn.user.jid, 'image') |
| | const _uptime = process.uptime() * 1000 |
| | return Buffer.isBuffer(text) ? conn.sendFile(jid, text, 'file', '', quoted, false, options) : conn.sendMessage(jid, { ...options, |
| | text, |
| | mentions: conn.parseMention(text), |
| | |
| | mentions: conn.parseMention(text), |
| | ...options }, { |
| | quoted, |
| | ephemeralExpiration: 86400, |
| | ...options |
| | }) |
| | } |
| | }, |
| | |
| | sendButtonImg: { |
| | async value (jid, buffer, contentText, footerText, button1, id1, quoted, options) { |
| | let type = await conn.getFile(buffer) |
| | let { res, data: file } = type |
| | if (res && res.status !== 200 || file.length <= 65536) { |
| | try { throw { json: JSON.parse(file.toString()) } } |
| | catch (e) { if (e.json) throw e.json } |
| | } |
| | const buttons = [ |
| | { buttonId: id1, buttonText: { displayText: button1 }, type: 1 } |
| | ] |
| | |
| | const buttonMessage = { |
| | image: file, |
| | fileLength: 999999999999999, |
| | caption: contentText, |
| | footer: footerText, |
| | mentions: await conn.parseMention(contentText + footerText), |
| | ...options, |
| | buttons: buttons, |
| | headerType: 4 |
| | } |
| | |
| | return await conn.sendMessage(jid, buttonMessage, { quoted, ephemeralExpiration: global.ephemeral, contextInfo: { mentionedJid: conn.parseMention(contentText + footerText) }, ...options }) |
| | } |
| | }, |
| | sendButton: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async value(jid, text = '', footer = '', buffer, buttons, quoted, options) { |
| | let type |
| | if (Array.isArray(buffer)) (options = quoted, quoted = buttons, buttons = buffer, buffer = null) |
| | else if (buffer) try { (type = await conn.getFile(buffer), buffer = type.data) } catch { buffer = null } |
| | if (!Array.isArray(buttons[0]) && typeof buttons[0] === 'string') buttons = [buttons] |
| | if (!options) options = {} |
| | let message = { |
| | ...options, |
| | [buffer ? 'caption' : 'text']: text || '', |
| | footer, |
| | buttons: buttons.map(btn => ({ |
| | buttonId: !nullish(btn[1]) && btn[1] || !nullish(btn[0]) && btn[0] || '', |
| | buttonText: { |
| | displayText: !nullish(btn[0]) && btn[0] || !nullish(btn[1]) && btn[1] || '' |
| | } |
| | })), |
| | ...(buffer ? |
| | options.asLocation && /image/.test(type.mime) ? { |
| | location: { |
| | ...options, |
| | jpegThumbnail: buffer |
| | } |
| | } : { |
| | [/video/.test(type.mime) ? 'video' : /image/.test(type.mime) ? 'image' : 'document']: buffer |
| | } : {}) |
| | } |
| |
|
| | return await conn.sendMessage(jid, message, { |
| | quoted, |
| | upload: conn.waUploadToServer, |
| | ...options |
| | }) |
| | }, |
| | enumerable: true |
| | }, |
| | sendHydrated: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async value(jid, text = '', footer = '', buffer, url, urlText, call, callText, buttons, quoted, options) { |
| | let type |
| | if (buffer) try { (type = await conn.getFile(buffer), buffer = type.data) } catch { buffer = buffer } |
| | if (buffer && !Buffer.isBuffer(buffer) && (typeof buffer === 'string' || Array.isArray(buffer))) (options = quoted, quoted = buttons, buttons = callText, callText = call, call = urlText, urlText = url, url = buffer, buffer = null) |
| | if (!options) options = {} |
| | let templateButtons = [] |
| | if (url || urlText) { |
| | if (!Array.isArray(url)) url = [url] |
| | if (!Array.isArray(urlText)) urlText = [urlText] |
| | templateButtons.push(...( |
| | url.map((v, i) => [v, urlText[i]]) |
| | .map(([url, urlText], i) => ({ |
| | index: templateButtons.length + i + 1, |
| | urlButton: { |
| | displayText: !nullish(urlText) && urlText || !nullish(url) && url || '', |
| | url: !nullish(url) && url || !nullish(urlText) && urlText || '' |
| | } |
| | })) || [] |
| | )) |
| | } |
| | if (call || callText) { |
| | if (!Array.isArray(call)) call = [call] |
| | if (!Array.isArray(callText)) callText = [callText] |
| | templateButtons.push(...( |
| | call.map((v, i) => [v, callText[i]]) |
| | .map(([call, callText], i) => ({ |
| | index: templateButtons.length + i + 1, |
| | callButton: { |
| | displayText: !nullish(callText) && callText || !nullish(call) && call || '', |
| | phoneNumber: !nullish(call) && call || !nullish(callText) && callText || '' |
| | } |
| | })) || [] |
| | )) |
| | } |
| | if (buttons.length) { |
| | if (!Array.isArray(buttons[0])) buttons = [buttons] |
| | templateButtons.push(...( |
| | buttons.map(([text, id], index) => ({ |
| | index: templateButtons.length + index + 1, |
| | quickReplyButton: { |
| | displayText: !nullish(text) && text || !nullish(id) && id || '', |
| | id: !nullish(id) && id || !nullish(text) && text || '' |
| | } |
| | })) || [] |
| | )) |
| | } |
| | let message = { |
| | ...options, |
| | [buffer ? 'caption' : 'text']: text || '', |
| | footer, |
| | templateButtons, |
| | ...(buffer ? |
| | options.asLocation && /image/.test(type.mime) ? { |
| | location: { |
| | ...options, |
| | jpegThumbnail: buffer |
| | } |
| | } : { |
| | [/video/.test(type.mime) ? 'video' : /image/.test(type.mime) ? 'image' : 'document']: buffer |
| | } : {}) |
| | } |
| | return await conn.sendMessage(jid, message, { |
| | quoted, |
| | upload: conn.waUploadToServer, |
| | ...options |
| | }) |
| | }, |
| | enumerable: true |
| | }, |
| |
|
| | sendHydrated2: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async value(jid, text = '', footer = '', buffer, url, urlText, url2, urlText2, buttons, quoted, options) { |
| | let type |
| | if (buffer) try { (type = await conn.getFile(buffer), buffer = type.data) } catch { buffer = buffer } |
| | if (buffer && !Buffer.isBuffer(buffer) && (typeof buffer === 'string' || Array.isArray(buffer))) (options = quoted, quoted = buttons, buttons = callText, callText = call, call = urlText, urlText = url, url = buffer, buffer = null) |
| | if (!options) options = {} |
| | let templateButtons = [] |
| | if (url || urlText) { |
| | if (!Array.isArray(url)) url = [url] |
| | if (!Array.isArray(urlText)) urlText = [urlText] |
| | templateButtons.push(...( |
| | url.map((v, i) => [v, urlText[i]]) |
| | .map(([url, urlText], i) => ({ |
| | index: templateButtons.length + i + 1, |
| | urlButton: { |
| | displayText: !nullish(urlText) && urlText || !nullish(url) && url || '', |
| | url: !nullish(url) && url || !nullish(urlText) && urlText || '' |
| | } |
| | })) || [] |
| | )) |
| | } |
| | if (url2 || urlText2) { |
| | if (!Array.isArray(url2)) url2 = [url2] |
| | if (!Array.isArray(urlText2)) urlText2 = [urlText2] |
| | templateButtons.push(...( |
| | url2.map((v, i) => [v, urlText2[i]]) |
| | .map(([url2, urlText2], i) => ({ |
| | index: templateButtons.length + i + 1, |
| | urlButton: { |
| | displayText: !nullish(urlText2) && urlText2 || !nullish(url2) && url2 || '', |
| | url: !nullish(url2) && url2 || !nullish(urlText2) && urlText2 || '' |
| | } |
| | })) || [] |
| | )) |
| | } |
| | if (buttons.length) { |
| | if (!Array.isArray(buttons[0])) buttons = [buttons] |
| | templateButtons.push(...( |
| | buttons.map(([text, id], index) => ({ |
| | index: templateButtons.length + index + 1, |
| | quickReplyButton: { |
| | displayText: !nullish(text) && text || !nullish(id) && id || '', |
| | id: !nullish(id) && id || !nullish(text) && text || '' |
| | } |
| | })) || [] |
| | )) |
| | } |
| | let message = { |
| | ...options, |
| | [buffer ? 'caption' : 'text']: text || '', |
| | footer, |
| | templateButtons, |
| | ...(buffer ? |
| | options.asLocation && /image/.test(type.mime) ? { |
| | location: { |
| | ...options, |
| | jpegThumbnail: buffer |
| | } |
| | } : { |
| | [/video/.test(type.mime) ? 'video' : /image/.test(type.mime) ? 'image' : 'document']: buffer |
| | } : {}) |
| | } |
| | return await conn.sendMessage(jid, message, { |
| | quoted, |
| | upload: conn.waUploadToServer, |
| | ...options |
| | }) |
| | }, |
| | enumerable: true |
| | }, |
| | |
| | |
| | |
| | sendPoll: { |
| | async value(jid, name = '', optiPoll, options) { |
| | if (!Array.isArray(optiPoll[0]) && typeof optiPoll[0] === 'string') optiPoll = [optiPoll] |
| | if (!options) options = {} |
| | const pollMessage = { |
| | name: name, |
| | options: optiPoll.map(btn => ({ |
| | optionName: !nullish(btn[0]) && btn[0] || '' |
| | })), |
| | selectableOptionsCount: 1 |
| | } |
| | return conn.relayMessage(jid, { pollCreationMessage: pollMessage }, { ...options }); |
| | } |
| | }, |
| | |
| | cMod: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(jid, message, text = '', sender = conn.user.jid, options = {}) { |
| | if (options.mentions && !Array.isArray(options.mentions)) options.mentions = [options.mentions] |
| | let copy = message.toJSON() |
| | delete copy.message.messageContextInfo |
| | delete copy.message.senderKeyDistributionMessage |
| | let mtype = Object.keys(copy.message)[0] |
| | let msg = copy.message |
| | let content = msg[mtype] |
| | if (typeof content === 'string') msg[mtype] = text || content |
| | else if (content.caption) content.caption = text || content.caption |
| | else if (content.text) content.text = text || content.text |
| | if (typeof content !== 'string') { |
| | msg[mtype] = { ...content, ...options } |
| | msg[mtype].contextInfo = { |
| | ...(content.contextInfo || {}), |
| | mentionedJid: options.mentions || content.contextInfo?.mentionedJid || [] |
| | } |
| | } |
| | if (copy.participant) sender = copy.participant = sender || copy.participant |
| | else if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant |
| | if (copy.key.remoteJid.includes('@s.whatsapp.net')) sender = sender || copy.key.remoteJid |
| | else if (copy.key.remoteJid.includes('@broadcast')) sender = sender || copy.key.remoteJid |
| | copy.key.remoteJid = jid |
| | copy.key.fromMe = areJidsSameUser(sender, conn.user.id) || false |
| | return proto.WebMessageInfo.fromObject(copy) |
| | }, |
| | enumerable: true |
| | }, |
| | copyNForward: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async value(jid, message, forwardingScore = true, options = {}) { |
| | let vtype |
| | if (options.readViewOnce && message.message.viewOnceMessage?.message) { |
| | vtype = Object.keys(message.message.viewOnceMessage.message)[0] |
| | delete message.message.viewOnceMessage.message[vtype].viewOnce |
| | message.message = proto.Message.fromObject( |
| | JSON.parse(JSON.stringify(message.message.viewOnceMessage.message)) |
| | ) |
| | message.message[vtype].contextInfo = message.message.viewOnceMessage.contextInfo |
| | } |
| | let mtype = Object.keys(message.message)[0] |
| | let m = generateForwardMessageContent(message, !!forwardingScore) |
| | let ctype = Object.keys(m)[0] |
| | if (forwardingScore && typeof forwardingScore === 'number' && forwardingScore > 200000) m[ctype].contextInfo.forwardingScore += forwardingScore |
| | m[ctype].contextInfo = { |
| | ...(message.message[mtype].contextInfo || {}), |
| | ...(m[ctype].contextInfo || {}) |
| | } |
| | m = generateWAMessageFromContent(jid, m, { |
| | ...options, |
| | userJid: conn.user.jid |
| | }) |
| | await conn.relayMessage(jid, m.message, { messageId: m.key.id, additionalAttributes: { ...options } }) |
| | return m |
| | }, |
| | enumerable: true |
| | }, |
| | fakeReply: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(jid, text = '', fakeJid = this.user.jid, fakeText = '', fakeGroupJid, options) { |
| | return conn.reply(jid, text, { key: { fromMe: areJidsSameUser(fakeJid, conn.user.id), participant: fakeJid, ...(fakeGroupJid ? { remoteJid: fakeGroupJid } : {}) }, message: { conversation: fakeText }, ...options }) |
| | } |
| | }, |
| | downloadM: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async value(m, type, saveToFile) { |
| | let filename |
| | if (!m || !(m.url || m.directPath)) return Buffer.alloc(0) |
| | const stream = await downloadContentFromMessage(m, type) |
| | let buffer = Buffer.from([]) |
| | for await (const chunk of stream) { |
| | buffer = Buffer.concat([buffer, chunk]) |
| | } |
| | if (saveToFile) ({ filename } = await conn.getFile(buffer, true)) |
| | return saveToFile && fs.existsSync(filename) ? filename : buffer |
| | }, |
| | enumerable: true |
| | }, |
| | parseMention: { |
| | |
| | |
| | |
| | |
| | |
| | value(text = '') { |
| | return [...text.matchAll(/@([0-9]{5,16}|0)/g)].map(v => v[1] + '@s.whatsapp.net') |
| | }, |
| | enumerable: true |
| | }, |
| | getName: { |
| | |
| | |
| | |
| | |
| | |
| | value(jid = '', withoutContact = false) { |
| | jid = conn.decodeJid(jid) |
| | withoutContact = conn.withoutContact || withoutContact |
| | let v |
| | if (jid.endsWith('@g.us')) return new Promise(async (resolve) => { |
| | v = conn.chats[jid] || {} |
| | if (!(v.name || v.subject)) v = await conn.groupMetadata(jid) || {} |
| | resolve(v.name || v.subject || PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international')) |
| | }) |
| | else v = jid === '0@s.whatsapp.net' ? { |
| | jid, |
| | vname: 'WhatsApp' |
| | } : areJidsSameUser(jid, conn.user.id) ? |
| | conn.user : |
| | (conn.chats[jid] || {}) |
| | return (withoutContact ? '' : v.name) || v.subject || v.vname || v.notify || v.verifiedName || PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international') |
| | }, |
| | enumerable: true |
| | }, |
| |
|
| | send3TemplateButtonImg: { |
| | async value (jid, buffer, content, footerText, button1, id1, button2, id2, button3, id3, quoted, options) { |
| | let type = await conn.getFile(buffer) |
| | let { res, data: file } = type |
| | if (res && res.status !== 200 || file.length <= 65536) { |
| | try { throw { json: JSON.parse(file.toString()) } } |
| | catch (e) { if (e.json) throw e.json } |
| | } |
| | const buttons = [ |
| | { index: 1, urlButton: { displayText: dtu, url: urlnya } }, |
| | { index: 2, quickReplyButton: { displayText: button1, id: id1 } }, |
| | { index: 3, quickReplyButton: { displayText: button2, id: id2 } }, |
| | { index: 4, quickReplyButton: { displayText: button3, id: id3 } } |
| | ] |
| | const buttonMessage = { |
| | image: file, |
| | caption: content, |
| | footer: footerText, |
| | mentions: await conn.parseMention(content + footerText), |
| | ephemeralExpiration: 86400, |
| | ...options, |
| | templateButtons: buttons, |
| | headerType: 1 |
| | } |
| | conn.sendMessage(jid, buttonMessage, { quoted, ephemeralExpiration: 86400, contextInfo: { mentionedJid: conn.parseMention(content + footerText), forwardingScore: 99999, isForwarded: true }, ...options, ephemeralExpiration: 86400 } ) |
| | } |
| | }, |
| | |
| | loadMessage: { |
| | |
| | |
| | |
| | |
| | |
| | value(messageID) { |
| | return Object.entries(conn.chats) |
| | .filter(([_, { messages }]) => typeof messages === 'object') |
| | .find(([_, { messages }]) => Object.entries(messages) |
| | .find(([k, v]) => (k === messageID || v.key?.id === messageID))) |
| | ?.[1].messages?.[messageID] |
| | }, |
| | enumerable: true |
| | }, |
| | sendGroupV4Invite: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async value(jid, participant, inviteCode, inviteExpiration, groupName = 'unknown subject', caption = 'Invitation to join my WhatsApp group', jpegThumbnail, options = {}) { |
| | const msg = proto.Message.fromObject({ |
| | groupInviteMessage: proto.GroupInviteMessage.fromObject({ |
| | inviteCode, |
| | inviteExpiration: parseInt(inviteExpiration) || + new Date(new Date + (3 * 86400000)), |
| | groupJid: jid, |
| | groupName: (groupName ? groupName : await conn.getName(jid)) || null, |
| | jpegThumbnail: Buffer.isBuffer(jpegThumbnail) ? jpegThumbnail : null, |
| | caption |
| | }) |
| | }) |
| | const message = generateWAMessageFromContent(participant, msg, options) |
| | await conn.relayMessage(participant, message.message, { messageId: message.key.id, additionalAttributes: { ...options } }) |
| | return message |
| | }, |
| | enumerable: true |
| | }, |
| |
|
| | prepareMessageMedia: { |
| | |
| | |
| | |
| | |
| | |
| | async value (message, options) { |
| | const logger = options.logger; |
| | let mediaType; |
| | for (const key of Defaults_1.MEDIA_KEYS) { |
| | if (key in message) { |
| | mediaType = key; |
| | } |
| | } |
| | const uploadData = { |
| | ...message, |
| | media: message[mediaType] |
| | }; |
| | delete uploadData[mediaType]; |
| | |
| | const cacheableKey = typeof uploadData.media === 'object' && |
| | ('url' in uploadData.media) && |
| | !!uploadData.media.url && |
| | !!options.mediaCache && ( |
| | |
| | mediaType + ':' + uploadData.media.url.toString()); |
| | if (mediaType === 'document' && !uploadData.fileName) { |
| | uploadData.fileName = 'file'; |
| | } |
| | if (!uploadData.mimetype) { |
| | uploadData.mimetype = MIMETYPE_MAP[mediaType]; |
| | } |
| | |
| | if (cacheableKey) { |
| | const mediaBuff = options.mediaCache.get(cacheableKey); |
| | if (mediaBuff) { |
| | logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'got media cache hit'); |
| | const obj = Types_1.WAProto.Message.decode(mediaBuff); |
| | const key = `${mediaType}Message`; |
| | delete uploadData.media; |
| | Object.assign(obj[key], { ...uploadData }); |
| | return obj; |
| | } |
| | } |
| | const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined'; |
| | const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && |
| | (typeof uploadData['jpegThumbnail'] === 'undefined'); |
| | const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation; |
| | const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath } = await messages_media_1.encryptedStream(uploadData.media, mediaType, requiresOriginalForSomeProcessing); |
| | |
| | const fileEncSha256B64 = encodeURIComponent(fileEncSha256.toString('base64') |
| | .replace(/\+/g, '-') |
| | .replace(/\//g, '_') |
| | .replace(/\=+$/, '')); |
| | const [{ mediaUrl, directPath }] = await Promise.all([ |
| | (async () => { |
| | const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs }); |
| | logger === null || logger === void 0 ? void 0 : logger.debug('uploaded media'); |
| | return result; |
| | })(), |
| | (async () => { |
| | try { |
| | if (requiresThumbnailComputation) { |
| | uploadData.jpegThumbnail = await messages_media_1.generateThumbnail(bodyPath, mediaType, options); |
| | logger === null || logger === void 0 ? void 0 : logger.debug('generated thumbnail'); |
| | } |
| | if (requiresDurationComputation) { |
| | uploadData.seconds = await messages_media_1.getAudioDuration(bodyPath); |
| | logger === null || logger === void 0 ? void 0 : logger.debug('computed audio duration'); |
| | } |
| | } |
| | catch (error) { |
| | logger === null || logger === void 0 ? void 0 : logger.warn({ trace: error.stack }, 'failed to obtain extra info'); |
| | } |
| | })(), |
| | ]) |
| | .finally(async () => { |
| | encWriteStream.destroy(); |
| | |
| | if (didSaveToTmpPath && bodyPath) { |
| | await fs_1.promises.unlink(bodyPath); |
| | logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files'); |
| | } |
| | }); |
| | delete uploadData.media; |
| | const obj = Types_1.WAProto.Message.fromObject({ |
| | [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({ |
| | url, |
| | directPath, |
| | mediaKey, |
| | fileEncSha256, |
| | fileSha256, |
| | fileLength: '999999999', |
| | mediaKeyTimestamp: generics_1.unixTimestampSeconds(), |
| | ...uploadData |
| | }) |
| | }); |
| | if (cacheableKey) { |
| | logger.debug({ cacheableKey }, 'set cache'); |
| | options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish()); |
| | } |
| | return obj; |
| | } |
| | }, |
| | |
| | processMessageStubType: { |
| | |
| | |
| | |
| | |
| | async value(m) { |
| | if (!m.messageStubType) return |
| | const chat = conn.decodeJid(m.key.remoteJid || m.message?.senderKeyDistributionMessage?.groupId || '') |
| | if (!chat || chat === 'status@broadcast') return |
| | const emitGroupUpdate = (update) => { |
| | ev.emit('groups.update', [{ id: chat, ...update }]) |
| | } |
| | switch (m.messageStubType) { |
| | case WAMessageStubType.REVOKE: |
| | case WAMessageStubType.GROUP_CHANGE_INVITE_LINK: |
| | emitGroupUpdate({ revoke: m.messageStubParameters[0] }) |
| | break |
| | case WAMessageStubType.GROUP_CHANGE_ICON: |
| | emitGroupUpdate({ icon: m.messageStubParameters[0] }) |
| | break |
| | default: { |
| | console.log({ |
| | messageStubType: m.messageStubType, |
| | messageStubParameters: m.messageStubParameters, |
| | type: WAMessageStubType[m.messageStubType] |
| | }) |
| | break |
| | } |
| | } |
| | const isGroup = chat.endsWith('@g.us') |
| | if (!isGroup) return |
| | let chats = conn.chats[chat] |
| | if (!chats) chats = conn.chats[chat] = { id: chat } |
| | chats.isChats = true |
| | const metadata = await conn.groupMetadata(chat).catch(_ => null) |
| | if (!metadata) return |
| | chats.subject = metadata.subject |
| | chats.metadata = metadata |
| | } |
| | }, |
| | insertAllGroup: { |
| | async value() { |
| | const groups = await conn.groupFetchAllParticipating().catch(_ => null) || {} |
| | for (const group in groups) conn.chats[group] = { ...(conn.chats[group] || {}), id: group, subject: groups[group].subject, isChats: true, metadata: groups[group] } |
| | return conn.chats |
| | }, |
| | }, |
| | pushMessage: { |
| | |
| | |
| | |
| | |
| | async value(m) { |
| | if (!m) return |
| | if (!Array.isArray(m)) m = [m] |
| | for (const message of m) { |
| | try { |
| | |
| | if (!message) continue |
| | if (message.messageStubType && message.messageStubType != WAMessageStubType.CIPHERTEXT) conn.processMessageStubType(message).catch(console.error) |
| | const _mtype = Object.keys(message.message || {}) |
| | const mtype = (!['senderKeyDistributionMessage', 'messageContextInfo'].includes(_mtype[0]) && _mtype[0]) || |
| | (_mtype.length >= 3 && _mtype[1] !== 'messageContextInfo' && _mtype[1]) || |
| | _mtype[_mtype.length - 1] |
| | const chat = conn.decodeJid(message.key.remoteJid || message.message?.senderKeyDistributionMessage?.groupId || '') |
| | if (message.message?.[mtype]?.contextInfo?.quotedMessage) { |
| | |
| | |
| | |
| | let context = message.message[mtype].contextInfo |
| | let participant = conn.decodeJid(context.participant) |
| | const remoteJid = conn.decodeJid(context.remoteJid || participant) |
| | |
| | |
| | |
| | |
| | let quoted = message.message[mtype].contextInfo.quotedMessage |
| | if ((remoteJid && remoteJid !== 'status@broadcast') && quoted) { |
| | let qMtype = Object.keys(quoted)[0] |
| | if (qMtype == 'conversation') { |
| | quoted.extendedTextMessage = { text: quoted[qMtype] } |
| | delete quoted.conversation |
| | qMtype = 'extendedTextMessage' |
| | } |
| | if (!quoted[qMtype].contextInfo) quoted[qMtype].contextInfo = {} |
| | quoted[qMtype].contextInfo.mentionedJid = context.mentionedJid || quoted[qMtype].contextInfo.mentionedJid || [] |
| | const isGroup = remoteJid.endsWith('g.us') |
| | if (isGroup && !participant) participant = remoteJid |
| | const qM = { |
| | key: { |
| | remoteJid, |
| | fromMe: areJidsSameUser(conn.user.jid, remoteJid), |
| | id: context.stanzaId, |
| | participant, |
| | }, |
| | message: JSON.parse(JSON.stringify(quoted)), |
| | ...(isGroup ? { participant } : {}) |
| | } |
| | let qChats = conn.chats[participant] |
| | if (!qChats) qChats = conn.chats[participant] = { id: participant, isChats: !isGroup } |
| | if (!qChats.messages) qChats.messages = {} |
| | if (!qChats.messages[context.stanzaId] && !qM.key.fromMe) qChats.messages[context.stanzaId] = qM |
| | let qChatsMessages |
| | if ((qChatsMessages = Object.entries(qChats.messages)).length > 40) qChats.messages = Object.fromEntries(qChatsMessages.slice(30, qChatsMessages.length)) |
| | } |
| | } |
| | if (!chat || chat === 'status@broadcast') continue |
| | const isGroup = chat.endsWith('@g.us') |
| | let chats = conn.chats[chat] |
| | if (!chats) { |
| | if (isGroup) await conn.insertAllGroup().catch(console.error) |
| | chats = conn.chats[chat] = { id: chat, isChats: true, ...(conn.chats[chat] || {}) } |
| | } |
| | let metadata, sender |
| | if (isGroup) { |
| | if (!chats.subject || !chats.metadata) { |
| | metadata = await conn.groupMetadata(chat).catch(_ => ({})) || {} |
| | if (!chats.subject) chats.subject = metadata.subject || '' |
| | if (!chats.metadata) chats.metadata = metadata |
| | } |
| | sender = conn.decodeJid(message.key?.fromMe && conn.user.id || message.participant || message.key?.participant || chat || '') |
| | if (sender !== chat) { |
| | let chats = conn.chats[sender] |
| | if (!chats) chats = conn.chats[sender] = { id: sender } |
| | if (!chats.name) chats.name = message.pushName || chats.name || '' |
| | } |
| | } else if (!chats.name) chats.name = message.pushName || chats.name || '' |
| | if (['senderKeyDistributionMessage', 'messageContextInfo'].includes(mtype)) continue |
| | chats.isChats = true |
| | if (!chats.messages) chats.messages = {} |
| | const fromMe = message.key.fromMe || areJidsSameUser(sender || chat, conn.user.id) |
| | if (!['protocolMessage'].includes(mtype) && !fromMe && message.messageStubType != WAMessageStubType.CIPHERTEXT && message.message) { |
| | delete message.message.messageContextInfo |
| | delete message.message.senderKeyDistributionMessage |
| | chats.messages[message.key.id] = JSON.parse(JSON.stringify(message, null, 2)) |
| | let chatsMessages |
| | if ((chatsMessages = Object.entries(chats.messages)).length > 40) chats.messages = Object.fromEntries(chatsMessages.slice(30, chatsMessages.length)) |
| | } |
| | } catch (e) { |
| | console.error(e) |
| | } |
| | } |
| | } |
| | }, |
| | serializeM: { |
| | |
| | |
| | |
| | |
| | value(m) { |
| | return smsg(conn, m) |
| | } |
| | }, |
| | updateProfilePicture: { |
| | async value(jid, content) { |
| | const { img } = await generateProfilePicture(content) |
| | return conn.query({ |
| | tag: 'iq', |
| | attrs: { to: jidNormalizedUser(jid), type: 'set', xmlns: 'w:profile:picture' }, |
| | content: [ { tag: 'picture', attrs: { type: 'image' }, content: img }] |
| | }) |
| | }, |
| | enumerable: true |
| | }, |
| | ...(typeof conn.chatRead !== 'function' ? { |
| | chatRead: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(jid, participant = conn.user.jid, messageID) { |
| | return conn.sendReadReceipt(jid, participant, [messageID]) |
| | }, |
| | enumerable: true |
| | } |
| | } : {}), |
| | ...(typeof conn.setStatus !== 'function' ? { |
| | setStatus: { |
| | |
| | |
| | |
| | |
| | value(status) { |
| | return conn.query({ |
| | tag: 'iq', |
| | attrs: { |
| | to: '@s.whatsapp.net', |
| | type: 'set', |
| | xmlns: 'status', |
| | }, |
| | content: [ |
| | { |
| | tag: 'status', |
| | attrs: {}, |
| | content: Buffer.from(status, 'utf-8') |
| | } |
| | ] |
| | }) |
| | }, |
| | enumerable: true |
| | } |
| | } : {}) |
| | }) |
| | if (sock.user?.id) sock.user.jid = sock.decodeJid(sock.user.id) |
| | store.bind(sock) |
| | return sock |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | export function smsg(conn, m, hasParent) { |
| | if (!m) return m |
| | |
| | |
| | |
| | let M = proto.WebMessageInfo |
| | m = M.fromObject(m) |
| | m.conn = conn |
| | let protocolMessageKey |
| | if (m.message) { |
| | if (m.mtype == 'protocolMessage' && m.msg.key) { |
| | protocolMessageKey = m.msg.key |
| | if (protocolMessageKey == 'status@broadcast') protocolMessageKey.remoteJid = m.chat |
| | if (!protocolMessageKey.participant || protocolMessageKey.participant == 'status_me') protocolMessageKey.participant = m.sender |
| | protocolMessageKey.fromMe = conn.decodeJid(protocolMessageKey.participant) === conn.decodeJid(conn.user.id) |
| | if (!protocolMessageKey.fromMe && protocolMessageKey.remoteJid === conn.decodeJid(conn.user.id)) protocolMessageKey.remoteJid = m.sender |
| | } |
| | if (m.quoted) if (!m.quoted.mediaMessage) delete m.quoted.download |
| | } |
| | if (!m.mediaMessage) delete m.download |
| |
|
| | try { |
| | if (protocolMessageKey && m.mtype == 'protocolMessage') conn.ev.emit('message.delete', protocolMessageKey) |
| | } catch (e) { |
| | console.error(e) |
| | } |
| | return m |
| | } |
| |
|
| | |
| | export function serialize() { |
| | const MediaType = ['imageMessage', 'videoMessage', 'audioMessage', 'stickerMessage', 'documentMessage'] |
| | return Object.defineProperties(proto.WebMessageInfo.prototype, { |
| | conn: { |
| | value: undefined, |
| | enumerable: false, |
| | writable: true |
| | }, |
| | id: { |
| | get() { |
| | return this.key?.id |
| | } |
| | }, |
| | isBaileys: { |
| | get() { |
| | return this.id?.length === 16 || this.id?.startsWith('3EB0') && this.id?.length === 12 || false |
| | } |
| | }, |
| | chat: { |
| | get() { |
| | const senderKeyDistributionMessage = this.message?.senderKeyDistributionMessage?.groupId |
| | return ( |
| | this.key?.remoteJid || |
| | (senderKeyDistributionMessage && |
| | senderKeyDistributionMessage !== 'status@broadcast' |
| | ) || '' |
| | ).decodeJid() |
| | } |
| | }, |
| | isGroup: { |
| | get() { |
| | return this.chat.endsWith('@g.us') |
| | }, |
| | enumerable: true |
| | }, |
| | sender: { |
| | get() { |
| | return this.conn?.decodeJid(this.key?.fromMe && this.conn?.user.id || this.participant || this.key.participant || this.chat || '') |
| | }, |
| | enumerable: true |
| | }, |
| | fromMe: { |
| | get() { |
| | return this.key?.fromMe || areJidsSameUser(this.conn?.user.id, this.sender) || false |
| | } |
| | }, |
| | mtype: { |
| | get() { |
| | if (!this.message) return '' |
| | const type = Object.keys(this.message) |
| | return (!['senderKeyDistributionMessage', 'messageContextInfo'].includes(type[0]) && type[0]) || |
| | (type.length >= 3 && type[1] !== 'messageContextInfo' && type[1]) || |
| | type[type.length - 1] |
| | }, |
| | enumerable: true |
| | }, |
| | msg: { |
| | get() { |
| | if (!this.message) return null |
| | return this.message[this.mtype] |
| | } |
| | }, |
| | mediaMessage: { |
| | get() { |
| | if (!this.message) return null |
| | const Message = ((this.msg?.url || this.msg?.directPath) ? { ...this.message } : extractMessageContent(this.message)) || null |
| | if (!Message) return null |
| | const mtype = Object.keys(Message)[0] |
| | return MediaType.includes(mtype) ? Message : null |
| | }, |
| | enumerable: true |
| | }, |
| | mediaType: { |
| | get() { |
| | let message |
| | if (!(message = this.mediaMessage)) return null |
| | return Object.keys(message)[0] |
| | }, |
| | enumerable: true, |
| | }, |
| | quoted: { |
| | get() { |
| | |
| | |
| | |
| | const self = this |
| | const msg = self.msg |
| | const contextInfo = msg?.contextInfo |
| | const quoted = contextInfo?.quotedMessage |
| | if (!msg || !contextInfo || !quoted) return null |
| | const type = Object.keys(quoted)[0] |
| | let q = quoted[type] |
| | const text = typeof q === 'string' ? q : q.text |
| | return Object.defineProperties(JSON.parse(JSON.stringify(typeof q === 'string' ? { text: q } : q)), { |
| | mtype: { |
| | get() { |
| | return type |
| | }, |
| | enumerable: true |
| | }, |
| | mediaMessage: { |
| | get() { |
| | const Message = ((q.url || q.directPath) ? { ...quoted } : extractMessageContent(quoted)) || null |
| | if (!Message) return null |
| | const mtype = Object.keys(Message)[0] |
| | return MediaType.includes(mtype) ? Message : null |
| | }, |
| | enumerable: true |
| | }, |
| | mediaType: { |
| | get() { |
| | let message |
| | if (!(message = this.mediaMessage)) return null |
| | return Object.keys(message)[0] |
| | }, |
| | enumerable: true, |
| | }, |
| | id: { |
| | get() { |
| | return contextInfo.stanzaId |
| | }, |
| | enumerable: true |
| | }, |
| | chat: { |
| | get() { |
| | return contextInfo.remoteJid || self.chat |
| | }, |
| | enumerable: true |
| | }, |
| | isBaileys: { |
| | get() { |
| | return this.id?.length === 16 || this.id?.startsWith('3EB0') && this.id.length === 12 || false |
| | }, |
| | enumerable: true |
| | }, |
| | sender: { |
| | get() { |
| | return (contextInfo.participant || this.chat || '').decodeJid() |
| | }, |
| | enumerable: true |
| | }, |
| | fromMe: { |
| | get() { |
| | return areJidsSameUser(this.sender, self.conn?.user.jid) |
| | }, |
| | enumerable: true, |
| | }, |
| | text: { |
| | get() { |
| | return text || this.caption || this.contentText || this.selectedDisplayText || '' |
| | }, |
| | enumerable: true |
| | }, |
| | mentionedJid: { |
| | get() { |
| | return q.contextInfo?.mentionedJid || self.getQuotedObj()?.mentionedJid || [] |
| | }, |
| | enumerable: true |
| | }, |
| | name: { |
| | get() { |
| | const sender = this.sender |
| | return sender ? self.conn?.getName(sender) : null |
| | }, |
| | enumerable: true |
| |
|
| | }, |
| | vM: { |
| | get() { |
| | return proto.WebMessageInfo.fromObject({ |
| | key: { |
| | fromMe: this.fromMe, |
| | remoteJid: this.chat, |
| | id: this.id |
| | }, |
| | message: quoted, |
| | ...(self.isGroup ? { participant: this.sender } : {}) |
| | }) |
| | } |
| | }, |
| | fakeObj: { |
| | get() { |
| | return this.vM |
| | } |
| | }, |
| | download: { |
| | value(saveToFile = false) { |
| | const mtype = this.mediaType |
| | return self.conn?.downloadM(this.mediaMessage[mtype], mtype.replace(/message/i, ''), saveToFile) |
| | }, |
| | enumerable: true, |
| | configurable: true, |
| | }, |
| | replyV2: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(text, chatId, options) { |
| | return self.conn?.replyV2(chatId ? chatId : this.chat, text, this.vM, options) |
| | }, |
| | enumerable: true, |
| | }, |
| | reply: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(text, chatId, options) { |
| | return self.conn?.reply(chatId ? chatId : this.chat, text, this.vM, options) |
| | }, |
| | enumerable: true, |
| | }, |
| | copy: { |
| | |
| | |
| | |
| | value() { |
| | const M = proto.WebMessageInfo |
| | return smsg(conn, M.fromObject(M.toObject(this.vM))) |
| | }, |
| | enumerable: true, |
| | }, |
| | forward: { |
| | |
| | |
| | |
| | |
| | |
| | value(jid, force = false, options) { |
| | return self.conn?.sendMessage(jid, { |
| | forward: this.vM, force, ...options |
| | }, { ...options }) |
| | }, |
| | enumerable: true, |
| | }, |
| | copyNForward: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(jid, forceForward = false, options) { |
| | return self.conn?.copyNForward(jid, this.vM, forceForward, options) |
| | }, |
| | enumerable: true, |
| |
|
| | }, |
| | cMod: { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | value(jid, text = '', sender = this.sender, options = {}) { |
| | return self.conn?.cMod(jid, this.vM, text, sender, options) |
| | }, |
| | enumerable: true, |
| |
|
| | }, |
| | delete: { |
| | |
| | |
| | |
| | value() { |
| | return self.conn?.sendMessage(this.chat, { delete: this.vM.key }) |
| | }, |
| | enumerable: true, |
| |
|
| | } |
| | }) |
| | }, |
| | enumerable: true |
| | }, |
| | _text: { |
| | value: null, |
| | writable: true, |
| | }, |
| | text: { |
| | get() { |
| | const msg = this.msg |
| | const text = (typeof msg === 'string' ? msg : msg?.text) || msg?.caption || msg?.contentText || '' |
| | return typeof this._text === 'string' ? this._text : '' || (typeof text === 'string' ? text : ( |
| | text?.selectedDisplayText || |
| | text?.hydratedTemplate?.hydratedContentText || |
| | text |
| | )) || '' |
| | }, |
| | set(str) { |
| | return this._text = str |
| | }, |
| | enumerable: true |
| | }, |
| | mentionedJid: { |
| | get() { |
| | return this.msg?.contextInfo?.mentionedJid?.length && this.msg.contextInfo.mentionedJid || [] |
| | }, |
| | enumerable: true |
| | }, |
| | name: { |
| | get() { |
| | return !nullish(this.pushName) && this.pushName || this.conn?.getName(this.sender) |
| | }, |
| | enumerable: true |
| | }, |
| | download: { |
| | value(saveToFile = false) { |
| | const mtype = this.mediaType |
| | return this.conn?.downloadM(this.mediaMessage[mtype], mtype.replace(/message/i, ''), saveToFile) |
| | }, |
| | enumerable: true, |
| | configurable: true |
| | }, |
| | replyV2: { |
| | value(text, chatId, options) { |
| | return this.conn?.replyV2(chatId ? chatId : this.chat, text, this, options) |
| | } |
| | }, |
| | reply: { |
| | value(text, chatId, options) { |
| | return this.conn?.reply(chatId ? chatId : this.chat, text, this, options) |
| | } |
| | }, |
| | copy: { |
| | value() { |
| | const M = proto.WebMessageInfo |
| | return smsg(this.conn, M.fromObject(M.toObject(this))) |
| | }, |
| | enumerable: true |
| | }, |
| | forward: { |
| | value(jid, force = false, options = {}) { |
| | return this.conn?.sendMessage(jid, { |
| | forward: this, force, ...options |
| | }, { ...options }) |
| | }, |
| | enumerable: true |
| | }, |
| | copyNForward: { |
| | value(jid, forceForward = false, options = {}) { |
| | return this.conn?.copyNForward(jid, this, forceForward, options) |
| | }, |
| | enumerable: true |
| | }, |
| | cMod: { |
| | value(jid, text = '', sender = this.sender, options = {}) { |
| | return this.conn?.cMod(jid, this, text, sender, options) |
| | }, |
| | enumerable: true |
| | }, |
| | getQuotedObj: { |
| | value() { |
| | if (!this.quoted.id) return null |
| | const q = proto.WebMessageInfo.fromObject(this.conn?.loadMessage(this.quoted.id) || this.quoted.vM) |
| | return smsg(this.conn, q) |
| | }, |
| | enumerable: true |
| | }, |
| | getQuotedMessage: { |
| | get() { |
| | return this.getQuotedObj |
| | } |
| | }, |
| | delete: { |
| | value() { |
| | return this.conn?.sendMessage(this.chat, { delete: this.key }) |
| | }, |
| | enumerable: true |
| | } |
| | }) |
| | } |
| |
|
| | export function logic(check, inp, out) { |
| | if (inp.length !== out.length) throw new Error('Input and Output must have same length') |
| | for (let i in inp) if (util.isDeepStrictEqual(check, inp[i])) return out[i] |
| | return null |
| | } |
| |
|
| | export function protoType() { |
| | Buffer.prototype.toArrayBuffer = function toArrayBufferV2() { |
| | const ab = new ArrayBuffer(this.length); |
| | const view = new Uint8Array(ab); |
| | for (let i = 0; i < this.length; ++i) { |
| | view[i] = this[i]; |
| | } |
| | return ab; |
| | } |
| | |
| | |
| | |
| | Buffer.prototype.toArrayBufferV2 = function toArrayBuffer() { |
| | return this.buffer.slice(this.byteOffset, this.byteOffset + this.byteLength) |
| | } |
| | |
| | |
| | |
| | ArrayBuffer.prototype.toBuffer = function toBuffer() { |
| | return Buffer.from(new Uint8Array(this)) |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | Uint8Array.prototype.getFileType = ArrayBuffer.prototype.getFileType = Buffer.prototype.getFileType = async function getFileType() { |
| | return await fileTypeFromBuffer(this) |
| | } |
| | |
| | |
| | |
| | String.prototype.isNumber = Number.prototype.isNumber = isNumber |
| | |
| | |
| | |
| | |
| | String.prototype.capitalize = function capitalize() { |
| | return this.charAt(0).toUpperCase() + this.slice(1, this.length) |
| | } |
| | |
| | |
| | |
| | String.prototype.capitalizeV2 = function capitalizeV2() { |
| | const str = this.split(' ') |
| | return str.map(v => v.capitalize()).join(' ') |
| | } |
| | String.prototype.decodeJid = function decodeJid() { |
| | if (/:\d+@/gi.test(this)) { |
| | const decode = jidDecode(this) || {} |
| | return (decode.user && decode.server && decode.user + '@' + decode.server || this).trim() |
| | } else return this.trim() |
| | } |
| | |
| | |
| | |
| | |
| | Number.prototype.toTimeString = function toTimeString() { |
| | |
| | const seconds = Math.floor((this / 1000) % 60) |
| | const minutes = Math.floor((this / (60 * 1000)) % 60) |
| | const hours = Math.floor((this / (60 * 60 * 1000)) % 24) |
| | const days = Math.floor((this / (24 * 60 * 60 * 1000))) |
| | return ( |
| | (days ? `${days} day(s) ` : '') + |
| | (hours ? `${hours} hour(s) ` : '') + |
| | (minutes ? `${minutes} minute(s) ` : '') + |
| | (seconds ? `${seconds} second(s)` : '') |
| | ).trim() |
| | } |
| | Number.prototype.getRandom = String.prototype.getRandom = Array.prototype.getRandom = getRandom |
| | } |
| |
|
| |
|
| | function isNumber() { |
| | const int = parseInt(this) |
| | return typeof int === 'number' && !isNaN(int) |
| | } |
| |
|
| | function getRandom() { |
| | if (Array.isArray(this) || this instanceof String) return this[Math.floor(Math.random() * this.length)] |
| | return Math.floor(Math.random() * this) |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | function nullish(args) { |
| | return !(args !== null && args !== undefined) |
| | } |
| |
|
| | async function generateProfilePicture(mediaUpload) { |
| | let bufferOrFilePath |
| | if (Buffer.isBuffer(mediaUpload)) bufferOrFilePath = mediaUpload |
| | else if ('url' in mediaUpload) bufferOrFilePath = mediaUpload.url.toString() |
| | else bufferOrFilePath = await Baileys.toBuffer(mediaUpload.stream) |
| | const { read, MIME_JPEG, AUTO } = await Promise.resolve().then(async () => (await import('jimp')).default) |
| | const jimp = await read(bufferOrFilePath) |
| | const min = jimp.getWidth() |
| | const max = jimp.getHeight() |
| | const cropped = jimp.crop(0, 0, min, max) |
| | return { |
| | img: await cropped.quality(100).scaleToFit(720, 720, AUTO).getBufferAsync(MIME_JPEG) |
| | } |
| | } |
| |
|
| |
|
| | |
| |
|
| |
|
| | |
| |
|
| |
|
| |
|
| | |
| |
|