diff --git a/.github/workflows/check-providers.yml b/.github/workflows/check-providers.yml deleted file mode 100644 index 9965606..0000000 --- a/.github/workflows/check-providers.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Rev Providers - -on: - pull_request: - branches: - - dev - -jobs: - check-npm: - name: Install Dependencies - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: 16.x - cache: 'yarn' - registry-url: https://registry.npmjs.org/ - - - run: corepack enable - - - name: Install NPM Dependencies - run: yarn install --immutable --network-timeout 300000 - - - name: Check Baileys - run: yarn node ./scripts/checker.js --name=baileys --stable=true - - - name: Check Venom - run: yarn node ./scripts/checker.js --name=venom --stable=true - - - name: Check web-whatsapp - run: yarn node ./scripts/checker.js --name=web-whatsapp --stable=true - - - name: Check Meta - run: yarn node ./scripts/checker.js --name=meta --stable=true - - - name: Check Twilio - run: yarn node ./scripts/checker.js --name=twilio --stable=true - - - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: 'ci(providers): πŸ‘ updated versions stable providers' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 86178fd..a1fed1b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,7 +13,7 @@ name: 'CodeQL' on: push: - branches: ['main', dev, next-release] + branches: [release/next] pull_request: # The branches below must be a subset of the branches above branches: ['main'] @@ -22,6 +22,7 @@ on: jobs: analyze: + if: ${{ !github.event.act }} name: Analyze runs-on: ubuntu-latest permissions: diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml index 4f3d94e..b126e98 100644 --- a/.github/workflows/contributors.yml +++ b/.github/workflows/contributors.yml @@ -1,8 +1,8 @@ name: Revisando Colaboradores + on: - push: - branches: - - main + schedule: + - cron: '0 9 * * *' jobs: contrib-readme-job: diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index e3e8200..1820da5 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -13,6 +13,7 @@ on: jobs: ############ DOCUMENTATION BUILD ############ build-documentation: + if: ${{ !github.event.act }} name: Build Package runs-on: ubuntu-latest diff --git a/.github/workflows/netlify.yml b/.github/workflows/netlify.yml index 8f1ba08..2dac101 100644 --- a/.github/workflows/netlify.yml +++ b/.github/workflows/netlify.yml @@ -7,7 +7,7 @@ on: jobs: ############ DOCUMENTATION BUILD ############ - build-documentation: + build-documentation-prod: name: Build Package runs-on: ubuntu-latest diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index 72f0c48..d587c64 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -6,7 +6,8 @@ on: - release/production jobs: ############ RELEASE ############ - release: + release-prod: + if: ${{ !github.event.act }} name: Release runs-on: ubuntu-latest steps: @@ -66,8 +67,13 @@ jobs: - name: Release Github run: yarn node ./scripts/github.js --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.OCTO_TOKEN }}" - - name: GIT commit and push all changed files - if: github.event_name == 'push' + - name: 'Run if changes have been detected' run: | - git commit -a -m 'chore(version): launch release πŸš€ "${{ steps.package-version.outputs.current-version}}"' - git push + git add . + git commit -m "chore(version): pre release" + + - name: Commit Versioning & Push changes + if: github.event_name == 'push' + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: 'chore(version): launch release πŸš€ "${{ steps.package-version.outputs.current-version}}"' diff --git a/.gitignore b/.gitignore index 721d12c..1cc3038 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ yarn-error.log .npmrc # Local Netlify folder .netlify +.secrets \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 023883a..48381f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ 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.16](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.15...v0.1.16) (2023-01-11) + +### [0.1.15](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.14...v0.1.15) (2023-01-11) + +### [0.1.14](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.13...v0.1.14) (2023-01-11) + ### [0.1.13](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.12...v0.1.13) (2023-01-11) ### [0.1.12](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.10...v0.1.12) (2023-01-11) diff --git a/package.json b/package.json index 07bc07d..a6e64e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bot-whatsapp/root", - "version": "0.1.13", + "version": "0.1.16", "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 4243713..79d996b 100644 --- a/packages/bot/core/core.class.js +++ b/packages/bot/core/core.class.js @@ -8,6 +8,9 @@ const { createWriteStream } = require('fs') const logger = new Console({ stdout: createWriteStream(`${process.cwd()}/core.class.log`), }) + +const QueuePrincipal = new Queue() + /** * [ ] Escuchar eventos del provider asegurarte que los provider emitan eventos * [ ] Guardar historial en db @@ -84,20 +87,40 @@ class CoreClass { this.databaseClass.save(ctxByNumber) } + // πŸ“„ Esta funcion se encarga de enviar un array de mensajes dentro de este ctx + const sendFlow = async (messageToSend, numberOrId) => { + const queue = [] + for (const ctxMessage of messageToSend) { + const delayMs = ctxMessage?.options?.delay || 0 + if (delayMs) await delay(delayMs) + QueuePrincipal.enqueue(() => + Promise.all([ + this.sendProviderAndSave(numberOrId, ctxMessage), + resolveCbEveryCtx(ctxMessage), + ]) + ) + } + return Promise.all(queue) + } + // πŸ“„ [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje - const fallBack = () => { + const fallBack = async () => { fallBackFlag = true - msgToSend = this.flowClass.find(refToContinue?.keyword, true) || [] - this.sendFlow(msgToSend, from) + await this.sendProviderAndSave(from, refToContinue) + QueuePrincipal.queue = [] return refToContinue } // πŸ“„ [options: flowDynamic]: esta funcion se encarga de responder un array de respuesta esta limitado a 5 mensajes // para evitar bloque de whatsapp - const flowDynamic = (listMsg = [], optListMsg = { limit: 3 }) => { + const flowDynamic = async ( + listMsg = [], + optListMsg = { limit: 5, fallback: false } + ) => { if (!Array.isArray(listMsg)) throw new Error('Esto debe ser un ARRAY') + fallBackFlag = optListMsg.fallback const parseListMsg = listMsg .map(({ body }, index) => toCtx({ @@ -108,26 +131,38 @@ class CoreClass { }) ) .slice(0, optListMsg.limit) - msgToSend = parseListMsg - this.sendFlow(msgToSend, from) + for (const msg of parseListMsg) { + await this.sendProviderAndSave(from, msg) + } return } + // πŸ“„ Se encarga de revisar si el contexto del mensaje tiene callback o fallback + const resolveCbEveryCtx = async (ctxMessage) => { + if (prevMsg?.options?.capture) return cbEveryCtx(prevMsg?.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 = (inRef) => { - this.flowClass.allCallbacks[inRef](messageCtxInComming, { + const cbEveryCtx = async (inRef) => { + if (!this.flowClass.allCallbacks[inRef]) return Promise.resolve() + return this.flowClass.allCallbacks[inRef](messageCtxInComming, { fallBack, flowDynamic, }) } + if (prevMsg?.ref) resolveCbEveryCtx(prevMsg) + // πŸ“„ [options: callback]: Si se tiene un callback se ejecuta - if (!fallBackFlag) { - if (prevMsg?.options?.capture) cbEveryCtx(prevMsg?.ref) - for (const ite of this.flowClass.find(body)) { - if (!ite?.options?.capture) cbEveryCtx(ite?.ref) - } - } + //TODO AQUI + // if (!fallBackFlag) { + // if (prevMsg?.options?.capture) cbEveryCtx(prevMsg?.ref) + // for (const ite of this.flowClass.find(body)) { + // if (!ite?.options?.capture) cbEveryCtx(ite?.ref) + // } + // } // πŸ“„πŸ€˜(tiene return) [options: nested(array)]: Si se tiene flujos hijos los implementa if (!fallBackFlag && prevMsg?.options?.nested?.length) { @@ -138,11 +173,12 @@ class CoreClass { msgToSend = this.flowClass.find(body, false, flowStandalone) || [] - for (const ite of msgToSend) { - cbEveryCtx(ite?.ref) - } + // //TODO AQUI + // for (const ite of msgToSend) { + // cbEveryCtx(ite?.ref) + // } - this.sendFlow(msgToSend, from) + sendFlow(msgToSend, from) return } @@ -153,13 +189,13 @@ class CoreClass { if (['string', 'boolean'].includes(typeCapture) && valueCapture) { msgToSend = this.flowClass.find(refToContinue?.ref, true) || [] - this.sendFlow(msgToSend, from) + sendFlow(msgToSend, from) return } } msgToSend = this.flowClass.find(body) || [] - this.sendFlow(msgToSend, from) + sendFlow(msgToSend, from) } /** @@ -176,18 +212,6 @@ class CoreClass { ]) } - sendFlow = async (messageToSend, numberOrId) => { - const queue = [] - for (const ctxMessage of messageToSend) { - const delayMs = ctxMessage?.options?.delay || 0 - if (delayMs) await delay(delayMs) - Queue.enqueue(() => - this.sendProviderAndSave(numberOrId, ctxMessage) - ) - } - return Promise.all(queue) - } - /** * @private * @param {*} message diff --git a/packages/bot/package.json b/packages/bot/package.json index 44ebca0..f8c71c4 100644 --- a/packages/bot/package.json +++ b/packages/bot/package.json @@ -1,6 +1,6 @@ { "name": "@bot-whatsapp/bot", - "version": "0.0.55-alpha.0", + "version": "0.0.62-alpha.0", "description": "", "main": "./lib/bundle.bot.cjs", "scripts": { diff --git a/packages/bot/rollup-bot.config.js b/packages/bot/rollup-bot.config.js index f8ffa2a..36bbb87 100644 --- a/packages/bot/rollup-bot.config.js +++ b/packages/bot/rollup-bot.config.js @@ -10,6 +10,7 @@ module.exports = [ banner: banner['banner.output'].join(''), file: join(__dirname, 'lib', 'bundle.bot.cjs'), format: 'cjs', + sourcemap: true, }, plugins: [commonjs(), nodeResolve()], }, diff --git a/packages/bot/utils/queue.js b/packages/bot/utils/queue.js index 1f610e9..873024a 100644 --- a/packages/bot/utils/queue.js +++ b/packages/bot/utils/queue.js @@ -1,8 +1,8 @@ class Queue { - static queue = [] - static pendingPromise = false + queue = [] + pendingPromise = false - static enqueue(promise) { + enqueue(promise) { return new Promise((resolve, reject) => { this.queue.push({ promise, @@ -13,7 +13,7 @@ class Queue { }) } - static dequeue() { + dequeue() { if (this.workingOnPromise) { return false } diff --git a/packages/cli/package.json b/packages/cli/package.json index 6f04765..6cdd841 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@bot-whatsapp/cli", - "version": "0.0.61-alpha.0", + "version": "0.0.68-alpha.0", "description": "", "main": "index.js", "devDependencies": { diff --git a/packages/contexts/package.json b/packages/contexts/package.json index 7f0f0a8..e1497ba 100644 --- a/packages/contexts/package.json +++ b/packages/contexts/package.json @@ -1,6 +1,6 @@ { "name": "@bot-whatsapp/contexts", - "version": "0.0.5-alpha.0", + "version": "0.0.12-alpha.0", "description": "", "main": "./lib/bundle.contexts.cjs", "files": [ diff --git a/packages/create-bot-whatsapp/package.json b/packages/create-bot-whatsapp/package.json index b6cf5b4..62e0a29 100644 --- a/packages/create-bot-whatsapp/package.json +++ b/packages/create-bot-whatsapp/package.json @@ -1,6 +1,6 @@ { "name": "create-bot-whatsapp", - "version": "0.0.72-alpha.0", + "version": "0.0.79-alpha.0", "description": "", "main": "./lib/bundle.create-bot-whatsapp.cjs", "files": [ diff --git a/packages/database/package.json b/packages/database/package.json index 3d745a8..f1f58cc 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -1,6 +1,6 @@ { "name": "@bot-whatsapp/database", - "version": "0.0.53-alpha.0", + "version": "0.0.60-alpha.0", "description": "Esto es el conector a mysql, pg, mongo", "main": "./lib/mock/index.cjs", "keywords": [], diff --git a/packages/docs/src/routes/docs/flows/index.mdx b/packages/docs/src/routes/docs/flows/index.mdx index 027c793..7a2171c 100644 --- a/packages/docs/src/routes/docs/flows/index.mdx +++ b/packages/docs/src/routes/docs/flows/index.mdx @@ -1,6 +1,6 @@ import Navigation from '../../../components/widgets/Navigation' -# Flow (Flujos) +# Flow Los flujos hace referencia al hecho de construir un flujo de conversion. Esto es un flow podemos observar que estan presente dos metodos importantes **addKeyword** y el **addAnswer**. @@ -23,6 +23,142 @@ const flowPrincipal = addKeyword(['hola', 'alo']) --- +## addKeyword() + +Esta funcion se utliza para iniciar un flujo de conversion.
Recibe un `string` o un `array` +de string `['hola','buenas']`. + +**Opciones** + +- sensitive: Sensible a mayusculas y minusculas por defecto `false` + +```js +const { addKeyword } = require('@bot-whatsapp/bot') + +const flowString = addKeyword('hola') + +const flowArray = addKeyword(['hola', 'alo']) + +const flowSensitive = addKeyword(['hola', 'alo'], { + sensitive: true, +}) +``` + +--- + +## addAnswer() + +Esta funcion se utliza para responder un mensaje despues del `addKeyword()` + +**Opciones** + +- delay: 0 (milisegundos) +- media: url de imagen +- buttons: array `[{body:'Boton1'}, {body:'Boton2'}, {body:'Boton3'}]` +- capture: false (para esperar respuesta) +- child: Objecto tipo flujo o arra de flujos hijos + +```js +const { addKeyword } = require('@bot-whatsapp/bot') + +const flowString = addKeyword('hola').addAnswer( + 'Este mensaje se enviara 1 segundo despues', + { + delay: 1000, + } +) + +const flowString = addKeyword('hola').addAnswer( + 'Este mensaje envia una imagen', + { + media: 'https://i.imgur.com/0HpzsEm.png', + } +) + +const flowString = addKeyword('hola').addAnswer( + 'Este mensaje envia tres botones', + { + buttons: [ + { body: 'Boton 1' }, + { body: 'Boton 2' }, + { body: 'Boton 3' }, + ], + } +) + +const flowString = addKeyword('hola').addAnswer( + 'Este mensaje espera una respueta del usuario', + { + capture: true, + } +) +``` + +--- + +## ctx + +Este argumento se utiliza para obtener el contexto de la conversaciΓ³n + +```js +const { addKeyword } = require('@bot-whatsapp/bot') + +const flowString = addKeyword('hola').addAnswer( + 'Indica cual es tu email', + null, + (ctx) => { + console.log('πŸ‘‰ Informacion del contexto: ', ctx) + } +) +``` + +--- + +## fallBack() + +Esta funcion se utliza para volver a enviar el ultimo mensaje abajo un ejemplo. +En el ejemplo de abajo esperamos que el usuario ingrese un mensaje que contenga `@` sino contiene +se repetira el mensaje `Indica cual es tu email` + +```js +const { addKeyword } = require('@bot-whatsapp/bot') + +const flowString = addKeyword('hola').addAnswer( + 'Indica cual es tu email', + null, + (ctx, { fallBack }) => { + if (!ctx.body.includes('@')) return fallBack() + } +) +``` + +--- + +## flowDynamic() + +Esta funcion se utliza para devolver mensajes dinamicos que pueden venir de una API o Base de datos. +La funcion recibe un array que debe contener la siguiente estrucutura: + +`[{body:'Mensaje}, {body:'Mensaje2}]` + +```js +const { addKeyword } = require('@bot-whatsapp/bot') + +const flowString = addKeyword('hola') + .addAnswer('Indica cual es tu email', null, async (ctx, {flowDynamic}) => { + const mensajesDB = () => { + const categories = db.find(...) + const mapDatos = categories.map((c) => ({body:c.name})) + return mapDatos + } + await flowDynamic(mensajesDB()) + }) + + +``` + +--- +