mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-21 21:19:17 +00:00
Merge pull request #139 from leifermendez/feature/fallback
Feature/fallback
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -2,7 +2,7 @@ name: Test / Coverage
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [feature/monorepo]
|
branches: [dev]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|
||||||
|
|||||||
22
.github/workflows/contributors.yml
vendored
Normal file
22
.github/workflows/contributors.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: Add contributors
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '20 20 * * *'
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
add-contributors:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: BobAnkh/add-contributors@master
|
||||||
|
with:
|
||||||
|
CONTRIBUTOR: '### Contributors'
|
||||||
|
COLUMN_PER_ROW: '6'
|
||||||
|
ACCESS_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
IMG_WIDTH: '100'
|
||||||
|
FONT_SIZE: '14'
|
||||||
|
PATH: '/README.md'
|
||||||
|
COMMIT_MESSAGE: 'docs(README): update contributors'
|
||||||
|
AVATAR_SHAPE: 'round'
|
||||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"conventionalCommits.scopes": ["hook", "contributing", "cli"]
|
"conventionalCommits.scopes": ["hook", "contributing", "cli", "bot"]
|
||||||
}
|
}
|
||||||
|
|||||||
2
GLOSSARY.md
Normal file
2
GLOSSARY.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
CTX: Es el objeto que representa un mensaje, con opciones, id, ref
|
||||||
|
messageInComming: Objeto entrante del provider {body, from,...}
|
||||||
28
TODO.md
28
TODO.md
@@ -4,14 +4,15 @@
|
|||||||
- [ ] __(doc)__ Video explicacion de github action
|
- [ ] __(doc)__ Video explicacion de github action
|
||||||
|
|
||||||
### @bot-whatsapp/bot
|
### @bot-whatsapp/bot
|
||||||
- [ ] agregar export package
|
- [X] agregar export package
|
||||||
- [X] Posibilidad de en el capture meter todo un nuevo CTX de FLOW .addAnswer('Marca la opcion',{capture:true, join:CTX})
|
- [X] Posibilidad de en el capture meter todo un nuevo CTX de FLOW .addAnswer('Marca la opcion',{capture:true, join:CTX})
|
||||||
- [X] .addKeyword('1') no funciona con 1 caracter
|
- [X] .addKeyword('1') no funciona con 1 caracter
|
||||||
- [X] sensitivy viene activado por defecto
|
- [X] sensitivy viene activado por defecto
|
||||||
- [ ] fallback respuesta en hijo: Se puede colocar en option el ref de la answer fallback
|
- [X] fallback respuesta en hijo: Se puede colocar en option el ref de la answer fallback
|
||||||
|
- [X] Cuando Envian Sticket devuelve mensaje raro
|
||||||
- [ ] colocar mensaje esperando conectando whatsapp (provider)
|
- [ ] colocar mensaje esperando conectando whatsapp (provider)
|
||||||
- [ ] Cuando Envian Sticket devuelve mensaje raro
|
|
||||||
- [ ] createDatabase validar implementacion de funciones
|
- [ ] createDatabase validar implementacion de funciones
|
||||||
|
- [ ] limitar caracteres de mensajes
|
||||||
|
|
||||||
### @bot-whatsapp/database
|
### @bot-whatsapp/database
|
||||||
- [X] agregar export package
|
- [X] agregar export package
|
||||||
@@ -23,10 +24,25 @@
|
|||||||
### @bot-whatsapp/provider
|
### @bot-whatsapp/provider
|
||||||
- [X] agregar export package
|
- [X] agregar export package
|
||||||
- [ ] __(doc):__ Video para explicar como implementar nuevos providers
|
- [ ] __(doc):__ Video para explicar como implementar nuevos providers
|
||||||
- [ ] WhatsappWeb provider enviar imagenes
|
- [X] WhatsappWeb provider enviar imagenes
|
||||||
- [ ] WhatsappWeb provider enviar audio
|
- [X] WhatsappWeb provider enviar audio
|
||||||
|
- [X] WhatsappWeb botones (Tiene truco) github:leifermendez/whatsapp-web.js
|
||||||
- [ ] Twilio adapter
|
- [ ] Twilio adapter
|
||||||
- [ ] Meta adapter
|
- [ ] Meta adapter
|
||||||
|
|
||||||
### @bot-whatsapp/cli
|
### @bot-whatsapp/cli
|
||||||
- [ ] Hacer comando para crear `example-app`
|
- [X] Hacer comando para crear `example-app`
|
||||||
|
|
||||||
|
|
||||||
|
### @bot-whatsapp/create-bot
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
### Starters
|
||||||
|
- [X] Base
|
||||||
|
- [X] Basico
|
||||||
|
- [ ] Enviando Imagen
|
||||||
|
- [ ] Enviando Botones
|
||||||
|
- [ ] Mezclando flujos hijos
|
||||||
|
|
||||||
|
### Extra
|
||||||
|
- [X] Crear CI mantener fork update https://stackoverflow.com/questions/23793062/can-forks-be-synced-automatically-in-github
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ class CoreClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manejador de eventos
|
||||||
|
*/
|
||||||
listenerBusEvents = () => [
|
listenerBusEvents = () => [
|
||||||
{
|
{
|
||||||
event: 'require_action',
|
event: 'require_action',
|
||||||
@@ -44,16 +47,18 @@ class CoreClass {
|
|||||||
]
|
]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
*
|
||||||
* @param {*} ctxMessage
|
* @param {*} messageInComming
|
||||||
|
* @returns
|
||||||
*/
|
*/
|
||||||
handleMsg = async (messageInComming) => {
|
handleMsg = async (messageInComming) => {
|
||||||
const { body, from } = messageInComming
|
const { body, from } = messageInComming
|
||||||
let msgToSend = []
|
let msgToSend = []
|
||||||
|
let fallBackFlag = false
|
||||||
|
|
||||||
|
if (!body.length) return
|
||||||
|
|
||||||
//Consultamos mensaje previo en DB
|
|
||||||
const prevMsg = await this.databaseClass.getPrevByNumber(from)
|
const prevMsg = await this.databaseClass.getPrevByNumber(from)
|
||||||
//Consultamos for refSerializada en el flow actual
|
|
||||||
const refToContinue = this.flowClass.findBySerialize(
|
const refToContinue = this.flowClass.findBySerialize(
|
||||||
prevMsg?.refSerialize
|
prevMsg?.refSerialize
|
||||||
)
|
)
|
||||||
@@ -67,14 +72,24 @@ class CoreClass {
|
|||||||
this.databaseClass.save(ctxByNumber)
|
this.databaseClass.save(ctxByNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Si se tiene un callback se ejecuta
|
// 📄 [options: fallback]: esta funcion se encarga de repetir el ultimo mensaje
|
||||||
if (refToContinue && prevMsg?.options?.callback) {
|
const fallBack = () => {
|
||||||
const indexFlow = this.flowClass.findIndexByRef(refToContinue?.ref)
|
fallBackFlag = true
|
||||||
this.flowClass.allCallbacks[indexFlow].callback(messageInComming)
|
msgToSend = this.flowClass.find(refToContinue?.keyword, true) || []
|
||||||
|
this.sendFlow(msgToSend, from)
|
||||||
|
return refToContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
//Si se tiene anidaciones de flows, si tienes anidados obligatoriamente capture:true
|
// 📄 [options: callback]: Si se tiene un callback se ejecuta
|
||||||
if (prevMsg?.options?.nested?.length) {
|
if (!fallBackFlag && refToContinue && prevMsg?.options?.callback) {
|
||||||
|
const indexFlow = this.flowClass.findIndexByRef(refToContinue?.ref)
|
||||||
|
this.flowClass.allCallbacks[indexFlow].callback(messageInComming, {
|
||||||
|
fallBack,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 📄🤘(tiene return) [options: nested(array)]: Si se tiene flujos hijos los implementa
|
||||||
|
if (!fallBackFlag && prevMsg?.options?.nested?.length) {
|
||||||
const nestedRef = prevMsg.options.nested
|
const nestedRef = prevMsg.options.nested
|
||||||
const flowStandalone = nestedRef.map((f) => ({
|
const flowStandalone = nestedRef.map((f) => ({
|
||||||
...nestedRef.find((r) => r.refSerialize === f.refSerialize),
|
...nestedRef.find((r) => r.refSerialize === f.refSerialize),
|
||||||
@@ -85,20 +100,32 @@ class CoreClass {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Consultamos si se espera respuesta por parte de cliente "Ejemplo: Dime tu nombre"
|
// 📄🤘(tiene return) [options: capture (boolean)]: Si se tiene option boolean
|
||||||
if (!prevMsg?.options?.nested?.length && prevMsg?.options?.capture) {
|
if (!fallBackFlag && !prevMsg?.options?.nested?.length) {
|
||||||
|
const typeCapture = typeof prevMsg?.options?.capture
|
||||||
|
const valueCapture = prevMsg?.options?.capture
|
||||||
|
|
||||||
|
if (['string', 'boolean'].includes(typeCapture) && valueCapture) {
|
||||||
msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
|
msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
|
||||||
} else {
|
this.sendFlow(msgToSend, from)
|
||||||
msgToSend = this.flowClass.find(body) || []
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msgToSend = this.flowClass.find(body) || []
|
||||||
this.sendFlow(msgToSend, from)
|
this.sendFlow(msgToSend, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enviar mensaje con contexto atraves del proveedor de whatsapp
|
||||||
|
* @param {*} numberOrId
|
||||||
|
* @param {*} ctxMessage ver más en GLOSSARY.md
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
sendProviderAndSave = (numberOrId, ctxMessage) => {
|
sendProviderAndSave = (numberOrId, ctxMessage) => {
|
||||||
const { answer } = ctxMessage
|
const { answer } = ctxMessage
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this.providerClass.sendMessage(numberOrId, answer),
|
this.providerClass.sendMessage(numberOrId, answer, ctxMessage),
|
||||||
this.databaseClass.save({ ...ctxMessage, from: numberOrId }),
|
this.databaseClass.save({ ...ctxMessage, from: numberOrId }),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
const { generateRef } = require('../../utils/hash')
|
const { generateRef } = require('../../utils/hash')
|
||||||
const { toJson } = require('./toJson')
|
const { toJson } = require('./toJson')
|
||||||
const { toSerialize } = require('./toSerialize')
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param answer string
|
* @param answer string
|
||||||
* @param options {media:string, buttons:[], capture:true default false}
|
* @param options {media:string, buttons:[{"body":"😎 Cursos"}], capture:true default false}
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const addAnswer =
|
const addAnswer =
|
||||||
@@ -79,6 +78,7 @@ const addAnswer =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retornar contexto no colocar nada más abajo de esto
|
||||||
const ctx = ctxAnswer()
|
const ctx = ctxAnswer()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ProviderClass extends EventEmitter {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sendMessage = async (userId, message) => {
|
sendMessage = async (userId, message, sendMessage) => {
|
||||||
if (NODE_ENV !== 'production')
|
if (NODE_ENV !== 'production')
|
||||||
console.log('[sendMessage]', { userId, message })
|
console.log('[sendMessage]', { userId, message })
|
||||||
return message
|
return message
|
||||||
|
|||||||
@@ -9,10 +9,12 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"mongodb": "^4.11.0"
|
"mongodb": "^4.11.0",
|
||||||
|
"mysql2": "^2.3.3"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
"./mock": "./lib/mock/index.cjs",
|
"./mock": "./lib/mock/index.cjs",
|
||||||
"./mongo": "./lib/mongo/index.cjs"
|
"./mongo": "./lib/mongo/index.cjs",
|
||||||
|
"./mysql": "./lib/mysql/index.cjs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,4 +21,13 @@ module.exports = [
|
|||||||
},
|
},
|
||||||
plugins: [commonjs()],
|
plugins: [commonjs()],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: join(__dirname, 'src', 'mysql', 'index.js'),
|
||||||
|
output: {
|
||||||
|
banner: banner['banner.output'].join(''),
|
||||||
|
file: join(__dirname, 'lib', 'mysql', 'index.cjs'),
|
||||||
|
format: 'cjs',
|
||||||
|
},
|
||||||
|
plugins: [commonjs()],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
76
packages/database/src/mysql/index.js
Normal file
76
packages/database/src/mysql/index.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
require('dotenv').config()
|
||||||
|
const mysql = require('mysql2')
|
||||||
|
|
||||||
|
const DB_NAME = process.env.DB_NAME || 'db_bot'
|
||||||
|
const DB_HOST = process.env.DB_HOST || 'localhost'
|
||||||
|
const DB_USER = process.env.DB_USER || 'root'
|
||||||
|
|
||||||
|
class MyslAdapter {
|
||||||
|
db
|
||||||
|
listHistory = []
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.init().then()
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
this.db = mysql.createConnection({
|
||||||
|
host: DB_HOST,
|
||||||
|
user: DB_USER,
|
||||||
|
database: DB_NAME,
|
||||||
|
})
|
||||||
|
|
||||||
|
await this.db.connect((error) => {
|
||||||
|
if (!error) {
|
||||||
|
console.log(`Solicitud de conexión a base de datos exitosa`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.log(`Solicitud de conexión fallida ${error.stack}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getPrevByNumber = (from) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
const sql = `SELECT * FROM history WHERE phone=${from} ORDER BY id DESC`
|
||||||
|
this.db.query(sql, (error, rows) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows.length) {
|
||||||
|
const [row] = rows
|
||||||
|
row.options = JSON.parse(row.options)
|
||||||
|
resolve(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rows.length) {
|
||||||
|
resolve(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
save = (ctx) => {
|
||||||
|
const values = [
|
||||||
|
[
|
||||||
|
ctx.ref,
|
||||||
|
ctx.keyword,
|
||||||
|
ctx.answer,
|
||||||
|
ctx.refSerialize,
|
||||||
|
ctx.from,
|
||||||
|
JSON.stringify(ctx.options),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
const sql =
|
||||||
|
'INSERT INTO history (ref, keyword, answer, refSerialize, phone, options ) values ?'
|
||||||
|
|
||||||
|
this.db.query(sql, [values], (err) => {
|
||||||
|
if (err) throw err
|
||||||
|
console.log('Guardado en DB...', values)
|
||||||
|
})
|
||||||
|
this.listHistory.push(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = MyslAdapter
|
||||||
@@ -29,10 +29,13 @@
|
|||||||
"@types/node": "latest",
|
"@types/node": "latest",
|
||||||
"@typescript-eslint/eslint-plugin": "5.43.0",
|
"@typescript-eslint/eslint-plugin": "5.43.0",
|
||||||
"@typescript-eslint/parser": "5.43.0",
|
"@typescript-eslint/parser": "5.43.0",
|
||||||
|
"autoprefixer": "10.4.11",
|
||||||
"eslint": "8.28.0",
|
"eslint": "8.28.0",
|
||||||
"eslint-plugin-qwik": "0.14.1",
|
"eslint-plugin-qwik": "0.14.1",
|
||||||
"node-fetch": "3.3.0",
|
"node-fetch": "3.3.0",
|
||||||
|
"postcss": "^8.4.16",
|
||||||
"prettier": "2.7.1",
|
"prettier": "2.7.1",
|
||||||
|
"tailwindcss": "^3.1.8",
|
||||||
"typescript": "4.9.3",
|
"typescript": "4.9.3",
|
||||||
"vite": "3.2.4",
|
"vite": "3.2.4",
|
||||||
"vite-tsconfig-paths": "3.5.0",
|
"vite-tsconfig-paths": "3.5.0",
|
||||||
|
|||||||
6
packages/docs/postcss.config.js
Normal file
6
packages/docs/postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
21
packages/docs/tailwind.config.js
Normal file
21
packages/docs/tailwind.config.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
|
||||||
|
const defaultTheme = require("tailwindcss/defaultTheme");
|
||||||
|
const colors = require("tailwindcss/colors");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
primary: colors.purple,
|
||||||
|
secondary: colors.sky,
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
sans: ["'Inter'", ...defaultTheme.fontFamily.sans],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
darkMode: "class",
|
||||||
|
};
|
||||||
@@ -1,13 +1,24 @@
|
|||||||
const { Client, LocalAuth } = require('whatsapp-web.js')
|
const {
|
||||||
|
Client,
|
||||||
|
LocalAuth,
|
||||||
|
MessageMedia,
|
||||||
|
Buttons,
|
||||||
|
List,
|
||||||
|
} = require('whatsapp-web.js')
|
||||||
const { ProviderClass } = require('@bot-whatsapp/bot')
|
const { ProviderClass } = require('@bot-whatsapp/bot')
|
||||||
const { Console } = require('console')
|
const { Console } = require('console')
|
||||||
const { createWriteStream } = require('fs')
|
const { createWriteStream, existsSync } = require('fs')
|
||||||
const { cleanNumber, generateImage, isValidNumber } = require('./utils')
|
const { cleanNumber, generateImage, isValidNumber } = require('./utils')
|
||||||
|
|
||||||
const logger = new Console({
|
const logger = new Console({
|
||||||
stdout: createWriteStream('./log'),
|
stdout: createWriteStream('./log'),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
class WebWhatsappProvider extends ProviderClass {
|
class WebWhatsappProvider extends ProviderClass {
|
||||||
vendor
|
vendor
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -26,8 +37,9 @@ class WebWhatsappProvider extends ProviderClass {
|
|||||||
logger.log(e)
|
logger.log(e)
|
||||||
this.emit('require_action', {
|
this.emit('require_action', {
|
||||||
instructions: [
|
instructions: [
|
||||||
`Debes eliminar la carpeta .wwebjs_auth`,
|
`(Opcion 1): Debes eliminar la carpeta .wwebjs_auth y reiniciar nuevamente el bot. `,
|
||||||
`y reiniciar nuevamente el bot `,
|
`(Opcion 2): Intenta actualizar el paquete [npm install whatsapp-web.js] `,
|
||||||
|
`(Opcion 3): Ir FORO de discord https://link.codigoencasa.com/DISCORD `,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -80,10 +92,87 @@ class WebWhatsappProvider extends ProviderClass {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
sendMessage = async (userId, message) => {
|
/**
|
||||||
const number = cleanNumber(userId)
|
* Enviar un archivo multimedia
|
||||||
|
* https://docs.wwebjs.dev/MessageMedia.html
|
||||||
|
* @private
|
||||||
|
* @param {*} number
|
||||||
|
* @param {*} mediaInput
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
sendMedia = async (number, mediaInput = null) => {
|
||||||
|
if (!existsSync(mediaInput))
|
||||||
|
throw new Error(`NO_SE_ENCONTRO: ${mediaInput}`)
|
||||||
|
const media = MessageMedia.fromFilePath(mediaInput)
|
||||||
|
return this.vendor.sendMessage(number, media, {
|
||||||
|
sendAudioAsVoice: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enviar botones
|
||||||
|
* https://docs.wwebjs.dev/Buttons.html
|
||||||
|
* @private
|
||||||
|
* @param {*} number
|
||||||
|
* @param {*} message
|
||||||
|
* @param {*} buttons []
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
sendButtons = async (number, message, buttons = []) => {
|
||||||
|
const buttonMessage = new Buttons(message, buttons, '', '')
|
||||||
|
return this.vendor.sendMessage(number, buttonMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enviar lista
|
||||||
|
* https://docs.wwebjs.dev/List.html
|
||||||
|
* @private
|
||||||
|
* @alpha No funciona en whatsapp bussines
|
||||||
|
* @param {*} number
|
||||||
|
* @param {*} message
|
||||||
|
* @param {*} buttons []
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
sendList = async (number, message, listInput = []) => {
|
||||||
|
let sections = [
|
||||||
|
{
|
||||||
|
title: 'sectionTitle',
|
||||||
|
rows: [
|
||||||
|
{ title: 'ListItem1', description: 'desc' },
|
||||||
|
{ title: 'ListItem2' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
let list = new List('List body', 'btnText', sections, 'Title', 'footer')
|
||||||
|
return this.vendor.sendMessage(number, list)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enviar un mensaje solo texto
|
||||||
|
* https://docs.wwebjs.dev/Message.html
|
||||||
|
* @private
|
||||||
|
* @param {*} number
|
||||||
|
* @param {*} message
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
sendText = async (number, message) => {
|
||||||
return this.vendor.sendMessage(number, message)
|
return this.vendor.sendMessage(number, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} userId
|
||||||
|
* @param {*} message
|
||||||
|
* @param {*} param2
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
return this.sendText(number, message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = WebWhatsappProvider
|
module.exports = WebWhatsappProvider
|
||||||
|
|||||||
@@ -5,11 +5,6 @@ const {
|
|||||||
addKeyword,
|
addKeyword,
|
||||||
} = require('@bot-whatsapp/bot')
|
} = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
/**
|
|
||||||
* ATENCION: Si vas a usar el provider whatsapp-web.js
|
|
||||||
* recuerda ejecutar npm i whatsapp-web.js@latest
|
|
||||||
*/
|
|
||||||
|
|
||||||
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
|
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
|
||||||
const MockAdapter = require('@bot-whatsapp/database/mock')
|
const MockAdapter = require('@bot-whatsapp/database/mock')
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,6 @@ const {
|
|||||||
addChild,
|
addChild,
|
||||||
} = require('@bot-whatsapp/bot')
|
} = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
/**
|
|
||||||
* ATENCION: Si vas a usar el provider whatsapp-web.js
|
|
||||||
* recuerda ejecutar npm i whatsapp-web.js@latest
|
|
||||||
*/
|
|
||||||
|
|
||||||
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
|
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
|
||||||
const MockAdapter = require('@bot-whatsapp/database/mock')
|
const MockAdapter = require('@bot-whatsapp/database/mock')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user