Merge pull request #215 from codigoencasa/dev

merge-full
This commit is contained in:
Leifer Mendez
2022-12-15 14:12:41 +01:00
committed by GitHub
17 changed files with 368 additions and 9 deletions

View File

@@ -7,6 +7,7 @@
"provider",
"adapter",
"ci",
"starters"
"starters",
"conflict"
]
}

View File

@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/bot",
"version": "0.0.21-alpha.0",
"version": "0.0.22-alpha.0",
"description": "",
"main": "./lib/bundle.bot.cjs",
"scripts": {

View File

@@ -33,10 +33,10 @@ const startInteractive = async () => {
message: '¿Cuál proveedor de whatsapp quieres utilizar?',
choices: [
{ title: 'whatsapp-web.js (gratis)', value: 'wweb' },
{ title: 'Twilio', value: 'twilio' },
{ title: 'Venom (gratis)', value: 'venom' },
{ title: 'Baileys (gratis)', value: 'bailey' },
{ title: 'API Oficial (Meta)', value: 'meta', disabled: true },
{ title: 'Twilio', value: 'twilio' },
{ title: 'API Oficial (Meta)', value: 'meta' },
],
max: 1,
hint: 'Espacio para seleccionar',

View File

@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/cli",
"version": "0.0.28-alpha.0",
"version": "0.0.29-alpha.0",
"description": "",
"main": "index.js",
"devDependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "create-bot-whatsapp",
"version": "0.0.39-alpha.0",
"version": "0.0.40-alpha.0",
"description": "",
"main": "./lib/bundle.create-bot-whatsapp.cjs",
"files": [

View File

@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/database",
"version": "0.0.20-alpha.0",
"version": "0.0.21-alpha.0",
"description": "Esto es el conector a mysql, pg, mongo",
"main": "./lib/mock/index.cjs",
"keywords": [],

View File

@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/provider",
"version": "0.0.26-alpha.0",
"version": "0.0.27-alpha.0",
"description": "Esto es el conector a Twilio, Meta, etc...",
"main": "./lib/mock/index.cjs",
"keywords": [],
@@ -18,6 +18,7 @@
"./twilio": "./lib/twilio/index.cjs",
"./web-whatsapp": "./lib/web-whatsapp/index.cjs",
"./venom": "./lib/venom/index.cjs",
"./baileys": "./lib/baileys/index.cjs"
"./baileys": "./lib/baileys/index.cjs",
"./meta": "./lib/meta/index.cjs"
}
}

View File

@@ -48,4 +48,13 @@ module.exports = [
},
plugins: [commonjs()],
},
{
input: join(__dirname, 'src', 'meta', 'index.js'),
output: {
banner: banner['banner.output'].join(''),
file: join(__dirname, 'lib', 'meta', 'index.cjs'),
format: 'cjs',
},
plugins: [commonjs()],
},
]

View File

@@ -1,5 +1,7 @@
const { ProviderClass } = require('@bot-whatsapp/bot')
const pino = require('pino')
const mime = require('mime-types')
const fs = require('fs')
const {
default: makeWASocket,
useMultiFileAuthState,
@@ -166,6 +168,49 @@ class BaileysProvider extends ProviderClass {
if (options?.media) return this.sendMedia(number, options.media)
return this.sendText(number, message)
}
/**
*
* @param {string} number
* @param {string} filePath
* @example await sendMessage('+XXXXXXXXXXX', './document/file.pdf')
*/
sendFile = async (number, filePath) => {
if (fs.existsSync(filePath)) {
const mimeType = mime.lookup(filePath)
const numberClean = number.replace('+', '')
const fileName = filePath.split('/').pop()
await this.vendor.sendMessage(`${numberClean}@c.us`, {
document: { url: filePath },
mimetype: mimeType,
fileName: fileName,
})
}
}
/**
*
* @param {string} number
* @param {string} text
* @param {string} footer
* @param {Array} buttons
* @example await sendMessage("+XXXXXXXXXXX", "Your Text", "Your Footer", [{"buttonId": "id", "buttonText": {"displayText": "Button"}, "type": 1}])
*/
sendButtons = async (number, text, footer, buttons) => {
const numberClean = number.replace('+', '')
const buttonMessage = {
text: text,
footer: footer,
buttons: buttons,
headerType: 1,
}
await this.vendor.sendMessage(`${numberClean}@c.us`, buttonMessage)
}
}
module.exports = BaileysProvider

View File

@@ -0,0 +1,115 @@
const { ProviderClass } = require('@bot-whatsapp/bot')
const axios = require('axios')
const MetaWebHookServer = require('./server')
const URL = `https://graph.facebook.com/v15.0`
/**
* ⚙MetaProvider: Es un provedor que te ofrece enviar
* mensaje a Whatsapp via API
* info: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages
*
*
* Necesitas las siguientes tokens y valores
* { token, numberId, vendorNumber, verify_token }
*/
class MetaProvider extends ProviderClass {
metHook
token
numberId
constructor({ token, numberId, verifyToken }, _port = 3000) {
super()
this.token = token
this.numberId = numberId
this.metHook = new MetaWebHookServer(verifyToken, _port)
this.metHook.start()
const listEvents = this.busEvents()
for (const { event, func } of listEvents) {
this.metHook.on(event, func)
}
}
/**
* Mapeamos los eventos nativos a los que la clase Provider espera
* para tener un standar de eventos
* @returns
*/
busEvents = () => [
{
event: 'auth_failure',
func: (payload) => this.emit('error', payload),
},
{
event: 'ready',
func: () => this.emit('ready', true),
},
{
event: 'message',
func: (payload) => {
this.emit('message', payload)
},
},
]
sendMessageMeta = async (body) => {
try {
const response = await axios.post(
`${URL}/${this.numberId}/messages`,
body,
{
headers: {
Authorization: `Bearer ${this.token}`,
},
}
)
return response.data
} catch (error) {
return Promise.resolve(error)
}
}
sendtext = async (number, message) => {
const body = {
messaging_product: 'whatsapp',
to: number,
type: 'text',
text: {
preview_url: false,
body: message,
},
}
await this.sendMessageMeta(body)
}
sendMedia = async (number, _, mediaInput = null) => {
if (!mediaInput) throw new Error(`MEDIA_INPUT_NULL_: ${mediaInput}`)
const body = {
messaging_product: 'whatsapp',
to: number,
type: 'image',
image: {
link: mediaInput,
},
}
await this.sendMessageMeta(body)
}
/**
*
* @param {*} userId
* @param {*} message
* @param {*} param2
* @returns
*/
sendMessage = async (number, message, { options }) => {
if (options?.buttons?.length) return console.log('Envio de botones')
if (options?.media)
return this.sendMedia(number, message, options.media)
this.sendtext(number, message)
}
}
module.exports = MetaProvider

View File

@@ -0,0 +1,63 @@
const { EventEmitter } = require('node:events')
const polka = require('polka')
const { urlencoded } = require('body-parser')
class MetaWebHookServer extends EventEmitter {
metaServer
metaPort
verifyToken
constructor(_verifyToken, _metaPort) {
super()
this.metaServer = this.buildHTTPServer()
this.metaPort = _metaPort
this.verifyToken = _verifyToken
}
/**
* Mensaje entrante
* emit: 'message'
* @param {*} req
* @param {*} res
*/
incomingMsg = (req, res) => {
const { body } = req
const message = body.entry[0].changes[0].value.messages[0]
const to = body.entry[0].changes[0].value.metadata.display_phone_number
this.emit('message', {
from: message.from,
to,
body: message.text.body,
})
const json = JSON.stringify({ body })
res.end(json)
}
/**
* Contruir HTTP Server
* @returns
*/
buildHTTPServer = () => {
return polka()
.use(urlencoded({ extended: true }))
.post('/meta-hook', this.incomingMsg)
}
/**
* Puerto del HTTP
* @param {*} port default 3000
*/
start = () => {
this.metaServer.listen(this.metaPort, () => {
console.log(``)
console.log(`[meta]: Agregar esta url "WHEN A MESSAGE COMES IN"`)
console.log(
`[meta]: POST http://localhost:${this.metaPort}/meta-hook`
)
console.log(`[meta]: Más información en la documentacion`)
console.log(``)
})
this.emit('ready')
}
}
module.exports = MetaWebHookServer

View File

@@ -10,6 +10,7 @@
"keywords": [],
"dependencies": {
"@adiwajshing/baileys": "^4.4.0",
"mime-types": "^2.1.35",
"@bot-whatsapp/bot": "latest",
"@bot-whatsapp/cli": "latest",
"@bot-whatsapp/database": "latest",

View File

@@ -10,6 +10,7 @@
"keywords": [],
"dependencies": {
"@adiwajshing/baileys": "^4.4.0",
"mime-types": "^2.1.35",
"@bot-whatsapp/bot": "latest",
"@bot-whatsapp/cli": "latest",
"@bot-whatsapp/database": "latest",

View File

@@ -10,6 +10,7 @@
"keywords": [],
"dependencies": {
"@adiwajshing/baileys": "^4.4.0",
"mime-types": "^2.1.35",
"@bot-whatsapp/bot": "latest",
"@bot-whatsapp/cli": "latest",
"@bot-whatsapp/database": "latest",

View File

@@ -0,0 +1,12 @@
### BASE APP
Este bot contiene un flujo basico en el cual una persona (cliente) escribe **"hola"** y el bot responde.
- Bienvenido a mi tienda
- Como puedo ayudarte?
- Tengo: Zapatos Bolsos etc..
------
- [Discord](https://link.codigoencasa.com/DISCORD)
- [Twitter](https://twitter.com/leifermendez)
- [Youtube](https://www.youtube.com/watch?v=5lEMCeWEJ8o&list=PL_WGMLcL4jzWPhdhcUyhbFU6bC0oJd2BR)
- [Telegram](https://t.me/leifermendez)

View File

@@ -0,0 +1,88 @@
const {
createBot,
createProvider,
createFlow,
addKeyword,
addChild,
} = require('@bot-whatsapp/bot')
const TwilioProvider = require('@bot-whatsapp/provider/twilio')
const MockAdapter = require('@bot-whatsapp/database/mock')
/**
* Declarando flujo hijo
*/
const flowBolsos2 = addKeyword(['bolsos2', '2'])
.addAnswer('🤯 *MUCHOS* bolsos ...')
.addAnswer('y mas bolsos... bla bla')
const flowZapatos2 = addKeyword(['zapatos2', '2'])
.addAnswer('🤯 repito que tengo *MUCHOS* zapatos.')
.addAnswer('y algunas otras cosas.')
const flowZapatos = addKeyword(['zapatos', 'ZAPATOS'])
.addAnswer('🤯 Veo que elegiste zapatos')
.addAnswer('Tengo muchos zapatos...bla bla')
.addAnswer(
['Manda:', '*2*', 'o', '*zapatos2*', 'para mas información'],
{ capture: true },
(ctx) => {
console.log('Aqui puedes ver más info del usuario...')
console.log('Puedes enviar un mail, hook, etc..')
console.log(ctx)
},
[...addChild(flowZapatos2)]
)
const flowBolsos = addKeyword(['bolsos', 'BOLSOS'])
.addAnswer('🙌 Veo que elegiste bolsos')
.addAnswer('Tengo muchos bolsos...bla bla')
.addAnswer(
['Manda:', '*2*', 'o', '*bolsos2*', 'para mas información.'],
{ capture: true },
(ctx) => {
console.log('Aqui puedes ver más info del usuario...')
console.log('Puedes enviar un mail, hook, etc..')
console.log(ctx)
},
[...addChild(flowBolsos2)]
)
/**
* Declarando flujo principal
*/
const flowPrincipal = addKeyword(['hola', 'ole', 'alo'])
.addAnswer('Hola, bienvenido a mi tienda')
.addAnswer('Como puedo ayudarte?')
.addAnswer(['Tengo:', 'Zapatos', 'Bolsos', 'etc..'])
.addAnswer(
['Para continuar escribe:', '*Zapatos*', 'o', '*Bolsos*'],
{ capture: true },
(ctx) => {
console.log('Aqui puedes ver más info del usuario...')
console.log('Puedes enviar un mail, hook, etc..')
console.log(ctx)
console.log(ctx['_data']['notifyName'])
},
[...addChild(flowBolsos), ...addChild(flowZapatos)]
)
const main = async () => {
const adapterDB = new MockAdapter()
const adapterFlow = createFlow([flowPrincipal])
const adapterProvider = createProvider(TwilioProvider, {
accountSid: 'YOUR_ACCOUNT_SID',
authToken: 'YOUR_ACCOUNT_TOKEN',
vendorNumber: '+14155238886',
})
createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
}
main()

View File

@@ -0,0 +1,22 @@
{
"name": "bot-whatsapp-base-meta-memory",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"pre-copy": "cd .. && yarn run copy.lib base-meta-memory",
"start": "node app.js"
},
"keywords": [],
"dependencies": {
"body-parser": "^1.20.1",
"polka": "^0.5.2",
"twilio": "^3.83.4",
"@bot-whatsapp/bot": "latest",
"@bot-whatsapp/cli": "latest",
"@bot-whatsapp/database": "latest",
"@bot-whatsapp/provider": "latest"
},
"author": "",
"license": "ISC"
}