mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-17 19:26:23 +00:00
fix(bot): ⚡ flow improvement + add utils
This commit is contained in:
@@ -5,6 +5,12 @@ const TwilioWebHookServer = require('./server')
|
||||
const { parseNumber } = require('./utils')
|
||||
|
||||
/**
|
||||
* ⚙️TwilioProvider: Es un provedor que te ofrece enviar
|
||||
* mensaje a Whatsapp via API
|
||||
* info: https://www.twilio.com/es-mx/messaging/whatsapp
|
||||
* video: https://youtu.be/KoOmsHylxUw
|
||||
*
|
||||
* Necesitas las siguientes tokens y valores
|
||||
* { accountSid, authToken, vendorNumber }
|
||||
*/
|
||||
class TwilioProvider extends ProviderClass {
|
||||
@@ -15,7 +21,7 @@ class TwilioProvider extends ProviderClass {
|
||||
super()
|
||||
this.vendor = new twilio(accountSid, authToken)
|
||||
this.twilioHook = new TwilioWebHookServer(_port)
|
||||
this.vendorNumber = vendorNumber
|
||||
this.vendorNumber = parseNumber(vendorNumber)
|
||||
|
||||
this.twilioHook.start()
|
||||
const listEvents = this.busEvents()
|
||||
@@ -25,14 +31,6 @@ class TwilioProvider extends ProviderClass {
|
||||
}
|
||||
}
|
||||
|
||||
sendMessage = async (number, message) => {
|
||||
return this.vendor.messages.create({
|
||||
body: message,
|
||||
from: ['whatsapp:+', parseNumber(this.vendorNumber)].join(''),
|
||||
to: ['whatsapp:+', parseNumber(number)].join(''),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapeamos los eventos nativos de whatsapp-web.js a los que la clase Provider espera
|
||||
* para tener un standar de eventos
|
||||
@@ -54,6 +52,65 @@ class TwilioProvider extends ProviderClass {
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
/**
|
||||
* Enviar un archivo multimedia
|
||||
* https://www.twilio.com/es-mx/docs/whatsapp/tutorial/send-and-receive-media-messages-whatsapp-nodejs
|
||||
* @private
|
||||
* @param {*} number
|
||||
* @param {*} mediaInput
|
||||
* @returns
|
||||
*/
|
||||
sendMedia = async (number, message, mediaInput = null) => {
|
||||
if (!mediaInput) throw new Error(`MEDIA_INPUT_NULL_: ${mediaInput}`)
|
||||
number = parseNumber(number)
|
||||
return this.vendor.messages.create({
|
||||
mediaUrl: [`${mediaInput}`],
|
||||
body: message,
|
||||
from: `whatsapp:+${this.vendorNumber}`,
|
||||
to: `whatsapp:+${number}`,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar botones
|
||||
* https://www.twilio.com/es-mx/docs/whatsapp/buttons
|
||||
* @private
|
||||
* @param {*} number
|
||||
* @param {*} message
|
||||
* @param {*} buttons []
|
||||
* @returns
|
||||
*/
|
||||
sendButtons = async (number, message, buttons = []) => {
|
||||
console.log(``)
|
||||
console.log(
|
||||
`[NOTA]: Actualmente enviar botons con Twilio esta en desarrollo`
|
||||
)
|
||||
console.log(
|
||||
`[NOTA]: https://www.twilio.com/es-mx/docs/whatsapp/buttons`
|
||||
)
|
||||
console.log(``)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} userId
|
||||
* @param {*} message
|
||||
* @param {*} param2
|
||||
* @returns
|
||||
*/
|
||||
sendMessage = async (number, message, { options }) => {
|
||||
number = parseNumber(number)
|
||||
if (options?.buttons?.length)
|
||||
this.sendButtons(number, message, options.buttons)
|
||||
if (options?.media)
|
||||
return this.sendMedia(number, message, options.media)
|
||||
return this.vendor.messages.create({
|
||||
body: message,
|
||||
from: `whatsapp:+${this.vendorNumber}`,
|
||||
to: `whatsapp:+${number}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TwilioProvider
|
||||
|
||||
@@ -11,6 +11,7 @@ class TwilioWebHookServer extends EventEmitter {
|
||||
twilioServer
|
||||
twilioPort
|
||||
constructor(_twilioPort) {
|
||||
super()
|
||||
this.twilioServer = this.buildHTTPServer()
|
||||
this.twilioPort = _twilioPort
|
||||
}
|
||||
@@ -51,7 +52,7 @@ class TwilioWebHookServer extends EventEmitter {
|
||||
console.log(``)
|
||||
console.log(`[Twilio]: Agregar esta url "WHEN A MESSAGE COMES IN"`)
|
||||
console.log(
|
||||
`[Twilio]: http://localhost:${this.twilioPort}/twilio-hook`
|
||||
`[Twilio]: POST http://localhost:${this.twilioPort}/twilio-hook`
|
||||
)
|
||||
console.log(`[Twilio]: Más información en la documentacion`)
|
||||
console.log(``)
|
||||
|
||||
@@ -8,14 +8,19 @@ const {
|
||||
const { ProviderClass } = require('@bot-whatsapp/bot')
|
||||
const { Console } = require('console')
|
||||
const { createWriteStream, existsSync } = require('fs')
|
||||
const { cleanNumber, generateImage, isValidNumber } = require('./utils')
|
||||
const {
|
||||
cleanNumber,
|
||||
generateImage,
|
||||
isValidNumber,
|
||||
downloadMedia,
|
||||
} = require('./utils')
|
||||
|
||||
const logger = new Console({
|
||||
stdout: createWriteStream('./log'),
|
||||
})
|
||||
|
||||
/**
|
||||
* WebWhatsappProvider: Es una clase tipo adaptor
|
||||
* ⚙️ WebWhatsappProvider: Es una clase tipo adaptor
|
||||
* que extiende clases de ProviderClass (la cual es como interfaz para sber que funciones rqueridas)
|
||||
* https://github.com/pedroslopez/whatsapp-web.js
|
||||
*/
|
||||
@@ -97,9 +102,9 @@ class WebWhatsappProvider extends ProviderClass {
|
||||
* @returns
|
||||
*/
|
||||
sendMedia = async (number, mediaInput = null) => {
|
||||
if (!existsSync(mediaInput))
|
||||
throw new Error(`NO_SE_ENCONTRO: ${mediaInput}`)
|
||||
const media = MessageMedia.fromFilePath(mediaInput)
|
||||
if (!mediaInput) throw new Error(`NO_SE_ENCONTRO: ${mediaInput}`)
|
||||
const fileDownloaded = await downloadMedia(mediaInput)
|
||||
const media = MessageMedia.fromFilePath(fileDownloaded)
|
||||
return this.vendor.sendMessage(number, media, {
|
||||
sendAudioAsVoice: true,
|
||||
})
|
||||
@@ -164,9 +169,9 @@ class WebWhatsappProvider extends ProviderClass {
|
||||
*/
|
||||
sendMessage = async (userId, message, { options }) => {
|
||||
const number = cleanNumber(userId)
|
||||
if (options?.media) return this.sendMedia(number, options.media)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
const { createWriteStream } = require('fs')
|
||||
const qr = require('qr-image')
|
||||
const { tmpdir } = require('os')
|
||||
const http = require('http')
|
||||
const https = require('https')
|
||||
|
||||
const cleanNumber = (number, full = false) => {
|
||||
number = number.replace('@c.us', '')
|
||||
@@ -18,4 +21,33 @@ const isValidNumber = (rawNumber) => {
|
||||
return !exist
|
||||
}
|
||||
|
||||
module.exports = { cleanNumber, generateImage, isValidNumber }
|
||||
/**
|
||||
* Incompleta
|
||||
* Descargar archivo multimedia para enviar
|
||||
* @param {*} url
|
||||
* @returns
|
||||
*/
|
||||
const downloadMedia = (url) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const ext = url.split('.').pop()
|
||||
const checkProtocol = url.includes('https:')
|
||||
const handleHttp = checkProtocol ? https : http
|
||||
const name = `tmp-${Date.now()}.${ext}`
|
||||
const fullPath = `${tmpdir()}/${name}`
|
||||
const file = createWriteStream(fullPath)
|
||||
handleHttp.get(url, function (response) {
|
||||
response.pipe(file)
|
||||
file.on('finish', function () {
|
||||
file.close()
|
||||
resolve(fullPath)
|
||||
})
|
||||
file.on('error', function () {
|
||||
console.log('errro')
|
||||
file.close()
|
||||
reject(null)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { cleanNumber, generateImage, isValidNumber, downloadMedia }
|
||||
|
||||
Reference in New Issue
Block a user