mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-20 20:49:15 +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')
|
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 }
|
* { accountSid, authToken, vendorNumber }
|
||||||
*/
|
*/
|
||||||
class TwilioProvider extends ProviderClass {
|
class TwilioProvider extends ProviderClass {
|
||||||
@@ -15,7 +21,7 @@ class TwilioProvider extends ProviderClass {
|
|||||||
super()
|
super()
|
||||||
this.vendor = new twilio(accountSid, authToken)
|
this.vendor = new twilio(accountSid, authToken)
|
||||||
this.twilioHook = new TwilioWebHookServer(_port)
|
this.twilioHook = new TwilioWebHookServer(_port)
|
||||||
this.vendorNumber = vendorNumber
|
this.vendorNumber = parseNumber(vendorNumber)
|
||||||
|
|
||||||
this.twilioHook.start()
|
this.twilioHook.start()
|
||||||
const listEvents = this.busEvents()
|
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
|
* Mapeamos los eventos nativos de whatsapp-web.js a los que la clase Provider espera
|
||||||
* para tener un standar de eventos
|
* 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
|
module.exports = TwilioProvider
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class TwilioWebHookServer extends EventEmitter {
|
|||||||
twilioServer
|
twilioServer
|
||||||
twilioPort
|
twilioPort
|
||||||
constructor(_twilioPort) {
|
constructor(_twilioPort) {
|
||||||
|
super()
|
||||||
this.twilioServer = this.buildHTTPServer()
|
this.twilioServer = this.buildHTTPServer()
|
||||||
this.twilioPort = _twilioPort
|
this.twilioPort = _twilioPort
|
||||||
}
|
}
|
||||||
@@ -51,7 +52,7 @@ class TwilioWebHookServer extends EventEmitter {
|
|||||||
console.log(``)
|
console.log(``)
|
||||||
console.log(`[Twilio]: Agregar esta url "WHEN A MESSAGE COMES IN"`)
|
console.log(`[Twilio]: Agregar esta url "WHEN A MESSAGE COMES IN"`)
|
||||||
console.log(
|
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(`[Twilio]: Más información en la documentacion`)
|
||||||
console.log(``)
|
console.log(``)
|
||||||
|
|||||||
@@ -8,14 +8,19 @@ const {
|
|||||||
const { ProviderClass } = require('@bot-whatsapp/bot')
|
const { ProviderClass } = require('@bot-whatsapp/bot')
|
||||||
const { Console } = require('console')
|
const { Console } = require('console')
|
||||||
const { createWriteStream, existsSync } = require('fs')
|
const { createWriteStream, existsSync } = require('fs')
|
||||||
const { cleanNumber, generateImage, isValidNumber } = require('./utils')
|
const {
|
||||||
|
cleanNumber,
|
||||||
|
generateImage,
|
||||||
|
isValidNumber,
|
||||||
|
downloadMedia,
|
||||||
|
} = require('./utils')
|
||||||
|
|
||||||
const logger = new Console({
|
const logger = new Console({
|
||||||
stdout: createWriteStream('./log'),
|
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)
|
* que extiende clases de ProviderClass (la cual es como interfaz para sber que funciones rqueridas)
|
||||||
* https://github.com/pedroslopez/whatsapp-web.js
|
* https://github.com/pedroslopez/whatsapp-web.js
|
||||||
*/
|
*/
|
||||||
@@ -97,9 +102,9 @@ class WebWhatsappProvider extends ProviderClass {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
sendMedia = async (number, mediaInput = null) => {
|
sendMedia = async (number, mediaInput = null) => {
|
||||||
if (!existsSync(mediaInput))
|
if (!mediaInput) throw new Error(`NO_SE_ENCONTRO: ${mediaInput}`)
|
||||||
throw new Error(`NO_SE_ENCONTRO: ${mediaInput}`)
|
const fileDownloaded = await downloadMedia(mediaInput)
|
||||||
const media = MessageMedia.fromFilePath(mediaInput)
|
const media = MessageMedia.fromFilePath(fileDownloaded)
|
||||||
return this.vendor.sendMessage(number, media, {
|
return this.vendor.sendMessage(number, media, {
|
||||||
sendAudioAsVoice: true,
|
sendAudioAsVoice: true,
|
||||||
})
|
})
|
||||||
@@ -164,9 +169,9 @@ class WebWhatsappProvider extends ProviderClass {
|
|||||||
*/
|
*/
|
||||||
sendMessage = async (userId, message, { options }) => {
|
sendMessage = async (userId, message, { options }) => {
|
||||||
const number = cleanNumber(userId)
|
const number = cleanNumber(userId)
|
||||||
if (options?.media) return this.sendMedia(number, options.media)
|
|
||||||
if (options?.buttons?.length)
|
if (options?.buttons?.length)
|
||||||
return this.sendButtons(number, message, options.buttons)
|
return this.sendButtons(number, message, options.buttons)
|
||||||
|
if (options?.media) return this.sendMedia(number, options.media)
|
||||||
return this.sendText(number, message)
|
return this.sendText(number, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
const { createWriteStream } = require('fs')
|
const { createWriteStream } = require('fs')
|
||||||
const qr = require('qr-image')
|
const qr = require('qr-image')
|
||||||
|
const { tmpdir } = require('os')
|
||||||
|
const http = require('http')
|
||||||
|
const https = require('https')
|
||||||
|
|
||||||
const cleanNumber = (number, full = false) => {
|
const cleanNumber = (number, full = false) => {
|
||||||
number = number.replace('@c.us', '')
|
number = number.replace('@c.us', '')
|
||||||
@@ -18,4 +21,33 @@ const isValidNumber = (rawNumber) => {
|
|||||||
return !exist
|
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