diff --git a/.husky/commit-msg b/.husky/commit-msg
index 4002db717..3d3fb5271 100755
--- a/.husky/commit-msg
+++ b/.husky/commit-msg
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
-npx --no -- commitlint --edit
+npm run lint:fix && npx --no -- commitlint --edit
diff --git a/.prettierignore b/.prettierignore
index 547ec21b6..7fffea952 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,5 +1,5 @@
packages/**/lib
-packages/docs/*.json
+packages/docs/
**/.git
**/.svn
**/.hg
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 0d0e52b36..1ace26051 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,3 +1,3 @@
{
- "recommendations": ["xyc.vscode-mdx-preview"]
+ "recommendations": ["xyc.vscode-mdx-preview", "vivaxy.vscode-conventional-commits", "mhutchie.git-graph"]
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d0bdbfa2d..01adb7fa2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,27 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+### [0.1.20](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.19...v0.1.20) (2023-02-05)
+
+
+### Features
+
+* **cli:** :fire: add regex expression in addKeyworkd ([e34560c](https://github.com/leifermendez/bot-whatsapp/commit/e34560c77d4852d2e90930f0858e51aa67d4eeab))
+* **provider:** :zap: possible get class provider ([76ba717](https://github.com/leifermendez/bot-whatsapp/commit/76ba717927a75b3d6299206aa0b8aee2bc25b726))
+
+
+### Bug Fixes
+
+* **cli:** :zap: working flowDynamic test ([c0113ca](https://github.com/leifermendez/bot-whatsapp/commit/c0113ca49295aff220d8defcb53f2ba7f2872d75))
+* **cli:** :zap: working flowDynamic test ([aef52d2](https://github.com/leifermendez/bot-whatsapp/commit/aef52d2694fa6616d614338643db198b4f7f1fe8))
+* **cli:** :zap: working flowDynamic test ([f769320](https://github.com/leifermendez/bot-whatsapp/commit/f76932021ce968d93241b55cfcdb8ae0e0e6c934))
+* **cli:** :zap: working flowDynamic test ([23e09ef](https://github.com/leifermendez/bot-whatsapp/commit/23e09efaeccaf51018c55da492edff45b625f0a9))
+* **database:** add support emoji in mysql ([9311aa0](https://github.com/leifermendez/bot-whatsapp/commit/9311aa0a65623a1bf40e96207a281625154dae90))
+* **database:** fix naming ([cd082f2](https://github.com/leifermendez/bot-whatsapp/commit/cd082f235012cd5f5844c6437f51711beee0c865))
+* **database:** fix naming ([1afc3ba](https://github.com/leifermendez/bot-whatsapp/commit/1afc3ba182070713b5bec40eaab0fa1f680830cd))
+* **database:** fix naming ([c9831d2](https://github.com/leifermendez/bot-whatsapp/commit/c9831d202ab2c85f15a0247cd2a2426bc435270c))
+* **provider:** :zap: baily wa.link ([96c2bff](https://github.com/leifermendez/bot-whatsapp/commit/96c2bffd093269be8e39474a84c156938504a6cb))
+
### [0.1.19](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.18...v0.1.19) (2023-01-29)
diff --git a/__test__/01-case.test.js b/__test__/01-case.test.js
index bce4a42b4..57ae08c39 100644
--- a/__test__/01-case.test.js
+++ b/__test__/01-case.test.js
@@ -2,12 +2,7 @@ const { test } = require('uvu')
const assert = require('uvu/assert')
const MOCK_DB = require('../packages/database/src/mock')
const PROVIDER_DB = require('../packages/provider/src/mock')
-const {
- addKeyword,
- createBot,
- createFlow,
- createProvider,
-} = require('../packages/bot')
+const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
test(`[Caso - 01] Flow Basico`, async () => {
const [VALUE_A, VALUE_B] = ['hola', 'buenas']
diff --git a/__test__/05-case.test.js b/__test__/05-case.test.js
index 6ca65d09e..f61d114d8 100644
--- a/__test__/05-case.test.js
+++ b/__test__/05-case.test.js
@@ -2,12 +2,7 @@ const { test } = require('uvu')
const assert = require('uvu/assert')
const MOCK_DB = require('../packages/database/src/mock')
const PROVIDER_DB = require('../packages/provider/src/mock')
-const {
- addKeyword,
- createBot,
- createFlow,
- createProvider,
-} = require('../packages/bot/index')
+const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
/**
* Falsear peticion async
@@ -21,11 +16,7 @@ const fakeHTTP = async (fakeData = []) => {
}
test(`[Caso - 05] Continuar Flujo (continueFlow)`, async () => {
- const MOCK_VALUES = [
- '¿CUal es tu email?',
- 'Continuamos....',
- '¿Cual es tu edad?',
- ]
+ const MOCK_VALUES = ['¿CUal es tu email?', 'Continuamos....', '¿Cual es tu edad?']
const provider = createProvider(PROVIDER_DB)
const database = new MOCK_DB()
@@ -39,26 +30,20 @@ test(`[Caso - 05] Continuar Flujo (continueFlow)`, async () => {
const validation = ctx.body.includes('@')
if (validation) {
- const getDataFromApi = await fakeHTTP([
- 'Gracias por tu email se ha validado de manera correcta',
- ])
+ const getDataFromApi = await fakeHTTP(['Gracias por tu email se ha validado de manera correcta'])
return flowDynamic(getDataFromApi)
}
return fallBack(validation)
}
)
.addAnswer(MOCK_VALUES[1])
- .addAnswer(
- MOCK_VALUES[2],
- { capture: true },
- async (ctx, { flowDynamic, fallBack }) => {
- if (ctx.body !== '18') {
- await delay(50)
- return fallBack(false, 'Ups creo que no eres mayor de edad')
- }
- return flowDynamic('Bien tu edad es correcta!')
+ .addAnswer(MOCK_VALUES[2], { capture: true }, async (ctx, { flowDynamic, fallBack }) => {
+ if (ctx.body !== '18') {
+ await delay(50)
+ return fallBack(false, 'Ups creo que no eres mayor de edad')
}
- )
+ return flowDynamic('Bien tu edad es correcta!')
+ })
.addAnswer('Puedes pasar')
createBot({
@@ -98,10 +83,7 @@ test(`[Caso - 05] Continuar Flujo (continueFlow)`, async () => {
assert.is('this is not email value', getHistory[1])
assert.is(MOCK_VALUES[0], getHistory[2])
assert.is('test@test.com', getHistory[3])
- assert.is(
- '1 Gracias por tu email se ha validado de manera correcta',
- getHistory[4]
- )
+ assert.is('1 Gracias por tu email se ha validado de manera correcta', getHistory[4])
assert.is(MOCK_VALUES[1], getHistory[5])
assert.is(MOCK_VALUES[2], getHistory[6])
assert.is('20', getHistory[7])
diff --git a/__test__/07-case.test.js b/__test__/07-case.test.js
new file mode 100644
index 000000000..6eb8e4208
--- /dev/null
+++ b/__test__/07-case.test.js
@@ -0,0 +1,92 @@
+const { test } = require('uvu')
+const assert = require('uvu/assert')
+const MOCK_DB = require('../packages/database/src/mock')
+const PROVIDER_DB = require('../packages/provider/src/mock')
+const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
+
+/**
+ * Falsear peticion async
+ * @param {*} fakeData
+ * @returns
+ */
+const fakeHTTP = async (fakeData = []) => {
+ await delay(5)
+ const data = fakeData.map((u, i) => ({ body: `${i + 1} ${u}` }))
+ return Promise.resolve(data)
+}
+
+let STATE_APP = {}
+
+test(`[Caso - 07] Retornar estado`, async () => {
+ const MOCK_VALUES = ['¿Cual es tu nombre?', '¿Cual es tu edad?', 'Tu datos son:']
+ const provider = createProvider(PROVIDER_DB)
+ const database = new MOCK_DB()
+
+ const flujoPrincipal = addKeyword(['hola'])
+ .addAnswer(
+ MOCK_VALUES[0],
+ {
+ capture: true,
+ },
+ async (ctx, { flowDynamic, fallBack }) => {
+ STATE_APP[ctx.from] = { ...STATE_APP[ctx.from], name: ctx.body }
+
+ flowDynamic('Gracias por tu nombre!')
+ }
+ )
+ .addAnswer(
+ MOCK_VALUES[1],
+ {
+ capture: true,
+ },
+ async (ctx, { flowDynamic, endFlow }) => {
+ STATE_APP[ctx.from] = { ...STATE_APP[ctx.from], age: ctx.body }
+
+ await flowDynamic('Gracias por tu edad!')
+ }
+ )
+ .addAnswer(MOCK_VALUES[2], null, async (ctx, { flowDynamic }) => {
+ flowDynamic(`Nombre: ${STATE_APP[ctx.from].name} Edad: ${STATE_APP[ctx.from].age}`)
+ })
+ .addAnswer('🤖🤖 Gracias por tu participacion')
+
+ createBot({
+ database,
+ flow: createFlow([flujoPrincipal]),
+ provider,
+ })
+
+ provider.delaySendMessage(0, 'message', {
+ from: '000',
+ body: 'hola',
+ })
+
+ provider.delaySendMessage(20, 'message', {
+ from: '000',
+ body: 'Leifer',
+ })
+
+ provider.delaySendMessage(40, 'message', {
+ from: '000',
+ body: '90',
+ })
+
+ await delay(1200)
+ const getHistory = database.listHistory.map((i) => i.answer)
+ assert.is(MOCK_VALUES[0], getHistory[0])
+ assert.is('Leifer', getHistory[1])
+ assert.is('Gracias por tu nombre!', getHistory[2])
+ assert.is('¿Cual es tu edad?', getHistory[3])
+ assert.is('90', getHistory[4])
+ assert.is('Gracias por tu edad!', getHistory[5])
+ assert.is('Tu datos son:', getHistory[6])
+ assert.is('Nombre: Leifer Edad: 90', getHistory[7])
+ assert.is('🤖🤖 Gracias por tu participacion', getHistory[8])
+ assert.is(undefined, getHistory[9])
+})
+
+test.run()
+
+function delay(ms) {
+ return new Promise((res) => setTimeout(res, ms))
+}
diff --git a/__test__/08-case.test.js b/__test__/08-case.test.js
new file mode 100644
index 000000000..82fc46a73
--- /dev/null
+++ b/__test__/08-case.test.js
@@ -0,0 +1,43 @@
+const { test } = require('uvu')
+const assert = require('uvu/assert')
+const MOCK_DB = require('../packages/database/src/mock')
+const PROVIDER_DB = require('../packages/provider/src/mock')
+const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
+
+test(`[Caso - 08] Regular expression on keyword`, async () => {
+ const provider = createProvider(PROVIDER_DB)
+ const database = new MOCK_DB()
+
+ const REGEX_CREDIT_NUMBER = `/(^4[0-9]{12}(?:[0-9]{3})?$)|(^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$)|(3[47][0-9]{13})|(^3(?:0[0-5]|[68][0-9])[0-9]{11}$)|(^6(?:011|5[0-9]{2})[0-9]{12}$)|(^(?:2131|1800|35\d{3})\d{11}$)/gm`
+ const flujoPrincipal = addKeyword(REGEX_CREDIT_NUMBER, { regex: true })
+ .addAnswer(`Gracias por proporcionar un numero de tarjeta valido`)
+ .addAnswer('Fin!')
+
+ createBot({
+ database,
+ flow: createFlow([flujoPrincipal]),
+ provider,
+ })
+
+ provider.delaySendMessage(0, 'message', {
+ from: '000',
+ body: 'hola',
+ })
+
+ provider.delaySendMessage(20, 'message', {
+ from: '000',
+ body: '374245455400126',
+ })
+
+ await delay(40)
+ const getHistory = database.listHistory.map((i) => i.answer)
+ assert.is('Gracias por proporcionar un numero de tarjeta valido', getHistory[0])
+ assert.is('Fin!', getHistory[1])
+ assert.is(undefined, getHistory[2])
+})
+
+test.run()
+
+function delay(ms) {
+ return new Promise((res) => setTimeout(res, ms))
+}
diff --git a/__test__/09-case.test.js b/__test__/09-case.test.js
new file mode 100644
index 000000000..417ce313b
--- /dev/null
+++ b/__test__/09-case.test.js
@@ -0,0 +1,41 @@
+const { test } = require('uvu')
+const assert = require('uvu/assert')
+const MOCK_DB = require('../packages/database/src/mock')
+const PROVIDER_MOCK = require('../packages/provider/src/mock')
+const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
+
+let PROVIDER = undefined
+
+test(`[Caso - 09] Check provider WS`, async () => {
+ const [VALUE_A, VALUE_B] = ['hola', 'buenas']
+
+ const flow = addKeyword(VALUE_A).addAnswer(VALUE_B, null, async (_, { provider }) => {
+ PROVIDER = provider
+ })
+ const provider = createProvider(PROVIDER_MOCK)
+ const database = new MOCK_DB()
+
+ createBot({
+ database,
+ flow: createFlow([flow]),
+ provider,
+ })
+
+ provider.delaySendMessage(100, 'message', {
+ from: '000',
+ body: VALUE_A,
+ })
+
+ await delay(100)
+
+ const prevMsg = database.getPrevByNumber('000')
+
+ assert.is(prevMsg.answer, VALUE_B)
+ assert.is(typeof PROVIDER.sendMessage, 'function')
+})
+
+test.run()
+
+function delay(ms) {
+ return new Promise((res) => setTimeout(res, ms))
+}
diff --git a/package.json b/package.json
index 30e3cf469..cc0b21ab0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/root",
- "version": "0.1.19",
+ "version": "0.1.20",
"description": "Bot de wahtsapp open source para MVP o pequeños negocios",
"main": "app.js",
"private": true,
diff --git a/packages/bot/core/core.class.js b/packages/bot/core/core.class.js
index 9b329ccc9..29cf5d1e2 100644
--- a/packages/bot/core/core.class.js
+++ b/packages/bot/core/core.class.js
@@ -43,8 +43,7 @@ class CoreClass {
},
{
event: 'require_action',
- func: ({ instructions, title = '⚡⚡ ACCIÓN REQUERIDA ⚡⚡' }) =>
- printer(instructions, title),
+ func: ({ instructions, title = '⚡⚡ ACCIÓN REQUERIDA ⚡⚡' }) => printer(instructions, title),
},
{
event: 'ready',
@@ -52,8 +51,7 @@ class CoreClass {
},
{
event: 'auth_failure',
- func: ({ instructions }) =>
- printer(instructions, '⚡⚡ ERROR AUTH ⚡⚡'),
+ func: ({ instructions }) => printer(instructions, '⚡⚡ ERROR AUTH ⚡⚡'),
},
{
@@ -78,9 +76,7 @@ class CoreClass {
if (!body.length) return
let prevMsg = await this.databaseClass.getPrevByNumber(from)
- const refToContinue = this.flowClass.findBySerialize(
- prevMsg?.refSerialize
- )
+ const refToContinue = this.flowClass.findBySerialize(prevMsg?.refSerialize)
if (prevMsg?.ref) {
const ctxByNumber = toCtx({
@@ -93,10 +89,7 @@ class CoreClass {
// 📄 Crar CTX de mensaje (uso private)
const createCtxMessage = (payload = {}, index = 0) => {
- const body =
- typeof payload === 'string'
- ? payload
- : payload?.body ?? payload?.answer
+ const body = typeof payload === 'string' ? payload : payload?.body ?? payload?.answer
const media = payload?.media ?? null
const buttons = payload?.buttons ?? []
const capture = payload?.capture ?? false
@@ -118,30 +111,16 @@ class CoreClass {
// 📄 Finalizar flujo
const endFlow = async (message = null) => {
- prevMsg = null
endFlowFlag = true
- if (message)
- this.sendProviderAndSave(from, createCtxMessage(message))
+ if (message) this.sendProviderAndSave(from, createCtxMessage(message))
clearQueue()
- return
- }
-
- // 📄 Continuar con el siguiente flujo
- const continueFlow = async () => {
- const cotinueMessage =
- this.flowClass.find(refToContinue?.ref, true) || []
- sendFlow(cotinueMessage, from, { continue: true })
+ sendFlow([])
return
}
// 📄 Esta funcion se encarga de enviar un array de mensajes dentro de este ctx
- const sendFlow = async (
- messageToSend,
- numberOrId,
- options = { continue: false }
- ) => {
- if (!options.continue && prevMsg?.options?.capture)
- await cbEveryCtx(prevMsg?.ref)
+ const sendFlow = async (messageToSend, numberOrId, options = { prev: prevMsg }) => {
+ if (options.prev?.options?.capture) await cbEveryCtx(options.prev?.ref)
const queue = []
for (const ctxMessage of messageToSend) {
@@ -150,9 +129,7 @@ class CoreClass {
if (delayMs) await delay(delayMs)
QueuePrincipal.enqueue(() =>
Promise.all([
- this.sendProviderAndSave(numberOrId, ctxMessage).then(
- () => resolveCbEveryCtx(ctxMessage)
- ),
+ this.sendProviderAndSave(numberOrId, ctxMessage).then(() => resolveCbEveryCtx(ctxMessage)),
])
)
}
@@ -160,20 +137,26 @@ class CoreClass {
}
// 📄 [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje
- const fallBack = async (next = false, message = null) => {
+ const fallBack = async (validation = false, message = null) => {
QueuePrincipal.queue = []
- if (next) return continueFlow()
- return this.sendProviderAndSave(from, {
+
+ if (validation) {
+ const currentPrev = await this.databaseClass.getPrevByNumber(from)
+ const nextFlow = await this.flowClass.find(refToContinue?.ref, true)
+ const filterNextFlow = nextFlow.filter((msg) => msg.refSerialize !== currentPrev?.refSerialize)
+
+ return sendFlow(filterNextFlow, from, { prev: undefined })
+ }
+
+ await this.sendProviderAndSave(from, {
...prevMsg,
- answer:
- typeof message === 'string'
- ? message
- : message?.body ?? prevMsg.answer,
+ answer: typeof message === 'string' ? message : message?.body ?? prevMsg.answer,
options: {
...prevMsg.options,
- buttons: message?.buttons ?? prevMsg.options?.buttons,
+ buttons: prevMsg.options?.buttons,
},
})
+ return
}
// 📄 [options: flowDynamic]: esta funcion se encarga de responder un array de respuesta esta limitado a 5 mensajes
@@ -182,31 +165,45 @@ class CoreClass {
const flowDynamic = async (listMsg = []) => {
if (!Array.isArray(listMsg)) listMsg = [listMsg]
- const parseListMsg = listMsg.map((opt, index) =>
- createCtxMessage(opt, index)
- )
+ const parseListMsg = listMsg.map((opt, index) => createCtxMessage(opt, index))
+ const currentPrev = await this.databaseClass.getPrevByNumber(from)
+
+ const skipContinueFlow = async () => {
+ const nextFlow = await this.flowClass.find(refToContinue?.ref, true)
+ const filterNextFlow = nextFlow.filter((msg) => msg.refSerialize !== currentPrev?.refSerialize)
+ const isContinueFlow = filterNextFlow.map((i) => i.keyword).includes(currentPrev?.ref)
+ return {
+ continue: !isContinueFlow,
+ contexts: filterNextFlow,
+ }
+ }
if (endFlowFlag) return
for (const msg of parseListMsg) {
await this.sendProviderAndSave(from, msg)
}
- return continueFlow()
+
+ const continueFlowData = await skipContinueFlow()
+
+ if (continueFlowData.continue) return sendFlow(continueFlowData.contexts, from, { prev: undefined })
+ return
}
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback o fallback
const resolveCbEveryCtx = async (ctxMessage) => {
- if (!ctxMessage?.options?.capture)
- return await cbEveryCtx(ctxMessage?.ref)
+ if (!ctxMessage?.options?.capture) return await cbEveryCtx(ctxMessage?.ref)
}
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback y ejecutarlo
const cbEveryCtx = async (inRef) => {
+ const provider = this.providerClass
+
if (!this.flowClass.allCallbacks[inRef]) return Promise.resolve()
return this.flowClass.allCallbacks[inRef](messageCtxInComming, {
+ provider,
fallBack,
flowDynamic,
endFlow,
- continueFlow,
})
}
@@ -246,10 +243,9 @@ class CoreClass {
*/
sendProviderAndSave = (numberOrId, ctxMessage) => {
const { answer } = ctxMessage
- return Promise.all([
- this.providerClass.sendMessage(numberOrId, answer, ctxMessage),
- this.databaseClass.save({ ...ctxMessage, from: numberOrId }),
- ])
+ return this.providerClass
+ .sendMessage(numberOrId, answer, ctxMessage)
+ .then(() => this.databaseClass.save({ ...ctxMessage, from: numberOrId }))
}
/**
@@ -279,9 +275,7 @@ class CoreClass {
for (const ctxMessage of messageToSend) {
const delayMs = ctxMessage?.options?.delay || 0
if (delayMs) await delay(delayMs)
- QueuePrincipal.enqueue(() =>
- this.sendProviderAndSave(numberOrId, ctxMessage)
- )
+ QueuePrincipal.enqueue(() => this.sendProviderAndSave(numberOrId, ctxMessage))
}
return Promise.all(queue)
}
diff --git a/packages/bot/index.js b/packages/bot/index.js
index ac96063b0..fe03d60c0 100644
--- a/packages/bot/index.js
+++ b/packages/bot/index.js
@@ -8,8 +8,7 @@ const { addKeyword, addAnswer, addChild, toSerialize } = require('./io/methods')
* @param {*} args
* @returns
*/
-const createBot = async ({ flow, database, provider }, args = {}) =>
- new CoreClass(flow, database, provider, args)
+const createBot = async ({ flow, database, provider }, args = {}) => new CoreClass(flow, database, provider, args)
/**
* Crear instancia de clase Io (Flow)
@@ -29,8 +28,7 @@ const createFlow = (args) => {
*/
const createProvider = (providerClass = class {}, args = null) => {
const providerInstance = new providerClass(args)
- if (!providerClass.prototype instanceof ProviderClass)
- throw new Error('El provider no implementa ProviderClass')
+ if (!providerClass.prototype instanceof ProviderClass) throw new Error('El provider no implementa ProviderClass')
return providerInstance
}
diff --git a/packages/bot/io/flow.class.js b/packages/bot/io/flow.class.js
index 458c42361..13de732fa 100644
--- a/packages/bot/io/flow.class.js
+++ b/packages/bot/io/flow.class.js
@@ -25,9 +25,17 @@ class FlowClass {
let refSymbol = null
overFlow = overFlow ?? this.flowSerialize
+ const customRegex = (str = null) => {
+ if (typeof str !== 'string') return
+ const instanceRegex = new RegExp(str)
+ return instanceRegex.test(str)
+ }
+
/** Retornar expresion regular para buscar coincidencia */
- const mapSensitive = (str, flag = false) => {
- const regexSensitive = flag ? 'g' : 'i'
+ const mapSensitive = (str, mapOptions = { sensitive: false, regex: false }) => {
+ if (mapOptions.regex) return customRegex(str)
+
+ const regexSensitive = mapOptions.sensitive ? 'g' : 'i'
if (Array.isArray(str)) {
return new RegExp(str.join('|'), regexSensitive)
}
@@ -36,6 +44,7 @@ class FlowClass {
const findIn = (keyOrWord, symbol = false, flow = overFlow) => {
const sensitive = refSymbol?.options?.sensitive || false
+ const regex = refSymbol?.options?.regex || false
capture = refSymbol?.options?.capture || false
if (capture) return messages
@@ -46,7 +55,7 @@ class FlowClass {
if (refSymbol?.ref) findIn(refSymbol.ref, true)
} else {
refSymbol = flow.find((c) => {
- return mapSensitive(c.keyword, sensitive).test(keyOrWord)
+ return mapSensitive(c.keyword, { sensitive, regex }).test(keyOrWord)
})
if (refSymbol?.ref) findIn(refSymbol.ref, true)
return messages
@@ -56,8 +65,7 @@ class FlowClass {
return messages
}
- findBySerialize = (refSerialize) =>
- this.flowSerialize.find((r) => r.refSerialize === refSerialize)
+ findBySerialize = (refSerialize) => this.flowSerialize.find((r) => r.refSerialize === refSerialize)
findIndexByRef = (ref) => this.flowSerialize.findIndex((r) => r.ref === ref)
}
diff --git a/packages/bot/io/methods/addAnswer.js b/packages/bot/io/methods/addAnswer.js
index f0ccdad19..5236c149b 100644
--- a/packages/bot/io/methods/addAnswer.js
+++ b/packages/bot/io/methods/addAnswer.js
@@ -17,15 +17,10 @@ const addAnswer =
* @returns
*/
const getAnswerOptions = () => ({
- media:
- typeof options?.media === 'string' ? `${options?.media}` : null,
+ media: typeof options?.media === 'string' ? `${options?.media}` : null,
buttons: Array.isArray(options?.buttons) ? options.buttons : [],
- capture:
- typeof options?.capture === 'boolean'
- ? options?.capture
- : false,
- child:
- typeof options?.child === 'string' ? `${options?.child}` : null,
+ capture: typeof options?.capture === 'boolean' ? options?.capture : false,
+ child: typeof options?.child === 'string' ? `${options?.child}` : null,
delay: typeof options?.delay === 'number' ? options?.delay : 0,
})
@@ -49,8 +44,7 @@ const addAnswer =
* Esta funcion aplana y busca los callback anidados de los hijos
* @returns
*/
- const getCbFromNested = () =>
- flatObject(Array.isArray(nested) ? nested : [nested])
+ const getCbFromNested = () => flatObject(Array.isArray(nested) ? nested : [nested])
const callback = typeof cb === 'function' ? cb : () => null
diff --git a/packages/bot/io/methods/addKeyword.js b/packages/bot/io/methods/addKeyword.js
index e17f9be77..50a5c0c39 100644
--- a/packages/bot/io/methods/addKeyword.js
+++ b/packages/bot/io/methods/addKeyword.js
@@ -8,12 +8,14 @@ const { toJson } = require('./toJson')
* @param {*} options {sensitive:boolean} default false
*/
const addKeyword = (keyword, options) => {
+ if (typeof keyword !== 'string' && !Array.isArray(keyword)) {
+ throw new Error('DEBE_SER_STRING_ARRAY_REGEX')
+ }
+
const parseOptions = () => {
const defaultProperties = {
- sensitive:
- typeof options?.sensitive === 'boolean'
- ? options?.sensitive
- : false,
+ sensitive: typeof options?.sensitive === 'boolean' ? options?.sensitive : false,
+ regex: typeof options?.regex === 'boolean' ? options?.regex : false,
}
return defaultProperties
diff --git a/packages/bot/package.json b/packages/bot/package.json
index 3d4acf3f9..563cd74bb 100644
--- a/packages/bot/package.json
+++ b/packages/bot/package.json
@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/bot",
- "version": "0.0.91-alpha.0",
+ "version": "0.0.96-alpha.0",
"description": "",
"main": "./lib/bundle.bot.cjs",
"scripts": {
diff --git a/packages/bot/provider/provider.class.js b/packages/bot/provider/provider.class.js
index 212f0428f..57d7185eb 100644
--- a/packages/bot/provider/provider.class.js
+++ b/packages/bot/provider/provider.class.js
@@ -20,8 +20,7 @@ class ProviderClass extends EventEmitter {
*/
sendMessage = async (userId, message) => {
- if (NODE_ENV !== 'production')
- console.log('[sendMessage]', { userId, message })
+ if (NODE_ENV !== 'production') console.log('[sendMessage]', { userId, message })
return message
}
}
diff --git a/packages/bot/tests/bot.class.test.js b/packages/bot/tests/bot.class.test.js
index d74fdad08..4db4ca8dd 100644
--- a/packages/bot/tests/bot.class.test.js
+++ b/packages/bot/tests/bot.class.test.js
@@ -2,13 +2,7 @@ const { test } = require('uvu')
const assert = require('uvu/assert')
const FlowClass = require('../io/flow.class')
const MockProvider = require('../../../__mocks__/mock.provider')
-const {
- createBot,
- CoreClass,
- createFlow,
- createProvider,
- ProviderClass,
-} = require('../index')
+const { createBot, CoreClass, createFlow, createProvider, ProviderClass } = require('../index')
class MockFlow {
allCallbacks = { ref: () => 1 }
@@ -100,20 +94,13 @@ test(`[Bot] Eventos 'require_action,ready,auth_failure,message '`, async () => {
await createBot(setting)
/// Escuchamos eventos
- mockProvider.on(
- 'require_action',
- (r) => (responseEvents['require_action'] = r)
- )
+ 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, '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)
@@ -121,21 +108,12 @@ test(`[Bot] Eventos 'require_action,ready,auth_failure,message '`, async () => {
await delay(0)
/// Testeamos eventos
- assert.is(
- JSON.stringify(responseEvents.require_action),
- JSON.stringify(MOCK_EVENTS.require_action)
- )
+ 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.auth_failure), JSON.stringify(MOCK_EVENTS.auth_failure))
- assert.is(
- JSON.stringify(responseEvents.message),
- JSON.stringify(MOCK_EVENTS.message)
- )
+ assert.is(JSON.stringify(responseEvents.message), JSON.stringify(MOCK_EVENTS.message))
})
test(`[Bot] Probando Flujos Internos`, async () => {
@@ -166,20 +144,13 @@ test(`[Bot] Probando Flujos Internos`, async () => {
await createBot(setting)
/// Escuchamos eventos
- mockProvider.on(
- 'require_action',
- (r) => (responseEvents['require_action'] = r)
- )
+ 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, '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)
@@ -187,21 +158,12 @@ test(`[Bot] Probando Flujos Internos`, async () => {
await delay(0)
/// Testeamos eventos
- assert.is(
- JSON.stringify(responseEvents.require_action),
- JSON.stringify(MOCK_EVENTS.require_action)
- )
+ 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.auth_failure), JSON.stringify(MOCK_EVENTS.auth_failure))
- assert.is(
- JSON.stringify(responseEvents.message),
- JSON.stringify(MOCK_EVENTS.message)
- )
+ assert.is(JSON.stringify(responseEvents.message), JSON.stringify(MOCK_EVENTS.message))
})
test(`[Bot] Probando Flujos Nested`, async () => {
@@ -234,20 +196,13 @@ test(`[Bot] Probando Flujos Nested`, async () => {
botInstance.sendProviderAndSave('xxxxx', 'xxxxx')
botInstance.continue('xxxxx', 'xxxxx')
/// Escuchamos eventos
- mockProvider.on(
- 'require_action',
- (r) => (responseEvents['require_action'] = r)
- )
+ 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, '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)
@@ -255,21 +210,12 @@ test(`[Bot] Probando Flujos Nested`, async () => {
await delay(0)
/// Testeamos eventos
- assert.is(
- JSON.stringify(responseEvents.require_action),
- JSON.stringify(MOCK_EVENTS.require_action)
- )
+ 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.auth_failure), JSON.stringify(MOCK_EVENTS.auth_failure))
- assert.is(
- JSON.stringify(responseEvents.message),
- JSON.stringify(MOCK_EVENTS.message)
- )
+ assert.is(JSON.stringify(responseEvents.message), JSON.stringify(MOCK_EVENTS.message))
})
test.run()
diff --git a/packages/bot/tests/methods.test.js b/packages/bot/tests/methods.test.js
index 10b09770b..f03073187 100644
--- a/packages/bot/tests/methods.test.js
+++ b/packages/bot/tests/methods.test.js
@@ -35,10 +35,7 @@ test('Debere probar toSerialize', () => {
const ARRANGE = {
keyword: ['hola!', 'ole'],
}
- const MAIN_CTX = addKeyword(ARRANGE.keyword)
- .addAnswer('Segundo!')
- .addAnswer('Segundo!')
- .toJson()
+ const MAIN_CTX = addKeyword(ARRANGE.keyword).addAnswer('Segundo!').addAnswer('Segundo!').toJson()
const [ANSWER_A] = MAIN_CTX
@@ -71,9 +68,7 @@ test('Debere probar la anidación', () => {
answer_A: 'Bienvenido',
answer_B: 'Continuar',
}
- const MAIN_CTX = addKeyword(ARRANGE.keyword)
- .addAnswer(ARRANGE.answer_A)
- .addAnswer(ARRANGE.answer_B)
+ const MAIN_CTX = addKeyword(ARRANGE.keyword).addAnswer(ARRANGE.answer_A).addAnswer(ARRANGE.answer_B)
assert.is(MAIN_CTX.ctx.answer, ARRANGE.answer_B)
})
@@ -107,10 +102,7 @@ test('Debere probar error las addAnswer', () => {
})
test('Obtener toJson', () => {
- const [ctxA, ctxB, ctxC] = addKeyword('hola')
- .addAnswer('pera!')
- .addAnswer('chao')
- .toJson()
+ const [ctxA, ctxB, ctxC] = addKeyword('hola').addAnswer('pera!').addAnswer('chao').toJson()
assert.is(ctxA.keyword, 'hola')
assert.match(ctxA.ref, /^key_/)
diff --git a/packages/bot/utils/delay.js b/packages/bot/utils/delay.js
index 021fafe2f..a6534c0f7 100644
--- a/packages/bot/utils/delay.js
+++ b/packages/bot/utils/delay.js
@@ -1,4 +1,3 @@
-const delay = (miliseconds) =>
- new Promise((res) => setTimeout(res, miliseconds))
+const delay = (miliseconds) => new Promise((res) => setTimeout(res, miliseconds))
module.exports = { delay }
diff --git a/packages/bot/utils/flattener.js b/packages/bot/utils/flattener.js
index 875736d40..ddc823fb4 100644
--- a/packages/bot/utils/flattener.js
+++ b/packages/bot/utils/flattener.js
@@ -3,9 +3,7 @@ const flatObject = (listArray = []) => {
if (!listArray.length) return {}
- const cbNestedObj = cbNestedList
- .map(({ ctx }) => ctx?.callbacks)
- .filter((i) => !!i)
+ const cbNestedObj = cbNestedList.map(({ ctx }) => ctx?.callbacks).filter((i) => !!i)
const queueCb = cbNestedObj.reduce((acc, current) => {
const getKeys = Object.keys(current)
const parse = getKeys.map((icb, i) => ({
diff --git a/packages/bot/utils/hash.js b/packages/bot/utils/hash.js
index 84a25db64..6902d5884 100644
--- a/packages/bot/utils/hash.js
+++ b/packages/bot/utils/hash.js
@@ -16,9 +16,6 @@ const generateRef = (prefix = false) => {
* @returns
*/
const generateRefSerialize = ({ index, answer, keyword }) =>
- crypto
- .createHash('md5')
- .update(JSON.stringify({ index, answer, keyword }))
- .digest('hex')
+ crypto.createHash('md5').update(JSON.stringify({ index, answer, keyword })).digest('hex')
module.exports = { generateRef, generateRefSerialize }
diff --git a/packages/bot/utils/interactive.js b/packages/bot/utils/interactive.js
index c317a7fdd..44905cf8f 100644
--- a/packages/bot/utils/interactive.js
+++ b/packages/bot/utils/interactive.js
@@ -4,9 +4,7 @@ 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(yellow(Array.isArray(message) ? message.join('\n') : message))
console.log(``)
}
}
diff --git a/packages/cli/check/index.js b/packages/cli/check/index.js
index 454f67cce..5befb8a1e 100644
--- a/packages/cli/check/index.js
+++ b/packages/cli/check/index.js
@@ -5,15 +5,9 @@ const checkNodeVersion = () => {
return new Promise((resolve, reject) => {
console.log(bgCyan('🚀 Revisando tu Node.js'))
const version = process.version
- const majorVersion = parseInt(
- version.replace('v', '').split('.').shift()
- )
+ const majorVersion = parseInt(version.replace('v', '').split('.').shift())
if (majorVersion < 16) {
- console.error(
- red(
- `🔴 Se require Node.js 16 o superior. Actualmente esta ejecutando Node.js ${version}`
- )
- )
+ console.error(red(`🔴 Se require Node.js 16 o superior. Actualmente esta ejecutando Node.js ${version}`))
console.log(``)
reject('ERROR_NODE')
}
diff --git a/packages/cli/clean/index.js b/packages/cli/clean/index.js
index 6b7f6fd1f..60b8092b0 100644
--- a/packages/cli/clean/index.js
+++ b/packages/cli/clean/index.js
@@ -2,10 +2,7 @@ const rimraf = require('rimraf')
const { yellow } = require('kleur')
const { join } = require('path')
-const PATH_WW = [
- join(process.cwd(), '.wwebjs_auth'),
- join(process.cwd(), 'session.json'),
-]
+const PATH_WW = [join(process.cwd(), '.wwebjs_auth'), join(process.cwd(), 'session.json')]
const cleanSession = () => {
const queue = []
diff --git a/packages/cli/configuration/index.js b/packages/cli/configuration/index.js
index 50565d97a..2ce60775b 100644
--- a/packages/cli/configuration/index.js
+++ b/packages/cli/configuration/index.js
@@ -23,11 +23,7 @@ const JSON_TEMPLATE = {
const PATH_CONFIG = join(process.cwd(), 'config.json')
const jsonConfig = () => {
- return writeFile(
- PATH_CONFIG,
- JSON.stringify(JSON_TEMPLATE, null, 2),
- 'utf-8'
- )
+ return writeFile(PATH_CONFIG, JSON.stringify(JSON_TEMPLATE, null, 2), 'utf-8')
}
module.exports = { jsonConfig }
diff --git a/packages/cli/install/tool.js b/packages/cli/install/tool.js
index 8095cd08a..a74cec685 100644
--- a/packages/cli/install/tool.js
+++ b/packages/cli/install/tool.js
@@ -20,13 +20,9 @@ const installDeps = (pkgManager, packageList) => {
const installSingle = (pkgInstall) => () => {
new Promise((resolve) => {
try {
- childProcess = spawn(
- pkgManager,
- [PKG_OPTION[pkgManager], pkgInstall],
- {
- stdio: 'inherit',
- }
- )
+ childProcess = spawn(pkgManager, [PKG_OPTION[pkgManager], pkgInstall], {
+ stdio: 'inherit',
+ })
childProcess.on('error', (e) => {
console.error(e)
diff --git a/packages/cli/interactive/index.js b/packages/cli/interactive/index.js
index 53cc885ea..d65ca1962 100644
--- a/packages/cli/interactive/index.js
+++ b/packages/cli/interactive/index.js
@@ -30,9 +30,7 @@ const startInteractive = async () => {
await nextSteps()
} catch (e) {
console.error(bgRed(`Ups! 🙄 algo no va bien.`))
- console.error(
- bgRed(`Revisa los requerimientos minimos en la documentacion`)
- )
+ console.error(bgRed(`Revisa los requerimientos minimos en la documentacion`))
}
}
@@ -82,8 +80,7 @@ const nextSteps = async () => {
const { outDir = '', providerDb = [], providerWs = [] } = response
const createApp = async (templateName = null) => {
- if (!templateName)
- throw new Error('TEMPLATE_NAME_INVALID: ', templateName)
+ if (!templateName) throw new Error('TEMPLATE_NAME_INVALID: ', templateName)
const possiblesPath = [
join(__dirname, '..', '..', 'starters', 'apps', templateName),
@@ -115,11 +112,7 @@ const nextSteps = async () => {
const vendorProvider = async () => {
const [answer] = providerWs
if (!providerWs.length) {
- console.log(
- red(
- `Debes seleccionar un proveedor de whatsapp. Tecla [Space] para seleccionar`
- )
- )
+ console.log(red(`Debes seleccionar un proveedor de whatsapp. Tecla [Space] para seleccionar`))
process.exit(1)
}
return answer
@@ -132,11 +125,7 @@ const nextSteps = async () => {
const dbProvider = async () => {
const [answer] = providerDb
if (!providerDb.length) {
- console.log(
- red(
- `Debes seleccionar un proveedor de base de datos. Tecla [Space] para seleccionar`
- )
- )
+ console.log(red(`Debes seleccionar un proveedor de base de datos. Tecla [Space] para seleccionar`))
process.exit(1)
}
return answer
diff --git a/packages/contexts/src/dialogflow-cx/dialogflow-cx.class.js b/packages/contexts/src/dialogflow-cx/dialogflow-cx.class.js
index 2d0ebd264..6be4f9e40 100644
--- a/packages/contexts/src/dialogflow-cx/dialogflow-cx.class.js
+++ b/packages/contexts/src/dialogflow-cx/dialogflow-cx.class.js
@@ -38,10 +38,8 @@ class DialogFlowCXContext extends CoreClass {
* */
}
- if (!this.optionsDX.location.length)
- throw new Error('LOCATION_NO_ENCONTRADO')
- if (!this.optionsDX.agentId.length)
- throw new Error('AGENTID_NO_ENCONTRADO')
+ if (!this.optionsDX.location.length) throw new Error('LOCATION_NO_ENCONTRADO')
+ if (!this.optionsDX.agentId.length) throw new Error('AGENTID_NO_ENCONTRADO')
const rawJson = readFileSync(GOOGLE_ACCOUNT_PATH, 'utf-8')
const { project_id, private_key, client_email } = JSON.parse(rawJson)
@@ -86,9 +84,7 @@ class DialogFlowCXContext extends CoreClass {
},
}
- const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [
- null,
- ]
+ const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [null]
const listMessages = single.queryResult.responseMessages.map((res) => {
if (res.message == 'text') {
@@ -96,17 +92,11 @@ class DialogFlowCXContext extends CoreClass {
}
if (res.message == 'payload') {
- const {
- media = null,
- buttons = [],
- answer = '',
- } = res.payload.fields
- const buttonsArray = buttons?.listValue?.values?.map(
- (btnValue) => {
- const { stringValue } = btnValue.structValue.fields.body
- return { body: stringValue }
- }
- )
+ const { media = null, buttons = [], answer = '' } = res.payload.fields
+ const buttonsArray = buttons?.listValue?.values?.map((btnValue) => {
+ const { stringValue } = btnValue.structValue.fields.body
+ return { body: stringValue }
+ })
return {
answer: answer?.stringValue,
options: {
diff --git a/packages/contexts/src/dialogflow-cx/index.js b/packages/contexts/src/dialogflow-cx/index.js
index 2a561c4d1..13c479e86 100644
--- a/packages/contexts/src/dialogflow-cx/index.js
+++ b/packages/contexts/src/dialogflow-cx/index.js
@@ -5,8 +5,7 @@ const DialogCXFlowClass = require('./dialogflow-cx.class')
* @param {*} args
* @returns
*/
-const createBotDialog = async ({ database, provider }, _options) =>
- new DialogCXFlowClass(database, provider, _options)
+const createBotDialog = async ({ database, provider }, _options) => new DialogCXFlowClass(database, provider, _options)
module.exports = {
createBotDialog,
diff --git a/packages/contexts/src/dialogflow/dialogflow.class.js b/packages/contexts/src/dialogflow/dialogflow.class.js
index 6a7cda08e..33df66b76 100644
--- a/packages/contexts/src/dialogflow/dialogflow.class.js
+++ b/packages/contexts/src/dialogflow/dialogflow.class.js
@@ -65,10 +65,7 @@ class DialogFlowContext extends CoreClass {
* para evitar este problema.
* https://github.com/codigoencasa/bot-whatsapp/pull/140
*/
- const session = this.sessionClient.projectAgentSessionPath(
- this.projectId,
- from
- )
+ const session = this.sessionClient.projectAgentSessionPath(this.projectId, from)
const reqDialog = {
session,
queryInput: {
@@ -79,15 +76,11 @@ class DialogFlowContext extends CoreClass {
},
}
- const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [
- null,
- ]
+ const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [null]
const { queryResult } = single
- const msgPayload = queryResult?.fulfillmentMessages?.find(
- (a) => a.message === 'payload'
- )
+ const msgPayload = queryResult?.fulfillmentMessages?.find((a) => a.message === 'payload')
// Revisamos si el dialogFlow tiene multimedia
if (msgPayload && msgPayload?.payload) {
diff --git a/packages/contexts/src/dialogflow/index.js b/packages/contexts/src/dialogflow/index.js
index e988f5057..377fd8813 100644
--- a/packages/contexts/src/dialogflow/index.js
+++ b/packages/contexts/src/dialogflow/index.js
@@ -5,8 +5,7 @@ const DialogFlowClass = require('./dialogflow.class')
* @param {*} args
* @returns
*/
-const createBotDialog = async ({ database, provider }) =>
- new DialogFlowClass(database, provider)
+const createBotDialog = async ({ database, provider }) => new DialogFlowClass(database, provider)
module.exports = {
createBotDialog,
diff --git a/packages/contexts/src/mock/index.js b/packages/contexts/src/mock/index.js
index b609be5b3..4e2e10fdd 100644
--- a/packages/contexts/src/mock/index.js
+++ b/packages/contexts/src/mock/index.js
@@ -5,8 +5,7 @@ const MockClass = require('./mock.class')
* @param {*} args
* @returns
*/
-const createBotMock = async ({ database, provider }) =>
- new MockClass(database, provider)
+const createBotMock = async ({ database, provider }) => new MockClass(database, provider)
module.exports = {
createBotMock,
diff --git a/packages/database/src/mock/index.js b/packages/database/src/mock/index.js
index 4c07c0361..2ab91a063 100644
--- a/packages/database/src/mock/index.js
+++ b/packages/database/src/mock/index.js
@@ -10,7 +10,10 @@ class MockDatabase {
constructor() {}
getPrevByNumber = (from) => {
- const history = this.listHistory.slice().reverse()
+ const history = this.listHistory
+ .slice()
+ .reverse()
+ .filter((i) => !!i.keyword)
return history.find((a) => a.from === from)
}
diff --git a/packages/database/src/mongo/index.js b/packages/database/src/mongo/index.js
index 6af68f0a5..9ea3fa5ed 100644
--- a/packages/database/src/mongo/index.js
+++ b/packages/database/src/mongo/index.js
@@ -24,12 +24,7 @@ class MongoAdapter {
}
getPrevByNumber = async (from) => {
- const result = await this.db
- .collection('history')
- .find({ from })
- .sort({ _id: -1 })
- .limit(1)
- .toArray()
+ const result = await this.db.collection('history').find({ from }).sort({ _id: -1 }).limit(1).toArray()
return result[0]
}
diff --git a/packages/database/src/mysql/index.js b/packages/database/src/mysql/index.js
index e01b55af0..0beea5678 100644
--- a/packages/database/src/mysql/index.js
+++ b/packages/database/src/mysql/index.js
@@ -46,18 +46,8 @@ class MyslAdapter {
})
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 ?'
+ 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
@@ -71,14 +61,14 @@ class MyslAdapter {
const tableName = 'history'
const sql = `CREATE TABLE ${tableName}
- (id INT AUTO_INCREMENT PRIMARY KEY,
- ref varchar(255) NOT NULL,
- keyword varchar(255) NOT NULL,
- answer longtext NOT NULL,
- refSerialize varchar(255) NOT NULL,
- phone varchar(255) NOT NULL,
- options longtext NOT NULL
- )`
+ (id INT AUTO_INCREMENT PRIMARY KEY,
+ ref varchar(255) NOT NULL,
+ keyword varchar(255) NOT NULL,
+ answer longtext NOT NULL,
+ refSerialize varchar(255) NOT NULL,
+ phone varchar(255) NOT NULL,
+ options longtext NOT NULL)
+ CHARACTER SET utf8mb4 COLLATE utf8mb4_General_ci`
this.db.query(sql, (err) => {
if (err) throw err
diff --git a/packages/docs/src/assets/fonts/generated/IBMPlexMono-Regular.module.css b/packages/docs/src/assets/fonts/generated/IBMPlexMono-Regular.module.css
index deddf7c37..f0ab1c083 100644
--- a/packages/docs/src/assets/fonts/generated/IBMPlexMono-Regular.module.css
+++ b/packages/docs/src/assets/fonts/generated/IBMPlexMono-Regular.module.css
@@ -8,6 +8,5 @@
font-family: IBMPlexMono-Regular;
src: url(IBMPlexMono-Regular-subset.woff2) format('woff2'),
url(IBMPlexMono-Regular-subset.zopfli.woff) format('woff');
- unicode-range: U+20, U+2C, U+2E, U+41-43, U+46, U+49, U+4B-4F, U+53-55, U+58,
- U+61-65, U+67-69, U+6C-76;
+ unicode-range: U+20, U+2C, U+2E, U+41-43, U+46, U+49, U+4B-4F, U+53-55, U+58, U+61-65, U+67-69, U+6C-76;
}
diff --git a/packages/docs/src/assets/fonts/generated/IBMPlexMono-SemiBold.module.css b/packages/docs/src/assets/fonts/generated/IBMPlexMono-SemiBold.module.css
index e2fdf72ee..6b47965f2 100644
--- a/packages/docs/src/assets/fonts/generated/IBMPlexMono-SemiBold.module.css
+++ b/packages/docs/src/assets/fonts/generated/IBMPlexMono-SemiBold.module.css
@@ -8,6 +8,6 @@
font-family: IBMPlexMono-SemiBold;
src: url(IBMPlexMono-SemiBold-subset.woff2) format('woff2'),
url(IBMPlexMono-SemiBold-subset.zopfli.woff) format('woff');
- unicode-range: U+20, U+24, U+2E, U+30, U+38, U+39, U+41, U+42, U+44, U+47,
- U+4E, U+4F, U+52-55, U+57, U+59, U+65, U+68, U+6F, U+72, U+74;
+ unicode-range: U+20, U+24, U+2E, U+30, U+38, U+39, U+41, U+42, U+44, U+47, U+4E, U+4F, U+52-55, U+57, U+59, U+65,
+ U+68, U+6F, U+72, U+74;
}
diff --git a/packages/docs/src/assets/fonts/generated/Pally-Variable.module.css b/packages/docs/src/assets/fonts/generated/Pally-Variable.module.css
index 74aa40038..e899bbf4e 100644
--- a/packages/docs/src/assets/fonts/generated/Pally-Variable.module.css
+++ b/packages/docs/src/assets/fonts/generated/Pally-Variable.module.css
@@ -6,9 +6,8 @@
@font-face {
font-family: Pally-Variable;
- src: url(Pally-Variable-subset.woff2) format('woff2'),
- url(Pally-Variable-subset.zopfli.woff) format('woff');
- unicode-range: U+20, U+24, U+2C, U+2E, U+30, U+33, U+39, U+41-43, U+46,
- U+49-4D, U+53, U+55, U+58, U+61-65, U+67-69, U+6B-77, U+79;
+ src: url(Pally-Variable-subset.woff2) format('woff2'), url(Pally-Variable-subset.zopfli.woff) format('woff');
+ unicode-range: U+20, U+24, U+2C, U+2E, U+30, U+33, U+39, U+41-43, U+46, U+49-4D, U+53, U+55, U+58, U+61-65, U+67-69,
+ U+6B-77, U+79;
font-weight: 400 700;
}
diff --git a/packages/docs/src/assets/fonts/generated/SourceSerifPro-Regular.module.css b/packages/docs/src/assets/fonts/generated/SourceSerifPro-Regular.module.css
index b1a323f55..a491d8c75 100644
--- a/packages/docs/src/assets/fonts/generated/SourceSerifPro-Regular.module.css
+++ b/packages/docs/src/assets/fonts/generated/SourceSerifPro-Regular.module.css
@@ -8,6 +8,5 @@
font-family: SourceSerifPro-Regular;
src: url(SourceSerifPro-Regular-subset.woff2) format('woff2'),
url(SourceSerifPro-Regular-subset.zopfli.woff) format('woff');
- unicode-range: U+20, U+2C, U+2E, U+41-44, U+49, U+4A, U+4C, U+53, U+55,
- U+61-65, U+67-69, U+6B-76, U+79;
+ unicode-range: U+20, U+2C, U+2E, U+41-44, U+49, U+4A, U+4C, U+53, U+55, U+61-65, U+67-69, U+6B-76, U+79;
}
diff --git a/packages/docs/src/assets/fonts/generated/Synonym-Variable.module.css b/packages/docs/src/assets/fonts/generated/Synonym-Variable.module.css
index b834dbb1c..00cb8dfd7 100644
--- a/packages/docs/src/assets/fonts/generated/Synonym-Variable.module.css
+++ b/packages/docs/src/assets/fonts/generated/Synonym-Variable.module.css
@@ -6,9 +6,8 @@
@font-face {
font-family: Synonym-Variable;
- src: url(Synonym-Variable-subset.woff2) format('woff2'),
- url(Synonym-Variable-subset.zopfli.woff) format('woff');
- unicode-range: U+20, U+24, U+2C, U+2E, U+30, U+33, U+35, U+41-44, U+46, U+47,
- U+49, U+4B-4F, U+53-55, U+57-59, U+61, U+63-65, U+67-69, U+6C-76;
+ src: url(Synonym-Variable-subset.woff2) format('woff2'), url(Synonym-Variable-subset.zopfli.woff) format('woff');
+ unicode-range: U+20, U+24, U+2C, U+2E, U+30, U+33, U+35, U+41-44, U+46, U+47, U+49, U+4B-4F, U+53-55, U+57-59, U+61,
+ U+63-65, U+67-69, U+6C-76;
font-weight: 400 700;
}
diff --git a/packages/docs/src/assets/fonts/generated/TenorSans-Regular.module.css b/packages/docs/src/assets/fonts/generated/TenorSans-Regular.module.css
index 819cfa3c9..b3dbfc6a6 100644
--- a/packages/docs/src/assets/fonts/generated/TenorSans-Regular.module.css
+++ b/packages/docs/src/assets/fonts/generated/TenorSans-Regular.module.css
@@ -6,8 +6,7 @@
@font-face {
font-family: TenorSans-Regular;
- src: url(TenorSans-Regular-subset.woff2) format('woff2'),
- url(TenorSans-Regular-subset.zopfli.woff) format('woff');
- unicode-range: U+20, U+24, U+2E, U+30, U+36, U+46, U+49, U+4A, U+53, U+54,
- U+61, U+63, U+65, U+69, U+6B, U+6E, U+6F, U+72-75, U+79;
+ src: url(TenorSans-Regular-subset.woff2) format('woff2'), url(TenorSans-Regular-subset.zopfli.woff) format('woff');
+ unicode-range: U+20, U+24, U+2E, U+30, U+36, U+46, U+49, U+4A, U+53, U+54, U+61, U+63, U+65, U+69, U+6B, U+6E, U+6F,
+ U+72-75, U+79;
}
diff --git a/packages/docs/src/components/atoms/DigitalOcean.tsx b/packages/docs/src/components/atoms/DigitalOcean.tsx
index dc1664709..fc97537db 100644
--- a/packages/docs/src/components/atoms/DigitalOcean.tsx
+++ b/packages/docs/src/components/atoms/DigitalOcean.tsx
@@ -56,10 +56,7 @@ export const DigitalOcean = () => (
h-3.1V2h3.2V14.9z M361.9,21.1v1.1c0,4.4,2.6,6.6,6.2,6.6c3.7,0,6.5-2.5,6.5-7.2c0-4.6-2.8-7.1-6.5-7.1
C364.5,14.5,361.9,16.8,361.9,21.1z"
/>
-
- El secreto es mantener los procesos repetitivos en - procesos automatizados simples, por eso te mostramos en - que destacamos. + El secreto es mantener los procesos repetitivos en procesos automatizados simples, por eso te + mostramos en que destacamos.
- {description} -
+{description}
- - Con esta libreria,{' '} - + Con esta libreria, - puedes configurar respuestas - automatizadas para preguntas frecuentes + puedes configurar respuestas automatizadas para preguntas frecuentes {' '} - , recibir y responder mensajes de manera - automatizada, y hacer un seguimiento de las - interacciones con los clientes. Además, - nuestro Chatbot se integra fácilmente con - otros sistemas y herramientas que ya esté - utilizando en su negocio. + , recibir y responder mensajes de manera automatizada, y hacer un seguimiento de las + interacciones con los clientes. Además, nuestro Chatbot se integra fácilmente con + otros sistemas y herramientas que ya esté utilizando en su negocio.
- Conviértete en un miembro destacado y forma parte del - proyecto y disfruta de manera adelantada de las - actualizaciones{' '} - + Conviértete en un miembro destacado y forma parte del proyecto y disfruta de manera adelantada + de las actualizaciones{' '} + Únete
diff --git a/packages/docs/src/components/widgets/NavBar.tsx b/packages/docs/src/components/widgets/NavBar.tsx index 56915c9ba..5b332bca1 100644 --- a/packages/docs/src/components/widgets/NavBar.tsx +++ b/packages/docs/src/components/widgets/NavBar.tsx @@ -5,55 +5,45 @@ import { DocumentationCtx } from '~/contexts' /** * options = [] array con la lista de opciones de la documentacion */ -export default component$( - ({ options = [] }: { options: DocumentationCtx[] }) => { - return ( -Downloads
Stars
Forks
Users
diff --git a/packages/docs/src/contexts/index.tsx b/packages/docs/src/contexts/index.tsx index 7282539a3..ca3349585 100644 --- a/packages/docs/src/contexts/index.tsx +++ b/packages/docs/src/contexts/index.tsx @@ -13,5 +13,4 @@ export interface User { avatar_url: string } -export const GlobalStore = - createContext- Unlike other frameworks, Qwik is resumable which means Qwik - applications require 0 hydration. This allows Qwik apps to have - instant-on interactivity, regardless of size or complexity + Unlike other frameworks, Qwik is resumable which means Qwik applications require 0 hydration. This allows + Qwik apps to have instant-on interactivity, regardless of size or complexity
- Qwik has unprecedented performance, offering sub-second full page - loads even on mobile devices. Qwik achieves this by delivering pure - HTML, and incrementally loading JS only as-needed. + Qwik has unprecedented performance, offering sub-second full page loads even on mobile devices. Qwik + achieves this by delivering pure HTML, and incrementally loading JS only as-needed.
- Con esta libreria, puedes configurar respuestas
- automatizadas para preguntas frecuentes, recibir y responder
- mensajes de manera automatizada, y hacer un seguimiento de
- las interacciones con los clientes.
Además, nuestro
- Chatbot se integra fácilmente con otros sistemas y
- herramientas que ya esté utilizando en su negocio.
+ Con esta libreria, puedes configurar respuestas automatizadas para preguntas frecuentes, recibir y
+ responder mensajes de manera automatizada, y hacer un seguimiento de las interacciones con los
+ clientes.
Además, nuestro Chatbot se integra fácilmente con otros sistemas y herramientas que
+ ya esté utilizando en su negocio.