mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-19 12:09:15 +00:00
rename core to bot
This commit is contained in:
78
packages/bot/classes/bot.class.js
Normal file
78
packages/bot/classes/bot.class.js
Normal file
@@ -0,0 +1,78 @@
|
||||
const { printer } = require('../utils/interactive')
|
||||
|
||||
/**
|
||||
* [ ] Escuchar eventos del provider asegurarte que los provider emitan eventos
|
||||
* [ ] Guardar historial en db
|
||||
* [ ] Buscar mensaje en flow
|
||||
*
|
||||
*/
|
||||
class BotClass {
|
||||
flowClass
|
||||
databaseClass
|
||||
providerClass
|
||||
constructor(_flow, _database, _provider) {
|
||||
this.flowClass = _flow
|
||||
this.databaseClass = _database
|
||||
this.providerClass = _provider
|
||||
|
||||
for (const { event, func } of this.listenerBusEvents()) {
|
||||
this.providerClass.on(event, func)
|
||||
}
|
||||
}
|
||||
|
||||
listenerBusEvents = () => [
|
||||
{
|
||||
event: 'require_action',
|
||||
func: ({ instructions, title = '⚡⚡ ACCION REQUERIDA ⚡⚡' }) =>
|
||||
printer(instructions, title),
|
||||
},
|
||||
{
|
||||
event: 'ready',
|
||||
func: () => printer('Provider conectado y listo'),
|
||||
},
|
||||
{
|
||||
event: 'auth_failure',
|
||||
func: ({ instructions }) =>
|
||||
printer(instructions, '⚡⚡ ERROR AUTH ⚡⚡'),
|
||||
},
|
||||
|
||||
{
|
||||
event: 'message',
|
||||
func: (msg) => this.handleMsg(msg),
|
||||
},
|
||||
]
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {*} ctxMessage
|
||||
*/
|
||||
handleMsg = ({ body, to, from }) => {
|
||||
this.databaseClass.save(body)
|
||||
const messageToSend = this.flowClass.find(body) || []
|
||||
console.log(messageToSend)
|
||||
if (Array.isArray(messageToSend)) this.sendFlow(messageToSend, from)
|
||||
}
|
||||
|
||||
sendFlow = (messageToSend, numberOrId) => {
|
||||
const queue = []
|
||||
for (const message of messageToSend) {
|
||||
queue.push(this.providerClass.sendMessage(numberOrId, message))
|
||||
}
|
||||
return Promise.all(queue)
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {*} message
|
||||
* @param {*} ref
|
||||
*/
|
||||
continue = (message, ref = false) => {
|
||||
const responde = this.flowClass.find(message, ref)
|
||||
if (responde) {
|
||||
this.providerClass.sendMessage(responde.answer)
|
||||
this.databaseClass.saveLog(responde.answer)
|
||||
this.continue(null, responde.ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = BotClass
|
||||
25
packages/bot/classes/provider.class.js
Normal file
25
packages/bot/classes/provider.class.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const { EventEmitter } = require('node:events')
|
||||
/**
|
||||
* Esta clase debe siempre proporcionar los siguietes metodos
|
||||
* sendMessage = Para enviar un mensaje
|
||||
*
|
||||
* @important
|
||||
* Esta clase extiende de la clase del provider OJO
|
||||
* Eventos
|
||||
* - message
|
||||
* - ready
|
||||
* - error
|
||||
* - require_action
|
||||
*/
|
||||
class ProviderClass extends EventEmitter {
|
||||
/**
|
||||
* events: message | auth | auth_error | ...
|
||||
*
|
||||
*/
|
||||
|
||||
sendMessage = async (userId, message) => {
|
||||
return message
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ProviderClass
|
||||
12
packages/bot/index.js
Normal file
12
packages/bot/index.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const BotClass = require('./classes/bot.class')
|
||||
const ProviderClass = require('./classes/provider.class')
|
||||
|
||||
/**
|
||||
* Crear instancia de clase
|
||||
* @param {*} args
|
||||
* @returns
|
||||
*/
|
||||
const create = async ({ flow, database, provider }) =>
|
||||
new BotClass(flow, database, provider)
|
||||
|
||||
module.exports = { create, ProviderClass }
|
||||
22
packages/bot/package.json
Normal file
22
packages/bot/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@bot-whatsapp/bot",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"core:dev": "node ./index.js",
|
||||
"core:rollup": "node ../../node_modules/.bin/rollup index.js --config ./rollup-cli.config.js",
|
||||
"format:check": "prettier --check .",
|
||||
"format:write": "prettier --write .",
|
||||
"lint:check": "eslint .",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"test.unit": "cross-env NODE_ENV=test node ../../node_modules/uvu/bin.js tests"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"kleur": "^4.1.5"
|
||||
}
|
||||
}
|
||||
14
packages/bot/rollup-bot.config.js
Normal file
14
packages/bot/rollup-bot.config.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const commonjs = require('@rollup/plugin-commonjs')
|
||||
const { nodeResolve } = require('@rollup/plugin-node-resolve')
|
||||
const { join } = require('path')
|
||||
|
||||
const PATH = join(__dirname, 'lib', 'bot', 'bundle.bot.cjs')
|
||||
|
||||
module.exports = {
|
||||
input: 'index.js',
|
||||
output: {
|
||||
file: PATH,
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [commonjs(), nodeResolve()],
|
||||
}
|
||||
95
packages/bot/tests/bot.class.test.js
Normal file
95
packages/bot/tests/bot.class.test.js
Normal file
@@ -0,0 +1,95 @@
|
||||
const { test } = require('uvu')
|
||||
const assert = require('uvu/assert')
|
||||
const MockProvider = require('../../../__mocks__/mock.provider')
|
||||
const { create } = require('@bot-whatsapp/bot')
|
||||
const BotClass = require('@bot-whatsapp/bot/classes/bot.class')
|
||||
|
||||
class MockFlow {
|
||||
find = () => {}
|
||||
}
|
||||
|
||||
class MockDB {
|
||||
save = () => {}
|
||||
}
|
||||
|
||||
test(`[BotClass] Probando instanciamiento de clase`, async () => {
|
||||
const setting = {
|
||||
flow: new MockFlow(),
|
||||
database: new MockDB(),
|
||||
provider: new MockProvider(),
|
||||
}
|
||||
const bot = await create(setting)
|
||||
assert.is(bot instanceof BotClass, true)
|
||||
})
|
||||
|
||||
test(`[BotClass] Eventos 'require_action,ready,auth_failure,message '`, async () => {
|
||||
let responseEvents = {}
|
||||
|
||||
const MOCK_EVENTS = {
|
||||
require_action: {
|
||||
instructions: 'Debes...',
|
||||
},
|
||||
ready: true,
|
||||
auth_failure: {
|
||||
instructions: 'Error...',
|
||||
},
|
||||
message: {
|
||||
from: 'XXXXXX',
|
||||
body: 'hola',
|
||||
hasMedia: false,
|
||||
},
|
||||
}
|
||||
|
||||
const mockProvider = new MockProvider()
|
||||
|
||||
const setting = {
|
||||
flow: new MockFlow(),
|
||||
database: new MockDB(),
|
||||
provider: mockProvider,
|
||||
}
|
||||
await create(setting)
|
||||
|
||||
/// Escuchamos eventos
|
||||
mockProvider.on(
|
||||
'require_action',
|
||||
(r) => (responseEvents['require_action'] = r)
|
||||
)
|
||||
mockProvider.on('ready', (r) => (responseEvents['ready'] = r))
|
||||
mockProvider.on('auth_failure', (r) => (responseEvents['auth_failure'] = r))
|
||||
mockProvider.on('message', (r) => (responseEvents['message'] = r))
|
||||
|
||||
/// Emitimos eventos
|
||||
mockProvider.delaySendMessage(
|
||||
0,
|
||||
'require_action',
|
||||
MOCK_EVENTS.require_action
|
||||
)
|
||||
mockProvider.delaySendMessage(0, 'ready', MOCK_EVENTS.ready)
|
||||
mockProvider.delaySendMessage(0, 'auth_failure', MOCK_EVENTS.auth_failure)
|
||||
mockProvider.delaySendMessage(0, 'message', MOCK_EVENTS.message)
|
||||
|
||||
await delay(0)
|
||||
|
||||
/// Testeamos eventos
|
||||
assert.is(
|
||||
JSON.stringify(responseEvents.require_action),
|
||||
JSON.stringify(MOCK_EVENTS.require_action)
|
||||
)
|
||||
assert.is(responseEvents.ready, MOCK_EVENTS.ready)
|
||||
|
||||
assert.is(
|
||||
JSON.stringify(responseEvents.auth_failure),
|
||||
JSON.stringify(MOCK_EVENTS.auth_failure)
|
||||
)
|
||||
|
||||
assert.is(
|
||||
JSON.stringify(responseEvents.message),
|
||||
JSON.stringify(MOCK_EVENTS.message)
|
||||
)
|
||||
})
|
||||
|
||||
test.run()
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((res) => setTimeout(res, ms))
|
||||
}
|
||||
14
packages/bot/utils/interactive.js
Normal file
14
packages/bot/utils/interactive.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const { yellow, bgRed } = require('kleur')
|
||||
const NODE_ENV = process.env.NODE_ENV || 'dev'
|
||||
const printer = (message, title) => {
|
||||
if (NODE_ENV !== 'test') {
|
||||
console.clear()
|
||||
if (title) console.log(bgRed(`${title}`))
|
||||
console.log(
|
||||
yellow(Array.isArray(message) ? message.join('\n') : message)
|
||||
)
|
||||
console.log(``)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { printer }
|
||||
Reference in New Issue
Block a user