Skip to content

Commit

Permalink
Merge pull request #838 from codigoencasa/dev
Browse files Browse the repository at this point in the history
chore: next version 0.1.32
  • Loading branch information
leifermendez authored Aug 31, 2023
2 parents 83c7e47 + ed0be7b commit df75e5f
Show file tree
Hide file tree
Showing 39 changed files with 1,917 additions and 238 deletions.
114 changes: 114 additions & 0 deletions __test__/0.1.6-case.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const { suite } = require('uvu')
const assert = require('uvu/assert')
const { addKeyword, createBot, createFlow, EVENTS } = require('../packages/bot/index')
const { setup, clear, delay } = require('../__mocks__/env')
const { generateRefprovider } = require('../packages/provider/common/hash')

const fakeHTTP = async (fakeData = []) => {
await delay(50)
const data = fakeData.map((u) => ({ body: `${u}` }))
return Promise.resolve(data)
}

const suiteCase = suite('EVENTS:')

suiteCase.before.each(setup)
suiteCase.after.each(clear)

suiteCase(`WELCOME`, async ({ database, provider }) => {
const flow = addKeyword(EVENTS.WELCOME).addAnswer('Bievenido')

createBot({
database,
provider,
flow: createFlow([flow]),
})

await provider.delaySendMessage(0, 'message', {
from: '000',
body: 'hola',
})

await delay(100)
const getHistory = database.listHistory.map((i) => i.answer)

assert.is('Bievenido', getHistory[0])
})

suiteCase(`MEDIA`, async ({ database, provider }) => {
const flow = addKeyword(EVENTS.MEDIA).addAnswer('media recibido')

createBot({
database,
provider,
flow: createFlow([flow]),
})

await provider.delaySendMessage(0, 'message', {
from: '000',
body: generateRefprovider('_event_media_'),
})
await delay(100)
const getHistory = database.listHistory.map((i) => i.answer)

assert.is('media recibido', getHistory[0])
})

suiteCase(`LOCATION`, async ({ database, provider }) => {
const flow = addKeyword(EVENTS.LOCATION).addAnswer('location recibido')

createBot({
database,
provider,
flow: createFlow([flow]),
})

await provider.delaySendMessage(0, 'message', {
from: '000',
body: generateRefprovider('_event_location_'),
})
await delay(100)
const getHistory = database.listHistory.map((i) => i.answer)

assert.is('location recibido', getHistory[0])
})

suiteCase(`DOCUMENT`, async ({ database, provider }) => {
const flow = addKeyword(EVENTS.DOCUMENT).addAnswer('document recibido')

createBot({
database,
provider,
flow: createFlow([flow]),
})

await provider.delaySendMessage(0, 'message', {
from: '000',
body: generateRefprovider('_event_document_'),
})
await delay(100)
const getHistory = database.listHistory.map((i) => i.answer)

assert.is('document recibido', getHistory[0])
})

suiteCase(`VOICE_NOTE`, async ({ database, provider }) => {
const flow = addKeyword(EVENTS.VOICE_NOTE).addAnswer('voice recibido')

createBot({
database,
provider,
flow: createFlow([flow]),
})

await provider.delaySendMessage(0, 'message', {
from: '000',
body: generateRefprovider('_event_voice_note_'),
})
await delay(100)
const getHistory = database.listHistory.map((i) => i.answer)

assert.is('voice recibido', getHistory[0])
})

suiteCase.run()
File renamed without changes.
46 changes: 46 additions & 0 deletions __test__/0.1.8-case.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const { suite } = require('uvu')
const assert = require('uvu/assert')
const { addKeyword, createBot, createFlow } = require('../packages/bot/index')
const { setup, clear, delay } = require('../__mocks__/env')

const suiteCase = suite('Flujo: addAction (capture)')

suiteCase.before.each(setup)
suiteCase.after.each(clear)

suiteCase(`Debe ejecutar accion con captura`, async ({ database, provider }) => {
const flujoPrincipal = addKeyword(['hola'])
.addAction(async (_, { flowDynamic }) => {
return flowDynamic('Buenas! ¿Cual es tu nombre?')
})
.addAction({ capture: true }, async (ctx, { flowDynamic, state }) => {
state.update({ name: ctx.body })
return flowDynamic(`Gracias por tu nombre!: ${ctx.body}`)
})
.addAnswer('Chao!')

await createBot({
database,
flow: createFlow([flujoPrincipal]),
provider,
})

await provider.delaySendMessage(0, 'message', {
from: '000',
body: 'hola',
})

await provider.delaySendMessage(50, 'message', {
from: '000',
body: 'Leifer',
})

await delay(1000)
const getHistory = database.listHistory.map((i) => i.answer)
assert.is('Buenas! ¿Cual es tu nombre?', getHistory[0])
assert.is('Gracias por tu nombre!: Leifer', getHistory[3])
assert.is('Chao!', getHistory[4])
assert.is(undefined, getHistory[5])
})

suiteCase.run()
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/root",
"version": "0.1.30",
"version": "0.1.31",
"description": "Bot de wahtsapp open source para MVP o pequeños negocios",
"main": "app.js",
"private": true,
Expand Down
93 changes: 66 additions & 27 deletions packages/bot/core/core.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const Queue = require('../utils/queue')
const { LIST_REGEX } = require('../io/events')
const SingleState = require('../context/state.class')
const GlobalState = require('../context/globalState.class')
const { generateTime } = require('../utils/hash')

const logger = new Console({
stdout: createWriteStream(`${process.cwd()}/core.class.log`),
Expand Down Expand Up @@ -157,6 +158,7 @@ class CoreClass {
// 📄 Limpiar cola de procesos
const clearQueue = () => {
this.queuePrincipal.clearQueue(from)
return
}

// 📄 Finalizar flujo
Expand All @@ -171,7 +173,9 @@ class CoreClass {
}

// 📄 Esta funcion se encarga de enviar un array de mensajes dentro de este ctx
const sendFlow = async (messageToSend, numberOrId, options = { prev: prevMsg }) => {
const sendFlow = async (messageToSend, numberOrId, options = {}) => {
options = { prev: prevMsg, forceQueue: false, ...options }

if (options.prev?.options?.capture) {
await cbEveryCtx(options.prev?.ref)
}
Expand All @@ -186,15 +190,33 @@ class CoreClass {
await delay(delayMs) // Esperar según el retraso configurado
}

logger.log(`[sendQueue_A]: `, ctxMessage)
//TODO el proceso de forzar cola de procsos
if (options?.forceQueue) {
const listIdsRefCallbacks = messageToSend.map((i) => i.ref)

const listProcessWait = this.queuePrincipal.getIdsCallbacs(from)
if (!listProcessWait.length) {
this.queuePrincipal.setIdsCallbacks(from, listIdsRefCallbacks)
} else {
const lastMessage = messageToSend[messageToSend.length - 1]
await this.databaseClass.save({ ...lastMessage, from: numberOrId })
if (listProcessWait.includes(lastMessage.ref)) {
this.queuePrincipal.clearQueue(from)
}
}
}

try {
await this.queuePrincipal.enqueue(from, async () => {
// Usar async en la función pasada a enqueue
await this.sendProviderAndSave(numberOrId, ctxMessage)
logger.log(`[QUEUE_SE_ENVIO]: `, ctxMessage)
await resolveCbEveryCtx(ctxMessage)
})
await this.queuePrincipal.enqueue(
from,
async () => {
// Usar async en la función pasada a enqueue
await this.sendProviderAndSave(numberOrId, ctxMessage)
logger.log(`[QUEUE_SE_ENVIO]: `, ctxMessage)
await resolveCbEveryCtx(ctxMessage)
},
ctxMessage.ref
)
} catch (error) {
logger.error(`Error al encolar: ${error.message}`)
return Promise.reject
Expand All @@ -215,12 +237,10 @@ class CoreClass {
const flowStandaloneChild = this.flowClass.getFlowsChild()
const nextChildMessages =
(await this.flowClass.find(refToContinueChild?.ref, true, flowStandaloneChild)) || []
if (nextChildMessages?.length) return await sendFlow(nextChildMessages, from, { prev: undefined })
}
if (nextChildMessages?.length)
return exportFunctionsSend(() => sendFlow(nextChildMessages, from, { prev: undefined }))

if (!isContinueFlow) {
await sendFlow(filterNextFlow, from, { prev: undefined })
return
return exportFunctionsSend(() => sendFlow(filterNextFlow, from, { prev: undefined }))
}
}
// 📄 [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje
Expand Down Expand Up @@ -269,13 +289,14 @@ class CoreClass {
const parseListMsg = listMsg.map((opt, index) => createCtxMessage(opt, index))

if (endFlowFlag) return
this.queuePrincipal.setFingerTime(from, generateTime()) //aqui debeo decirle al sistema como que finalizo el flujo
for (const msg of parseListMsg) {
const delayMs = msg?.options?.delay ?? this.generalArgs.delay ?? 0
if (delayMs) await delay(delayMs)
await this.sendProviderAndSave(from, msg)
}

if (options?.continue) await continueFlow()
if (options?.continue) await continueFlow(generateTime())
return
}

Expand Down Expand Up @@ -313,11 +334,27 @@ class CoreClass {
await this.flowClass.allCallbacks[inRef](messageCtxInComming, argsCb)
//Si no hay llamado de fallaback y no hay llamado de flowDynamic y no hay llamado de enflow EL flujo continua
const ifContinue = !flags.endFlow && !flags.fallBack && !flags.flowDynamic
if (ifContinue) await continueFlow()
if (ifContinue) await continueFlow(prevMsg?.options?.nested?.length)

return
}

const exportFunctionsSend = async (cb = () => Promise.resolve()) => {
await cb()
return {
createCtxMessage,
clearQueue,
endFlow,
sendFlow,
continueFlow,
fallBack,
gotoFlow,
flowDynamic,
resolveCbEveryCtx,
cbEveryCtx,
}
}

// 📄🤘(tiene return) [options: nested(array)]: Si se tiene flujos hijos los implementa
if (!endFlowFlag && prevMsg?.options?.nested?.length) {
const nestedRef = prevMsg.options.nested
Expand All @@ -327,8 +364,7 @@ class CoreClass {

msgToSend = this.flowClass.find(body, false, flowStandalone) || []

await sendFlow(msgToSend, from)
return
return exportFunctionsSend(() => sendFlow(msgToSend, from))
}

// 📄🤘(tiene return) Si el mensaje previo implementa capture
Expand All @@ -337,14 +373,15 @@ class CoreClass {

if (typeCapture === 'boolean' && fallBackFlag) {
msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
await sendFlow(msgToSend, from)
return
return exportFunctionsSend(() => sendFlow(msgToSend, from, { forceQueue: true }))
}
}

msgToSend = this.flowClass.find(body) || []

if (msgToSend.length) return sendFlow(msgToSend, from)
if (msgToSend.length) {
return exportFunctionsSend(() => sendFlow(msgToSend, from))
}

if (!prevMsg?.options?.capture) {
msgToSend = this.flowClass.find(this.generalArgs.listEvents.WELCOME) || []
Expand All @@ -365,7 +402,7 @@ class CoreClass {
msgToSend = this.flowClass.find(this.generalArgs.listEvents.VOICE_NOTE) || []
}
}
return sendFlow(msgToSend, from)
return exportFunctionsSend(() => sendFlow(msgToSend, from, { forceQueue: true }))
}

/**
Expand All @@ -377,18 +414,16 @@ class CoreClass {
sendProviderAndSave = async (numberOrId, ctxMessage) => {
try {
const { answer } = ctxMessage
logger.log(`[sendProviderAndSave]: `, ctxMessage)
if (answer && answer.length && answer !== '__call_action__') {
await this.providerClass.sendMessage(numberOrId, answer, ctxMessage)
logger.log(`[providerClass.sendMessage]: `, ctxMessage)
if (answer !== '__capture_only_intended__') {
await this.providerClass.sendMessage(numberOrId, answer, ctxMessage)
}
await this.databaseClass.save({ ...ctxMessage, from: numberOrId })
logger.log(`[databaseClass.save]: `, ctxMessage)
}

return Promise.resolve
} catch (err) {
logger.log(`[ERROR.save]: `, ctxMessage)
console.log('ERROR:Enviando')
return Promise.reject
}
}
Expand Down Expand Up @@ -419,7 +454,11 @@ class CoreClass {
for (const ctxMessage of messageToSend) {
const delayMs = ctxMessage?.options?.delay ?? this.generalArgs.delay ?? 0
if (delayMs) await delay(delayMs)
await this.queuePrincipal.enqueue(numberOrId, () => this.sendProviderAndSave(numberOrId, ctxMessage))
await this.queuePrincipal.enqueue(
numberOrId,
() => this.sendProviderAndSave(numberOrId, ctxMessage),
generateTime()
)
// await queuePromises.dequeue()
}
return Promise.resolve
Expand Down
5 changes: 4 additions & 1 deletion packages/bot/io/methods/addAnswer.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@ const addAnswer =
ctx,
ref: ctx.ref,
addAnswer: addAnswer(ctx),
addAction: (cb = () => null) => addAnswer(ctx)('__call_action__', null, cb),
addAction: (cb = () => null, flagCb = () => null) => {
if (typeof cb === 'object') return addAnswer(ctx)('__capture_only_intended__', cb, flagCb)
return addAnswer(ctx)('__call_action__', null, cb)
},
toJson: toJson(ctx),
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/bot/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/bot",
"version": "0.0.156-alpha.0",
"version": "0.0.167-alpha.0",
"description": "",
"main": "./lib/bundle.bot.cjs",
"scripts": {
Expand Down
Loading

0 comments on commit df75e5f

Please sign in to comment.