mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-18 03:29:15 +00:00
fix(adapter): 🔥 improvement baileys
fix(adapter): 🔥 improvement baileys
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
"./mock": "./lib/mock/index.cjs",
|
||||
"./twilio": "./lib/twilio/index.cjs",
|
||||
"./web-whatsapp": "./lib/web-whatsapp/index.cjs",
|
||||
"./venom": "./lib/venom/index.cjs"
|
||||
"./venom": "./lib/venom/index.cjs",
|
||||
"./baileys": "./lib/baileys/index.cjs"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +39,13 @@ module.exports = [
|
||||
},
|
||||
plugins: [commonjs()],
|
||||
},
|
||||
{
|
||||
input: join(__dirname, 'src', 'baileys', 'index.js'),
|
||||
output: {
|
||||
banner: banner['banner.output'].join(''),
|
||||
file: join(__dirname, 'lib', 'baileys', 'index.cjs'),
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [commonjs()],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,79 +1,171 @@
|
||||
const { ProviderClass } = require('@bot-whatsapp/bot')
|
||||
const PINO = require('pino')
|
||||
const makeWASocket = require('@adiwajshing/baileys').default
|
||||
const { useMultiFileAuthState } = require('@adiwajshing/baileys')
|
||||
const pino = require('pino')
|
||||
const {
|
||||
default: makeWASocket,
|
||||
useMultiFileAuthState,
|
||||
} = require('@adiwajshing/baileys')
|
||||
const {
|
||||
baileyGenerateImage,
|
||||
baileyCleanNumber,
|
||||
baileyIsValidNumber,
|
||||
} = require('./utils')
|
||||
|
||||
class Baileys extends ProviderClass {
|
||||
/**
|
||||
* ⚙️ BaileysProvider: Es una clase tipo adaptor
|
||||
* que extiende clases de ProviderClass (la cual es como interfaz para sber que funciones rqueridas)
|
||||
* https://github.com/adiwajshing/Baileys
|
||||
*/
|
||||
class BaileysProvider extends ProviderClass {
|
||||
vendor
|
||||
constructor() {
|
||||
super()
|
||||
this.sock
|
||||
this.initBailey().then(() => this.initBusEvents())
|
||||
}
|
||||
|
||||
async baileys() {
|
||||
const { state, saveCreds } = await useMultiFileAuthState(
|
||||
'baileys_auth_whatsapp'
|
||||
)
|
||||
/**
|
||||
* Iniciar todo Bailey
|
||||
*/
|
||||
async initBailey() {
|
||||
const { state, saveCreds } = await useMultiFileAuthState('sessions')
|
||||
|
||||
this.sock = await makeWASocket({
|
||||
printQRInTerminal: true,
|
||||
auth: state,
|
||||
logger: PINO({ level: 'error' }),
|
||||
})
|
||||
try {
|
||||
this.vendor = makeWASocket({
|
||||
printQRInTerminal: false,
|
||||
auth: state,
|
||||
logger: pino({ level: 'error' }),
|
||||
})
|
||||
|
||||
this.vendor.ev.on(
|
||||
'connection.update',
|
||||
async ({ qr, connection, lastDisconnect }) => {
|
||||
if (qr) baileyGenerateImage(qr)
|
||||
if (connection === 'open') this.emit('ready', true)
|
||||
if (lastDisconnect?.error) {
|
||||
saveCreds()
|
||||
this.initBailey()
|
||||
}
|
||||
}
|
||||
)
|
||||
} catch (e) {
|
||||
this.emit('error', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapeamos los eventos nativos a los que la clase Provider espera
|
||||
* para tener un standar de eventos
|
||||
* @returns
|
||||
*/
|
||||
busEvents = () => [
|
||||
{
|
||||
event: 'connection.update',
|
||||
func: async ({ qr, connection, lastDisconnect }) => {
|
||||
if (qr) {
|
||||
this.emit('require_action', {
|
||||
instructions: [
|
||||
`Debes escanear el QR Code para iniciar session reivsa qr.png`,
|
||||
`Recuerda que el QR se actualiza cada minuto `,
|
||||
`Necesitas ayuda: https://link.codigoencasa.com/DISCORD`,
|
||||
],
|
||||
})
|
||||
baileyGenerateImage(qr)
|
||||
}
|
||||
|
||||
this.sock.ev.on(
|
||||
'connection.update',
|
||||
({ connection, lastDisconnect }) => {
|
||||
if (lastDisconnect?.error) {
|
||||
saveCreds()
|
||||
|
||||
this.baileys()
|
||||
this.emit('require_action', {
|
||||
instructions: [
|
||||
`Algo sucedio reinicia el bot o revisa tu whatsapp`,
|
||||
`Necesitas ayuda: https://link.codigoencasa.com/DISCORD`,
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
if (connection === 'open') {
|
||||
console.log('Baileys is connected')
|
||||
if (connection === 'open') this.emit('ready', true)
|
||||
},
|
||||
},
|
||||
{
|
||||
event: 'messages.upsert',
|
||||
func: ({ messages }) => {
|
||||
const [messageCtx] = messages
|
||||
let payload = {
|
||||
...messageCtx,
|
||||
body: messageCtx?.message?.conversation,
|
||||
from: messageCtx?.key?.remoteJid,
|
||||
}
|
||||
}
|
||||
)
|
||||
if (payload.from === 'status@broadcast') {
|
||||
return
|
||||
}
|
||||
|
||||
if (!baileyIsValidNumber(payload.from)) {
|
||||
return
|
||||
}
|
||||
payload.from = baileyCleanNumber(payload.from, true)
|
||||
this.emit('message', payload)
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
initBusEvents = () => {
|
||||
const listEvents = this.busEvents()
|
||||
|
||||
for (const { event, func } of listEvents) {
|
||||
this.vendor.ev.on(event, func)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @alpha
|
||||
* @param {string} number
|
||||
* @param {string} message
|
||||
* @example await sendMessage('+51925465621', 'Hello World')
|
||||
*/
|
||||
async sendMessage(number, message) {
|
||||
const numberClean = number.replace('+', '')
|
||||
await this.sock.sendMessage(`${numberClean}@c.us`, { text: message })
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} number
|
||||
* @param {string} message
|
||||
* @example await sendMessage('+51925465621', 'https://dominio.com/imagen.jpg' | 'img/imagen.jpg')
|
||||
* @example await sendMessage('+XXXXXXXXXXX', 'https://dominio.com/imagen.jpg' | 'img/imagen.jpg')
|
||||
*/
|
||||
|
||||
async sendImage(number, imageUrl) {
|
||||
const numberClean = number.replace('+', '')
|
||||
await this.sock.sendMessage(`${numberClean}@c.us`, {
|
||||
sendMedia = async (number, imageUrl) => {
|
||||
await this.vendor.sendMessage(number, {
|
||||
image: { url: imageUrl },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @alpha
|
||||
* @param {string} number
|
||||
* @param {string} message
|
||||
* @param {boolean} voiceNote optional
|
||||
* @example await sendMessage('+51925465621', 'audio.mp3')
|
||||
* @example await sendMessage('+XXXXXXXXXXX', 'audio.mp3')
|
||||
*/
|
||||
|
||||
async sendAudio(number, audioUrl, voiceNote = false) {
|
||||
sendAudio = async (number, audioUrl, voiceNote = false) => {
|
||||
const numberClean = number.replace('+', '')
|
||||
await this.sock.sendMessage(`${numberClean}@c.us`, {
|
||||
await this.vendor.sendMessage(`${numberClean}@c.us`, {
|
||||
audio: { url: audioUrl },
|
||||
ptt: voiceNote,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} number
|
||||
* @param {string} message
|
||||
* @returns
|
||||
*/
|
||||
sendText = async (number, message) => {
|
||||
return this.vendor.sendMessage(number, { text: message })
|
||||
}
|
||||
/**
|
||||
* TODO: Necesita terminar de implementar el sendMedia y sendButton guiarse:
|
||||
* https://github.com/leifermendez/bot-whatsapp/blob/4e0fcbd8347f8a430adb43351b5415098a5d10df/packages/provider/src/web-whatsapp/index.js#L165
|
||||
* @param {string} number
|
||||
* @param {string} message
|
||||
* @example await sendMessage('+XXXXXXXXXXX', 'Hello World')
|
||||
*/
|
||||
sendMessage = async (numberIn, message, { options }) => {
|
||||
const number = baileyCleanNumber(numberIn)
|
||||
|
||||
// if (options?.buttons?.length)
|
||||
// return this.sendButtons(number, message, options.buttons)
|
||||
if (options?.media) return this.sendMedia(number, options.media)
|
||||
return this.sendText(number, message)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BaileysProvider
|
||||
|
||||
21
packages/provider/src/baileys/utils.js
Normal file
21
packages/provider/src/baileys/utils.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const { createWriteStream } = require('fs')
|
||||
const qr = require('qr-image')
|
||||
|
||||
const baileyCleanNumber = (number, full = false) => {
|
||||
number = number.replace('@s.whatsapp.net', '')
|
||||
number = !full ? `${number}@s.whatsapp.net` : `${number}`
|
||||
return number
|
||||
}
|
||||
|
||||
const baileyGenerateImage = (base64) => {
|
||||
let qr_svg = qr.image(base64, { type: 'png', margin: 4 })
|
||||
qr_svg.pipe(createWriteStream(`${process.cwd()}/qr.png`))
|
||||
}
|
||||
|
||||
const baileyIsValidNumber = (rawNumber) => {
|
||||
const regexGroup = /\@g.us\b/gm
|
||||
const exist = rawNumber.match(regexGroup)
|
||||
return !exist
|
||||
}
|
||||
|
||||
module.exports = { baileyCleanNumber, baileyGenerateImage, baileyIsValidNumber }
|
||||
@@ -4,7 +4,7 @@ const {
|
||||
venomCleanNumber,
|
||||
venomGenerateImage,
|
||||
venomisValidNumber,
|
||||
} = require('./utils/utils')
|
||||
} = require('./utils')
|
||||
|
||||
/**
|
||||
* ⚙️ VenomProvider: Es una clase tipo adaptor
|
||||
@@ -13,7 +13,6 @@ const {
|
||||
*/
|
||||
class VenomProvider extends ProviderClass {
|
||||
vendor
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.init().then(() => this.initBusEvents())
|
||||
|
||||
@@ -3,10 +3,10 @@ const { ProviderClass } = require('@bot-whatsapp/bot')
|
||||
const { Console } = require('console')
|
||||
const { createWriteStream } = require('fs')
|
||||
const {
|
||||
cleanNumber,
|
||||
generateImage,
|
||||
isValidNumber,
|
||||
downloadMedia,
|
||||
wwebCleanNumber,
|
||||
wwebDownloadMedia,
|
||||
wwebGenerateImage,
|
||||
wwebIsValidNumber,
|
||||
} = require('./utils')
|
||||
|
||||
const logger = new Console({
|
||||
@@ -65,7 +65,7 @@ class WebWhatsappProvider extends ProviderClass {
|
||||
`Necesitas ayuda: https://link.codigoencasa.com/DISCORD`,
|
||||
],
|
||||
})
|
||||
generateImage(qr)
|
||||
wwebGenerateImage(qr)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -79,10 +79,10 @@ class WebWhatsappProvider extends ProviderClass {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isValidNumber(payload.from)) {
|
||||
if (!wwebIsValidNumber(payload.from)) {
|
||||
return
|
||||
}
|
||||
payload.from = cleanNumber(payload.from, true)
|
||||
payload.from = wwebCleanNumber(payload.from, true)
|
||||
this.emit('message', payload)
|
||||
},
|
||||
},
|
||||
@@ -98,7 +98,7 @@ class WebWhatsappProvider extends ProviderClass {
|
||||
*/
|
||||
sendMedia = async (number, mediaInput = null) => {
|
||||
if (!mediaInput) throw new Error(`NO_SE_ENCONTRO: ${mediaInput}`)
|
||||
const fileDownloaded = await downloadMedia(mediaInput)
|
||||
const fileDownloaded = await wwebDownloadMedia(mediaInput)
|
||||
const media = MessageMedia.fromFilePath(fileDownloaded)
|
||||
return this.vendor.sendMessage(number, media, {
|
||||
sendAudioAsVoice: true,
|
||||
@@ -163,7 +163,7 @@ class WebWhatsappProvider extends ProviderClass {
|
||||
* @returns
|
||||
*/
|
||||
sendMessage = async (userId, message, { options }) => {
|
||||
const number = cleanNumber(userId)
|
||||
const number = wwebCleanNumber(userId)
|
||||
if (options?.buttons?.length)
|
||||
return this.sendButtons(number, message, options.buttons)
|
||||
if (options?.media) return this.sendMedia(number, options.media)
|
||||
|
||||
@@ -4,18 +4,18 @@ const { tmpdir } = require('os')
|
||||
const http = require('http')
|
||||
const https = require('https')
|
||||
|
||||
const cleanNumber = (number, full = false) => {
|
||||
const wwebCleanNumber = (number, full = false) => {
|
||||
number = number.replace('@c.us', '')
|
||||
number = !full ? `${number}@c.us` : `${number}`
|
||||
return number
|
||||
}
|
||||
|
||||
const generateImage = (base64) => {
|
||||
const wwebGenerateImage = (base64) => {
|
||||
let qr_svg = qr.image(base64, { type: 'png', margin: 4 })
|
||||
qr_svg.pipe(createWriteStream(`${process.cwd()}/qr.svg`))
|
||||
qr_svg.pipe(createWriteStream(`${process.cwd()}/qr.png`))
|
||||
}
|
||||
|
||||
const isValidNumber = (rawNumber) => {
|
||||
const wwebIsValidNumber = (rawNumber) => {
|
||||
const regexGroup = /\@g.us\b/gm
|
||||
const exist = rawNumber.match(regexGroup)
|
||||
return !exist
|
||||
@@ -27,7 +27,7 @@ const isValidNumber = (rawNumber) => {
|
||||
* @param {*} url
|
||||
* @returns
|
||||
*/
|
||||
const downloadMedia = (url) => {
|
||||
const wwebDownloadMedia = (url) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const ext = url.split('.').pop()
|
||||
const checkProtocol = url.includes('https:')
|
||||
@@ -50,4 +50,9 @@ const downloadMedia = (url) => {
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { cleanNumber, generateImage, isValidNumber, downloadMedia }
|
||||
module.exports = {
|
||||
wwebCleanNumber,
|
||||
wwebGenerateImage,
|
||||
wwebIsValidNumber,
|
||||
wwebDownloadMedia,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user