fix(adapter): 🔥 improvement baileys

fix(adapter): 🔥 improvement baileys
This commit is contained in:
Leifer Mendez
2022-12-14 18:46:16 +01:00
committed by GitHub
8 changed files with 189 additions and 62 deletions

View File

@@ -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"
}
}

View File

@@ -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()],
},
]

View File

@@ -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

View 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 }

View File

@@ -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())

View File

@@ -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)

View File

@@ -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,
}