rename core to bot

This commit is contained in:
Leifer Mendez
2022-11-13 14:18:20 +01:00
parent 59182f20f3
commit 3946c88ed7
13 changed files with 9 additions and 51 deletions

View 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

View 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
View 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
View 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"
}
}

View 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()],
}

View 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))
}

View 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 }