mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-20 20:49:15 +00:00
Compare commits
1 Commits
contributo
...
feat/docs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c8742735c |
@@ -1,2 +1 @@
|
||||
packages/docs/*
|
||||
packages/portal/*
|
||||
7
.github/FUNDING.yml
vendored
7
.github/FUNDING.yml
vendored
@@ -1,4 +1,9 @@
|
||||
# These are supported funding model platforms
|
||||
open_collective: bot-whatsapp
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: leifermendez
|
||||
open_collective: bot-whatsapp
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
custom: https://www.buymeacoffee.com/leifermendez
|
||||
|
||||
58
.github/ISSUE_TEMPLATE/bug.yml
vendored
58
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -1,58 +0,0 @@
|
||||
name: 🐛 Reporte Bug
|
||||
description: Algo no va bien?. Hazlo saber
|
||||
labels: [bug, triage]
|
||||
title: '[🐛]'
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Gracias por tomarte el tiempo de reportar este problema
|
||||
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: ¿Que versión estas usando?
|
||||
description: '__INFO:__ Recuerda que puedes consultar dudas directamente en [discord](https://link.codigoencasa.com/DISCORD)'
|
||||
options:
|
||||
- v2
|
||||
- v1
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: component
|
||||
attributes:
|
||||
label: ¿Sobre que afecta?
|
||||
options:
|
||||
- Flujo de palabras (Flow)
|
||||
- DialogFlow
|
||||
- Base de datos
|
||||
- Otro
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
description: 'Trata de ser lo más claro posible, de esa manera podemos entender el contexto de tu problema y darte una mejor solución'
|
||||
label: Describe tu problema
|
||||
placeholder: Yo tengo un problema....
|
||||
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Reproducir error
|
||||
description: __(Recomendación)__ trata de grabar un video puedes usar algunas de las siguientes herramientas [https://www.vidyard.com/](https://www.vidyard.com/) [https://www.loom.com/](https://www.loom.com/) y en lo posbile apoyate en [https://stackblitz.com/](https://stackblitz.com/) para compartir el código de ser necesario
|
||||
placeholder: URL video o stackblitz
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: additional_information
|
||||
attributes:
|
||||
label: Información Adicional
|
||||
validations:
|
||||
required: false
|
||||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,4 +0,0 @@
|
||||
contact_links:
|
||||
- name: 🤔 Core Team
|
||||
url: https://link.codigoencasa.com/DISCORD
|
||||
about: Si quieres formar parte del CoreTeam, patrocinar el proyecto o propuesta profesionales
|
||||
79
.github/ISSUE_TEMPLATE/test-case.yml
vendored
79
.github/ISSUE_TEMPLATE/test-case.yml
vendored
@@ -1,79 +0,0 @@
|
||||
name: 🐬 Caso de uso
|
||||
description: Reporta tu caso de uso y cuales fueron tus resultados
|
||||
labels: [usecase]
|
||||
title: '[🐬]'
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Gracias por tomarte el tiempo de detallar este caso de uso, sera de gran utilidad para mantener un software de calidad puedes comenzar
|
||||
⚡ `npm create bot-whatsapp@dev`
|
||||
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: ¿Cual proveedor usaste?
|
||||
description: 'Actualmente tenemos varios proveedores que sirven como punto de entrada y salida con Whatsapp'
|
||||
options:
|
||||
- whatsapp-web.js
|
||||
- venom
|
||||
- bailey
|
||||
- twilio
|
||||
- meta
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: component
|
||||
attributes:
|
||||
label: ¿Cual base de datos usaste?
|
||||
options:
|
||||
- memory
|
||||
- mongo
|
||||
- mysql
|
||||
- json
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: result
|
||||
attributes:
|
||||
label: Conclusion de la prueba
|
||||
options:
|
||||
- muy buena
|
||||
- buena
|
||||
- tiene errores
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
description: 'Trata de ser lo más claro posible, de esa manera podemos entender el contexto del caso de uso'
|
||||
label: Describe tu caso
|
||||
placeholder: Yo tengo un caso....
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: ¿Logs Importantes?
|
||||
description: Si tienes algunos logs importantes a tener en cuenta o que muetren algun error en concreto.
|
||||
render: shell
|
||||
|
||||
- type: textarea
|
||||
id: additional_information
|
||||
attributes:
|
||||
label: Información Adicional
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
id: usernames
|
||||
attributes:
|
||||
label: ¿Quieres que te mencionemos?
|
||||
description: Siempre buscamos fomentar la comunidad por lo cual si quieres que te mencionemos publicamente en nuestras redes sociales puedes dejar tu username
|
||||
placeholder: twitter o github o instagram o alguna url
|
||||
validations:
|
||||
required: false
|
||||
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,17 +0,0 @@
|
||||
# Que tipo de Pull Request es?
|
||||
|
||||
- [ ] Mejoras
|
||||
- [ ] Bug
|
||||
- [ ] Docs / tests
|
||||
|
||||
# Descripción
|
||||
|
||||
Por favor agrega una descripción de tu aporte para tener más contexto y poder avanzar más rápido. Si es de ayuda puedes usar plataformar como [https://www.loom.com/](https://www.loom.com/) para grabar un video.
|
||||
|
||||
|
||||
> Forma parte de este proyecto.
|
||||
|
||||
- [Discord](https://link.codigoencasa.com/DISCORD)
|
||||
- [Twitter](https://twitter.com/leifermendez)
|
||||
- [Youtube](https://www.youtube.com/watch?v=5lEMCeWEJ8o&list=PL_WGMLcL4jzWPhdhcUyhbFU6bC0oJd2BR)
|
||||
- [Telegram](https://t.me/leifermendez)
|
||||
52
.github/workflows/check-provider-major.yml
vendored
52
.github/workflows/check-provider-major.yml
vendored
@@ -1,52 +0,0 @@
|
||||
name: Rev Major Providers
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 9 * * *'
|
||||
|
||||
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
|
||||
|
||||
- name: Add and commit changes to gh-pages branch
|
||||
run: |
|
||||
git config --local user.email 'action@github.com'
|
||||
git config --local user.name 'GitHub Action'
|
||||
git add .
|
||||
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
commit_message: 'ci(providers): check provider versions'
|
||||
create_branch: true
|
||||
branch: feature/providers-major
|
||||
56
.github/workflows/ci.yml
vendored
56
.github/workflows/ci.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Build and Test
|
||||
name: BotWhatsapp Build-Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Build Package
|
||||
run: yarn build:full
|
||||
run: yarn build
|
||||
|
||||
- name: Build Eslint rules
|
||||
run: yarn lint:fix
|
||||
@@ -56,55 +56,3 @@ jobs:
|
||||
|
||||
- name: Unit Tests
|
||||
run: yarn test
|
||||
|
||||
############ UNIT TEST ############
|
||||
check-providers:
|
||||
name: Check Providers Versions
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
commit: ${{ steps.vars.outputs.commit }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{github.event.after}}
|
||||
persist-credentials: false
|
||||
|
||||
- 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
|
||||
|
||||
- name: Set output
|
||||
id: vars
|
||||
run: echo "commit=$(git log --format=%B -n 1 ${{github.event.after}})" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Commit & Push changes
|
||||
uses: actions-js/push@master
|
||||
with:
|
||||
branch: feature/providers-major
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
force: true
|
||||
|
||||
76
.github/workflows/codeql.yml
vendored
76
.github/workflows/codeql.yml
vendored
@@ -1,76 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: 'CodeQL'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [release/next]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: ['main']
|
||||
schedule:
|
||||
- cron: '21 16 * * 5'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
if: ${{ !github.event.act }}
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: ['javascript']
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: '/language:${{matrix.language}}'
|
||||
10
.github/workflows/contributors.yml
vendored
10
.github/workflows/contributors.yml
vendored
@@ -1,8 +1,10 @@
|
||||
name: Revisando Colaboradores
|
||||
|
||||
name: Add contributors
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 9 * * *'
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
- main
|
||||
types: [closed]
|
||||
|
||||
jobs:
|
||||
contrib-readme-job:
|
||||
|
||||
47
.github/workflows/netlify-dev.yml
vendored
47
.github/workflows/netlify-dev.yml
vendored
@@ -1,47 +0,0 @@
|
||||
name: 📄 Desplegando documentacion
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- 'feat/docs-**'
|
||||
- 'fix/docs-**'
|
||||
push:
|
||||
branches:
|
||||
- 'feat/docs-**'
|
||||
- 'fix/docs-**'
|
||||
|
||||
jobs:
|
||||
############ DOCUMENTATION BUILD ############
|
||||
build-documentation:
|
||||
if: ${{ !github.event.act }}
|
||||
name: Build Package
|
||||
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: Add netlify
|
||||
run: yarn add netlify-cli -D
|
||||
|
||||
- name: Create .env build file
|
||||
run: |
|
||||
touch packages/docs/.env
|
||||
echo VITE_GITHUB_TOKEN=${{ secrets.COLLABORATORS_TOKEN }} >> packages/docs/.env
|
||||
|
||||
- name: Build and Deploy
|
||||
run: |
|
||||
cd packages/docs
|
||||
netlify deploy --build --site ${{ secrets.NETLIFY_SITE_ID }} --auth ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
41
.github/workflows/netlify.yml
vendored
41
.github/workflows/netlify.yml
vendored
@@ -1,41 +0,0 @@
|
||||
name: 📄 (PROD) Desplegando documentacion
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- release/next
|
||||
|
||||
jobs:
|
||||
############ DOCUMENTATION BUILD ############
|
||||
build-documentation-prod:
|
||||
name: Build Package
|
||||
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: Add netlify
|
||||
run: yarn add netlify-cli -D
|
||||
|
||||
- name: Create .env build file
|
||||
run: |
|
||||
touch packages/docs/.env
|
||||
echo VITE_GITHUB_TOKEN=${{ secrets.COLLABORATORS_TOKEN }} >> packages/docs/.env
|
||||
|
||||
- name: Build and Deploy
|
||||
run: |
|
||||
cd packages/docs
|
||||
netlify deploy --prod --build --site ${{ secrets.NETLIFY_SITE_ID }} --auth ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
24
.github/workflows/releases-dev.yml
vendored
24
.github/workflows/releases-dev.yml
vendored
@@ -1,24 +1,22 @@
|
||||
name: 🚀 (DEV) Liberando versiones
|
||||
name: BotWhatsapp Releases(DEV)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- release/next
|
||||
- next-release
|
||||
|
||||
jobs:
|
||||
############ RELEASE ############
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
commit: ${{ steps.vars.outputs.commit }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{github.event.after}}
|
||||
ref: ${{ github.head_ref }}
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
@@ -33,7 +31,7 @@ jobs:
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Build Package
|
||||
run: yarn build:full
|
||||
run: yarn build
|
||||
|
||||
- name: Release @bot-whatsapp/bot
|
||||
run: yarn node ./scripts/release.js --name=bot --version= --token="${{ secrets.NPM_TOKEN }}"
|
||||
@@ -50,15 +48,9 @@ jobs:
|
||||
- name: Release @bot-whatsapp/provider
|
||||
run: yarn node ./scripts/release.js --name=provider --version= --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Release @bot-whatsapp/contexts
|
||||
run: yarn node ./scripts/release.js --name=contexts --version= --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Release @bot-whatsapp/portal
|
||||
run: yarn node ./scripts/release.js --name=portal --version= --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Commit & Push changes
|
||||
- name: Commit Versioning & Push changes
|
||||
uses: actions-js/push@master
|
||||
with:
|
||||
branch: release/next
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
force: true
|
||||
message: 'ci(version): :zap: automatic - "${date}" updated versions every packages'
|
||||
branch: 'dev'
|
||||
|
||||
51
.github/workflows/releases.yml
vendored
51
.github/workflows/releases.yml
vendored
@@ -1,18 +1,22 @@
|
||||
name: 🚀⚡ Liberando versiones
|
||||
name: BotWhatsapp Releases(Prod)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- release/production
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
|
||||
jobs:
|
||||
############ RELEASE ############
|
||||
release-prod:
|
||||
if: ${{ !github.event.act }}
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set output
|
||||
id: vars
|
||||
@@ -27,49 +31,30 @@ jobs:
|
||||
|
||||
- run: corepack enable
|
||||
|
||||
- name: Set User
|
||||
run: git config --global user.email "leifer.contacto@gmail.com" && git config --global user.name "Leifer Mendez"
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Set CHANGELOG
|
||||
run: yarn release
|
||||
|
||||
- name: get-npm-version
|
||||
id: package-version
|
||||
uses: martinbeentjes/npm-get-version-action@main
|
||||
|
||||
- name: Build Package
|
||||
run: yarn build:full
|
||||
run: yarn build
|
||||
|
||||
- name: Release @bot-whatsapp/bot
|
||||
run: yarn node ./scripts/release.js --name=bot --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
run: yarn node ./scripts/release.js --name=bot --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Release @bot-whatsapp/cli
|
||||
run: yarn node ./scripts/release.js --name=cli --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
run: yarn node ./scripts/release.js --name=cli --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Release @bot-whatsapp/create-bot-whatsapp
|
||||
run: yarn node ./scripts/release.js --name=create-bot-whatsapp --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
run: yarn node ./scripts/release.js --name=create-bot-whatsapp --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Release @bot-whatsapp/database
|
||||
run: yarn node ./scripts/release.js --name=database --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
run: yarn node ./scripts/release.js --name=database --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Release @bot-whatsapp/provider
|
||||
run: yarn node ./scripts/release.js --name=provider --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
run: yarn node ./scripts/release.js --name=provider --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Release @bot-whatsapp/contexts
|
||||
run: yarn node ./scripts/release.js --name=contexts --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Release @bot-whatsapp/portal
|
||||
run: yarn node ./scripts/release.js --name=portal --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
||||
|
||||
- name: Release Github
|
||||
run: yarn node ./scripts/github.js --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.OCTO_TOKEN }}"
|
||||
|
||||
- name: Commit & Push changes
|
||||
- name: Commit Versioning & Push changes
|
||||
uses: actions-js/push@master
|
||||
with:
|
||||
branch: release/production
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
force: true
|
||||
message: 'ci(version): :zap: automatic - "${date}" updated versions every packages'
|
||||
branch: 'dev'
|
||||
|
||||
27
.github/workflows/stale.yml
vendored
27
.github/workflows/stale.yml
vendored
@@ -1,27 +0,0 @@
|
||||
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||
#
|
||||
# You can adjust the behavior by modifying this file.
|
||||
# For more information, see:
|
||||
# https://github.com/actions/stale
|
||||
name: Revisar ISSUES abandonadas
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '55 22 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: '¿Alguna novedad sobre esta ISSUE?'
|
||||
stale-pr-message: '¿Alguna novedad sobre esta PULL REQUEST?'
|
||||
stale-issue-label: 'no-issue-activity'
|
||||
stale-pr-label: 'no-pr-activity'
|
||||
exempt-issue-assignees: 'leifermendez'
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,5 +1,4 @@
|
||||
/node_modules
|
||||
/packages/repl
|
||||
/packages/*/starters
|
||||
/packages/*/node_modules
|
||||
/packages/*/dist
|
||||
@@ -15,10 +14,6 @@ mediaSend/*
|
||||
!mediaSend/nota-de-voz.mp3
|
||||
.env
|
||||
.wwebjs_auth
|
||||
/session
|
||||
/session/*
|
||||
/tokens
|
||||
/tokens/*
|
||||
packages/cli/config.json
|
||||
config.json
|
||||
.yarnrc.yml
|
||||
@@ -41,6 +36,3 @@ qr.svg
|
||||
package-lock.json
|
||||
yarn-error.log
|
||||
.npmrc
|
||||
# Local Netlify folder
|
||||
.netlify
|
||||
.secrets
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npm run lint:fix && npx --no -- commitlint --edit
|
||||
npx --no -- commitlint --edit
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
packages/**/lib
|
||||
packages/docs/
|
||||
packages/docs/*.json
|
||||
**/.git
|
||||
**/.svn
|
||||
**/.hg
|
||||
|
||||
@@ -2,6 +2,5 @@
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 4,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"printWidth": 120
|
||||
"singleQuote": true
|
||||
}
|
||||
|
||||
24
.vscode/bot.code-snippets
vendored
24
.vscode/bot.code-snippets
vendored
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"Flow Bot (simple)": {
|
||||
"scope": "javascript",
|
||||
"prefix": "bot:flow",
|
||||
"description": "Crear un flujo simple",
|
||||
"body": [
|
||||
"export const flow${1} = addKeyword(['hola', 'buenas'])",
|
||||
" .addAnswer('Hola! 🚀 Bienvenido a este CHATBOT')",
|
||||
" .addAnswer('¿Como puedo ayudarte?')"
|
||||
]
|
||||
},
|
||||
"Flow Bot (completo)": {
|
||||
"scope": "javascript",
|
||||
"prefix": "bot:flow completo",
|
||||
"description": "Crear un flujo completo",
|
||||
"body": [
|
||||
"export const flow${1} = addKeyword(['categorias'])",
|
||||
" .addAnswer('⚡ Tenemos las siguientes categorias')",
|
||||
" .addAnswer(['🚀 Computadoras', '🚀 Celulares', '🚀 Otros'], {",
|
||||
" delay: 1500, //Milisegundo 1500 = 1.5segundos",
|
||||
"})"
|
||||
]
|
||||
}
|
||||
}
|
||||
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"recommendations": ["xyc.vscode-mdx-preview", "vivaxy.vscode-conventional-commits", "mhutchie.git-graph"]
|
||||
}
|
||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -7,8 +7,6 @@
|
||||
"provider",
|
||||
"adapter",
|
||||
"ci",
|
||||
"starters",
|
||||
"conflict",
|
||||
"contexts"
|
||||
"starters"
|
||||
]
|
||||
}
|
||||
|
||||
300
CHANGELOG.md
300
CHANGELOG.md
@@ -2,306 +2,6 @@
|
||||
|
||||
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)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* :fire: bailey add media ([eab39e4](https://github.com/leifermendez/bot-whatsapp/commit/eab39e4ac06fd46f1a4671f8c15d1456b4400b97))
|
||||
* :zap: more feature ([e19c3a2](https://github.com/leifermendez/bot-whatsapp/commit/e19c3a25a40259c74b4add9635af4844907eed26))
|
||||
* **provider:** :rocket: fix issues in providers venom and wwebjs ([cbe438b](https://github.com/leifermendez/bot-whatsapp/commit/cbe438b77854e8df48b9dafaf7a837d21124ac5f))
|
||||
* **provider:** :rocket: fix provider ([0ad4c58](https://github.com/leifermendez/bot-whatsapp/commit/0ad4c58457b548dc41c0f9e8470d59c48de7b95a))
|
||||
* **provider:** :rocket: fix provider ([f8c7184](https://github.com/leifermendez/bot-whatsapp/commit/f8c7184487065443ab10f77aaf585e8bd63ca441))
|
||||
* **provider:** :rocket: fix provider ([b2afa45](https://github.com/leifermendez/bot-whatsapp/commit/b2afa45352a7ab1f5d9775f3c1fde475bd8ca204))
|
||||
* **provider:** :rocket: fix provider venom and wwebjs ([dcb0566](https://github.com/leifermendez/bot-whatsapp/commit/dcb0566d2bc3da40cd0c71554bb5ea0ec115d9ca))
|
||||
* **provider:** :rocket: implements all send media to venom provider ([9dd7c02](https://github.com/leifermendez/bot-whatsapp/commit/9dd7c02b6a5474aff063f7d6be0ca8519504b93c))
|
||||
* **provider:** :rocket: send file wwebjs ([6ff1a3a](https://github.com/leifermendez/bot-whatsapp/commit/6ff1a3a980196c01c66ed04ee07d0e7e57256504))
|
||||
* **provider:** :zap: bailey add send file video audio ([14d1a61](https://github.com/leifermendez/bot-whatsapp/commit/14d1a61fa259c09135c37c55bd79e97c9c8367e4))
|
||||
* **provider:** :zap: venom wweb ([fd2847a](https://github.com/leifermendez/bot-whatsapp/commit/fd2847aea0db17a0bdf33b5bca67a4cb8db2da16))
|
||||
* **provider:** :zap: venom wweb ([f95331d](https://github.com/leifermendez/bot-whatsapp/commit/f95331d3dc70e76a3dfbe4c8d24059f0e7a164ef))
|
||||
* **provider:** 🚀 implements all send media to venom provider ([bd7d150](https://github.com/leifermendez/bot-whatsapp/commit/bd7d150c047af41fdbb47f0a50a21e82cd79ee85))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bot:** :fire: endFlow with ctx ([f6114af](https://github.com/leifermendez/bot-whatsapp/commit/f6114affadfbc324536a86167d1fdfe8da3c8de6))
|
||||
* **bot:** :fire: endFlow with ctx ([b655ae4](https://github.com/leifermendez/bot-whatsapp/commit/b655ae449e7958ea940d8cc3c678fd66f60b6385))
|
||||
* **bot:** :zap: endFlow butons ([87a4203](https://github.com/leifermendez/bot-whatsapp/commit/87a4203cd5b88f566387a76d586248e4265d6e4e))
|
||||
* **bot:** :zap: fix fallback refactor ([e22780d](https://github.com/leifermendez/bot-whatsapp/commit/e22780d3faba94f71a70f1f201a20690608fa5bf))
|
||||
* **cli:** :zap: endflow ([1c66f17](https://github.com/leifermendez/bot-whatsapp/commit/1c66f178a56d284bb8cb9df5ca17685c7e5d1ddd))
|
||||
* **cli:** :zap: refactor fallback in child flow ([b33e346](https://github.com/leifermendez/bot-whatsapp/commit/b33e34692d3abcb6874308a9be79f74be4a2c3a8))
|
||||
* **cli:** :zap: refactor fallback in child flow ([8da4b20](https://github.com/leifermendez/bot-whatsapp/commit/8da4b204b41125b5d0fa0aee4fa87c1f5faf5568))
|
||||
|
||||
### [0.1.18](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.17...v0.1.18) (2023-01-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bot:** :zap: add blacklist ([7078dc4](https://github.com/leifermendez/bot-whatsapp/commit/7078dc4c93d01bf90ef08ecb34e89a1abbe16fd2))
|
||||
* **bot:** :zap: flowDynamic buttons, media ([3c4b1c0](https://github.com/leifermendez/bot-whatsapp/commit/3c4b1c0fc4b6d98d67c67806d918d3604bb2209b))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bot:** :bug: body undefined ([bb6ed4a](https://github.com/leifermendez/bot-whatsapp/commit/bb6ed4a084ae98070dfdf0c4ba1eca574c4092cc))
|
||||
* **bot:** :bug: body undefined ([9234cf1](https://github.com/leifermendez/bot-whatsapp/commit/9234cf1c5d00abdd35e62a826b3c450ab056987a))
|
||||
* **bot:** :bug: body undefined ([a118bbb](https://github.com/leifermendez/bot-whatsapp/commit/a118bbbf7f0a7023cb7f33c23f37db72adad151f))
|
||||
* **bot:** :bug: body undefined ([f54dea5](https://github.com/leifermendez/bot-whatsapp/commit/f54dea52b01063acd6122eeba1fbbe324aa7805d))
|
||||
* **bot:** :bug: body undefined ([72e0a91](https://github.com/leifermendez/bot-whatsapp/commit/72e0a910503e9643db7dfbc6e09c41c96934e1f7))
|
||||
* **bot:** :bug: body undefined ([70dd4d7](https://github.com/leifermendez/bot-whatsapp/commit/70dd4d73e814fc5636d19a887f3621c483b837c1))
|
||||
* **bot:** :bug: body undefined ([ecf0eef](https://github.com/leifermendez/bot-whatsapp/commit/ecf0eef928917d76c59bd23886cb7a4108b421f1))
|
||||
* **bot:** :bug: flowDynamic stranger behaviour ([877252b](https://github.com/leifermendez/bot-whatsapp/commit/877252bd4a8a7bbbbf083c3ceaeaeb952b0a1828))
|
||||
* **bot:** :bug: flowDynamic stranger behaviour ([f5a7de3](https://github.com/leifermendez/bot-whatsapp/commit/f5a7de3a003c012e2164e51fff26892cfc3144be))
|
||||
* **bot:** :memo: more docs ([98793d0](https://github.com/leifermendez/bot-whatsapp/commit/98793d0cfc1674830beaa3707f933c5a791eec14))
|
||||
* **cli:** :zap: refactor ([a29b9d4](https://github.com/leifermendez/bot-whatsapp/commit/a29b9d4e1f85fc163cf1d633c0857f0c8b7f03e1))
|
||||
* **cli:** :zap: refactor ([18ef4e9](https://github.com/leifermendez/bot-whatsapp/commit/18ef4e9d726575ca390ca24354825860328d3347))
|
||||
* **cli:** :zap: refactor ([3648757](https://github.com/leifermendez/bot-whatsapp/commit/3648757fa083bdb88a16bf6c2e90c828c233bdb1))
|
||||
* **cli:** :zap: refactor ([32f6a70](https://github.com/leifermendez/bot-whatsapp/commit/32f6a70f8f6fb26d8ea2a0f1a4aec4827b9d6a93))
|
||||
* **cli:** :zap: refactor ([8c825e7](https://github.com/leifermendez/bot-whatsapp/commit/8c825e7f6b7133f7cc7f3041ce331b80a9fe60e0))
|
||||
* **cli:** :zap: refactor ([0c0f437](https://github.com/leifermendez/bot-whatsapp/commit/0c0f4375b84549bee809340a85f9ce038ee2739e))
|
||||
* **cli:** :zap: refactor ([039ce5d](https://github.com/leifermendez/bot-whatsapp/commit/039ce5dd7cac8115b335ad5de05f7bd871e24140))
|
||||
* **cli:** :zap: refactor ([5e87918](https://github.com/leifermendez/bot-whatsapp/commit/5e879188b8bf9d486399b308a9a9c2612607d465))
|
||||
* **cli:** :zap: refactor ([21a7270](https://github.com/leifermendez/bot-whatsapp/commit/21a72702817bc6b344223b34ca4513a7ff45fc93))
|
||||
* **cli:** :zap: refactor ([82a99b2](https://github.com/leifermendez/bot-whatsapp/commit/82a99b2c80e6738566042ea738bbab8208a17758))
|
||||
* **cli:** :zap: refactor ([cc19974](https://github.com/leifermendez/bot-whatsapp/commit/cc19974579379777b05cb69c38cec0fce6740471))
|
||||
* **cli:** :zap: refactor ([56fcb8f](https://github.com/leifermendez/bot-whatsapp/commit/56fcb8fb72169bc21fce7c4fcdceccf2acd39c73))
|
||||
* **cli:** :zap: refactor ([f36cff1](https://github.com/leifermendez/bot-whatsapp/commit/f36cff1eefdd96be4ab531e1cb2d3b630b1a81c3))
|
||||
* **cli:** :zap: refactor ([b393c11](https://github.com/leifermendez/bot-whatsapp/commit/b393c11af6c0ebccb0a690be8b90b9df8877dad1))
|
||||
* **cli:** :zap: refactor ([6683715](https://github.com/leifermendez/bot-whatsapp/commit/6683715ad617ea1075654a475a1c62ea607c733f))
|
||||
* **contexts:** :bug: fixed [#524](https://github.com/leifermendez/bot-whatsapp/issues/524) issue ([79cc31a](https://github.com/leifermendez/bot-whatsapp/commit/79cc31a96f6a9836447cc4e6bb1e1521c54183fe))
|
||||
* **contexts:** :bug: fixed [#524](https://github.com/leifermendez/bot-whatsapp/issues/524) issue ([7067b4a](https://github.com/leifermendez/bot-whatsapp/commit/7067b4a80b7938ccfaf1ed141a37d645a1a3a062))
|
||||
* **provider:** wwebjs upgrade ([345f256](https://github.com/leifermendez/bot-whatsapp/commit/345f256a1b4a238519dafc15c9a31bc5e6bad4fe))
|
||||
* se agrego @bot-whatsapp/portal a package.json ([46a9fa6](https://github.com/leifermendez/bot-whatsapp/commit/46a9fa6793e06600335de998d2bd9d0691b02ca4))
|
||||
|
||||
### [0.1.17](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.16...v0.1.17) (2023-01-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* mod de starters para habiltar portal ([eceb170](https://github.com/leifermendez/bot-whatsapp/commit/eceb170df03721dca4183b658c863b94fa04bc84))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ci:** pre-release ([aaec075](https://github.com/leifermendez/bot-whatsapp/commit/aaec0751408ab49483d428810d94aaf7d46acb94))
|
||||
* correccion en starters app.js para portal QR ([f430380](https://github.com/leifermendez/bot-whatsapp/commit/f430380b4f23d41702395c96c628bf13bf443278))
|
||||
* **starters:** :zap: added dockerfile ([230981e](https://github.com/leifermendez/bot-whatsapp/commit/230981e2676361149cb2a99def7f705e75009260))
|
||||
|
||||
### [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)
|
||||
|
||||
### [0.1.9-pre](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.9...v0.1.9-pre) (2023-01-10)
|
||||
|
||||
### [0.1.7-pre-1](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-alpha...v0.1.7-pre-1) (2023-01-10)
|
||||
|
||||
### [0.1.7-alpha](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-pre...v0.1.7-alpha) (2023-01-10)
|
||||
|
||||
### [0.1.11](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.10...v0.1.11) (2023-01-11)
|
||||
|
||||
### [0.1.9-pre](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.9...v0.1.9-pre) (2023-01-10)
|
||||
|
||||
### [0.1.7-pre-1](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-alpha...v0.1.7-pre-1) (2023-01-10)
|
||||
|
||||
### [0.1.7-alpha](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-pre...v0.1.7-alpha) (2023-01-10)
|
||||
|
||||
### [0.1.10](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.8...v0.1.10) (2023-01-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* :fire: update qr package ([ecde23f](https://github.com/leifermendez/bot-whatsapp/commit/ecde23fdea65def209aa874af35a3f293e6b1a91))
|
||||
|
||||
### [0.1.8](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-pre...v0.1.8) (2023-01-10)
|
||||
|
||||
### [0.1.7](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-pre...v0.1.7) (2023-01-10)
|
||||
|
||||
### [0.1.6](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.5...v0.1.6) (2023-01-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* :zap: new portal web for qr scan ([cb2e869](https://github.com/leifermendez/bot-whatsapp/commit/cb2e8692a3f94c8b24993cd11dd564f094b0e4ef))
|
||||
* :zap: new portal web for qr scan ([9e93795](https://github.com/leifermendez/bot-whatsapp/commit/9e93795e6fce38890045389da95184fef1fbe0da))
|
||||
* :zap: new portal web for qr scan ([3c178ea](https://github.com/leifermendez/bot-whatsapp/commit/3c178ea113b140535a51f5dcd521dbb66251670e))
|
||||
* :zap: new portal web for qr scan ([1f1f564](https://github.com/leifermendez/bot-whatsapp/commit/1f1f564f4e2e3aa13b84de500fe215e0c45c2770))
|
||||
* :zap: new portal web for qr scan ([3de5f4b](https://github.com/leifermendez/bot-whatsapp/commit/3de5f4b77a10e30632ff7555f5af5d8e93cb2019))
|
||||
* :zap: qr code filename ([d794f60](https://github.com/leifermendez/bot-whatsapp/commit/d794f604ac8a835e523709dbf18c9b1609bbd00e))
|
||||
* :zap: qr portal ([246ecdc](https://github.com/leifermendez/bot-whatsapp/commit/246ecdc11a8c4e652867c842b612dc4ce73f9828))
|
||||
* :zap: qr portal ([af8b401](https://github.com/leifermendez/bot-whatsapp/commit/af8b401d075e1c35065589ede61476461ce86b4d))
|
||||
* agregamos dockerfile y webserver a starters ([f9e3bbc](https://github.com/leifermendez/bot-whatsapp/commit/f9e3bbc6655060408e4fdbe1d7e920c2ed4fca53))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* :zap: add Dockerfile, starter ([4e0d33c](https://github.com/leifermendez/bot-whatsapp/commit/4e0d33c6bb46ad259774f6d0c38c6c0b5f8ca4a9))
|
||||
* :zap: fix inject port args ([20f752e](https://github.com/leifermendez/bot-whatsapp/commit/20f752e6c1b1f7d11948fc4f2f8950f7834df7d9))
|
||||
* :zap: fix inject port args ([7a23eb0](https://github.com/leifermendez/bot-whatsapp/commit/7a23eb0cc6f93ec21c5ab34e46981ae7a93f42ff))
|
||||
* **provider:** :zap: fix send image baileys ([2ddea54](https://github.com/leifermendez/bot-whatsapp/commit/2ddea5468d235035478d4e91e63c821da19da179))
|
||||
* **provider:** :zap: fix send image baileys ([391e11c](https://github.com/leifermendez/bot-whatsapp/commit/391e11ce738cd64792b5237d69f3739b0263c198))
|
||||
* **provider:** :zap: fix send image baileys ([5d10cb9](https://github.com/leifermendez/bot-whatsapp/commit/5d10cb9026da60043e9a2f86117ebb04d0631a3f))
|
||||
* **provider:** fix error docker as root user ([5a033da](https://github.com/leifermendez/bot-whatsapp/commit/5a033da83aee1f614120bccf27c9f330500cc7b0))
|
||||
|
||||
### [0.1.4](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.5...v0.1.4) (2023-01-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* :zap: new portal web for qr scan ([cb2e869](https://github.com/leifermendez/bot-whatsapp/commit/cb2e8692a3f94c8b24993cd11dd564f094b0e4ef))
|
||||
* :zap: new portal web for qr scan ([9e93795](https://github.com/leifermendez/bot-whatsapp/commit/9e93795e6fce38890045389da95184fef1fbe0da))
|
||||
* :zap: new portal web for qr scan ([3c178ea](https://github.com/leifermendez/bot-whatsapp/commit/3c178ea113b140535a51f5dcd521dbb66251670e))
|
||||
* :zap: new portal web for qr scan ([1f1f564](https://github.com/leifermendez/bot-whatsapp/commit/1f1f564f4e2e3aa13b84de500fe215e0c45c2770))
|
||||
* :zap: new portal web for qr scan ([3de5f4b](https://github.com/leifermendez/bot-whatsapp/commit/3de5f4b77a10e30632ff7555f5af5d8e93cb2019))
|
||||
* :zap: qr code filename ([d794f60](https://github.com/leifermendez/bot-whatsapp/commit/d794f604ac8a835e523709dbf18c9b1609bbd00e))
|
||||
* :zap: qr portal ([246ecdc](https://github.com/leifermendez/bot-whatsapp/commit/246ecdc11a8c4e652867c842b612dc4ce73f9828))
|
||||
* :zap: qr portal ([af8b401](https://github.com/leifermendez/bot-whatsapp/commit/af8b401d075e1c35065589ede61476461ce86b4d))
|
||||
* agregamos dockerfile y webserver a starters ([f9e3bbc](https://github.com/leifermendez/bot-whatsapp/commit/f9e3bbc6655060408e4fdbe1d7e920c2ed4fca53))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* :zap: add Dockerfile, starter ([4e0d33c](https://github.com/leifermendez/bot-whatsapp/commit/4e0d33c6bb46ad259774f6d0c38c6c0b5f8ca4a9))
|
||||
* :zap: fix inject port args ([20f752e](https://github.com/leifermendez/bot-whatsapp/commit/20f752e6c1b1f7d11948fc4f2f8950f7834df7d9))
|
||||
* :zap: fix inject port args ([7a23eb0](https://github.com/leifermendez/bot-whatsapp/commit/7a23eb0cc6f93ec21c5ab34e46981ae7a93f42ff))
|
||||
* **provider:** :zap: fix send image baileys ([2ddea54](https://github.com/leifermendez/bot-whatsapp/commit/2ddea5468d235035478d4e91e63c821da19da179))
|
||||
* **provider:** :zap: fix send image baileys ([391e11c](https://github.com/leifermendez/bot-whatsapp/commit/391e11ce738cd64792b5237d69f3739b0263c198))
|
||||
* **provider:** :zap: fix send image baileys ([5d10cb9](https://github.com/leifermendez/bot-whatsapp/commit/5d10cb9026da60043e9a2f86117ebb04d0631a3f))
|
||||
* **provider:** fix error docker as root user ([5a033da](https://github.com/leifermendez/bot-whatsapp/commit/5a033da83aee1f614120bccf27c9f330500cc7b0))
|
||||
|
||||
### [0.1.3](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.2...v0.1.3) (2023-01-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **adapter:** :zap: send messages with dialogflow ([c20e151](https://github.com/leifermendez/bot-whatsapp/commit/c20e151e209d33de9e7425a64f003c85360f1832))
|
||||
* **baileys:** added more methods ([1b23b83](https://github.com/leifermendez/bot-whatsapp/commit/1b23b837460ce4533ff33f10f1de5e3a344a5623))
|
||||
* **bot:** :zap: http responses support ([e331c2d](https://github.com/leifermendez/bot-whatsapp/commit/e331c2dcc40eeb82a93f9d29f6a82333b8465927))
|
||||
* **bot:** :zap: http responses support ([2d2bb08](https://github.com/leifermendez/bot-whatsapp/commit/2d2bb085cd95604a84ca3fe5c4ddc84b3824ac1c))
|
||||
* **bot:** :zap: rev-03 everything work fine ([3012e02](https://github.com/leifermendez/bot-whatsapp/commit/3012e026b77ab4e99334b992d166a89189f76503))
|
||||
* **cli:** :sparkles: added bailey ([06acec2](https://github.com/leifermendez/bot-whatsapp/commit/06acec2bf29d72c2b46f4ce81fed115bab97351f))
|
||||
* **cli:** :sparkles: added bailey ([c868f73](https://github.com/leifermendez/bot-whatsapp/commit/c868f7346245bec94582b25a342febc657926c9d))
|
||||
* **conflict:** :zap: remove unused variable ([eba9229](https://github.com/leifermendez/bot-whatsapp/commit/eba92299cfd84c971f09697d027043f19eec2b7c))
|
||||
* **contexts:** :zap: add new dialogflowcx ([4d8cf62](https://github.com/leifermendez/bot-whatsapp/commit/4d8cf623ff86b3d08c8d52293d4e289dfda68e1c))
|
||||
* **contexts:** :zap: add new dialogflowcx ([9885872](https://github.com/leifermendez/bot-whatsapp/commit/98858729919b2544dace07c49badce7888ddfd82))
|
||||
* **contexts:** dialogflowcx support ([9179421](https://github.com/leifermendez/bot-whatsapp/commit/917942139f9736f1c0f8ce5f07b4e12e5768b0c7))
|
||||
* correccion de flujos en app.js de ejemplo ([99f508f](https://github.com/leifermendez/bot-whatsapp/commit/99f508f93889d70240861158bc304c25a3b2daef))
|
||||
* **docs:** master class updated ([69fd81a](https://github.com/leifermendez/bot-whatsapp/commit/69fd81a565e61b249ac50917585293d2d84e3dd4))
|
||||
* **docs:** master class updated ([d522b03](https://github.com/leifermendez/bot-whatsapp/commit/d522b03e2e6e6e3f7c467c59e3d2d6f288fe37b2))
|
||||
* **provider:** :bug: dialogflow ([4ec6f1e](https://github.com/leifermendez/bot-whatsapp/commit/4ec6f1e120879e545fa111615f2d79b792d947a5))
|
||||
* **provider:** :sparkles: added dialogflow ([2f633c7](https://github.com/leifermendez/bot-whatsapp/commit/2f633c72da24f98d6c318d1e725571b62e04604c))
|
||||
* **provider:** :sparkles: added dialogflow ([798f1ce](https://github.com/leifermendez/bot-whatsapp/commit/798f1cebdefe43624c1698a219dcb224bb842d38))
|
||||
* **provider:** :sparkles: endpoint is added to validate the webhook … ([478929d](https://github.com/leifermendez/bot-whatsapp/commit/478929d1340d46d6bf997ae8edabbaae4511172d))
|
||||
* **provider:** :sparkles: endpoint is added to validate the webhook token ([1ec1564](https://github.com/leifermendez/bot-whatsapp/commit/1ec15647dc462363d5b765f42debddbe6ef6266b))
|
||||
* **provider:** :zap: add new methods ([0b4e353](https://github.com/leifermendez/bot-whatsapp/commit/0b4e35308dace0ccdf618cb1d04987ed5200d58c))
|
||||
* **provider:** :zap: add sendfile and sendButtons ([5433610](https://github.com/leifermendez/bot-whatsapp/commit/5433610a84d7a050a387e4daf2ded1daebfc03a4))
|
||||
* **provider:** :zap: add sendfile and sendButtons ([342cbcc](https://github.com/leifermendez/bot-whatsapp/commit/342cbccff1d09f9aabe5423ad6d686d590a2448f))
|
||||
* **provider:** :zap: added new venom provider ([01fe9eb](https://github.com/leifermendez/bot-whatsapp/commit/01fe9ebc9a943f2aa086ee415153d1cccdb14ec0))
|
||||
* **provider:** :zap: added tamplate venom ([337c2e9](https://github.com/leifermendez/bot-whatsapp/commit/337c2e94bccd0ae173958fe2db08b494bdc93c28))
|
||||
* **provider:** :zap: baileysProvider ([23b2e8e](https://github.com/leifermendez/bot-whatsapp/commit/23b2e8e439ecec24450bd5cf1a3820316e643434))
|
||||
* **provider:** :zap: solution error buttons ([1b83871](https://github.com/leifermendez/bot-whatsapp/commit/1b83871cca6996c6acae3d4c8b6b42aec05ea146))
|
||||
* **provider:** :zap: solution error utils venom ([31c83f5](https://github.com/leifermendez/bot-whatsapp/commit/31c83f5d689a01490d3adb96006f54c2a5d3268b))
|
||||
* **provider:** :zap: update ([b62d21a](https://github.com/leifermendez/bot-whatsapp/commit/b62d21a0bf94466e43c25c6e8c0f5db9ae91c572))
|
||||
* **provider:** :zap: update ([0c94647](https://github.com/leifermendez/bot-whatsapp/commit/0c94647a27747c3ddf4f02926580370f0d81bdc2))
|
||||
* **provider:** meta provider is added ([b041f7d](https://github.com/leifermendez/bot-whatsapp/commit/b041f7d0c7cc6f152d3f36785d1d398a4141d57d))
|
||||
* **provider:** meta provider is added ([438607c](https://github.com/leifermendez/bot-whatsapp/commit/438607c222b91d6f8814201dabe5f7c3e7ba1abb))
|
||||
* **provider:** new added baileys ([4e0fcbd](https://github.com/leifermendez/bot-whatsapp/commit/4e0fcbd8347f8a430adb43351b5415098a5d10df))
|
||||
* **provider:** new provider - venon:zap: configuracion inicial provi… ([66f75f8](https://github.com/leifermendez/bot-whatsapp/commit/66f75f872200334bfc9eda744bed92c509dfee56))
|
||||
* **provider:** new provider - venon:zap: configuracion inicial provider venom ([fee7c2e](https://github.com/leifermendez/bot-whatsapp/commit/fee7c2e967b7fe8835b5acc243c19f7713acfbe7))
|
||||
* se agregaron los datros del adapter mongo en app.js y package.json ([8160d13](https://github.com/leifermendez/bot-whatsapp/commit/8160d13c866b8ae17b0ec8e68eee1bc0373595b0))
|
||||
* se agrego informacion al ejemplo en app.js ([954e751](https://github.com/leifermendez/bot-whatsapp/commit/954e751f700c6a39ec70c0bc5168637c0dc7e07c))
|
||||
* se agrego informacion al ejemplo en app.js ([b2f1339](https://github.com/leifermendez/bot-whatsapp/commit/b2f13396104db9ccef5b3bad1c4e19c6a4bad2d4))
|
||||
* **starters:** meta memory base template added ([11c784f](https://github.com/leifermendez/bot-whatsapp/commit/11c784f882965d6bd3a2313cf91bed9fb3aa5f26))
|
||||
* **starters:** meta memory base template added ([e8d6252](https://github.com/leifermendez/bot-whatsapp/commit/e8d625201ed86e162e0b4e82100ede1d08985555))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* :art: update ([7d6708c](https://github.com/leifermendez/bot-whatsapp/commit/7d6708c01bbdc5043a7e6ed56fe15a9618115b91))
|
||||
* :sparkles: updated starters ([5da4b7a](https://github.com/leifermendez/bot-whatsapp/commit/5da4b7a4d1e5950be94361ac439938741b9d299c))
|
||||
* actualizar app.js de ejemplo ([1746613](https://github.com/leifermendez/bot-whatsapp/commit/17466138ddcef60a23a0c87911f22045f26d3233))
|
||||
* actualizar ejemplo app.js ([60fdbf3](https://github.com/leifermendez/bot-whatsapp/commit/60fdbf3d3cd62819e618853a9dc2fd0e23fe8752))
|
||||
* **adapter:** :fire: clear log ([9ad4874](https://github.com/leifermendez/bot-whatsapp/commit/9ad4874fdafabfbf0e9e20e6b3281f702bb9fbe7))
|
||||
* **adapter:** :fire: clear log ([4d34d3a](https://github.com/leifermendez/bot-whatsapp/commit/4d34d3ab1daab4e72fb5244216c78cf836d1a164))
|
||||
* **adapter:** :fire: improvement baileys ([e6fefb4](https://github.com/leifermendez/bot-whatsapp/commit/e6fefb4049847f996f2a169b9acfc27c2428d3e6))
|
||||
* **adapter:** :fire: improvement baileys ([2d5ac26](https://github.com/leifermendez/bot-whatsapp/commit/2d5ac2664bea09e60ac85ff2612609ae21050945))
|
||||
* **adapter:** :rocket: venom update - cli - qr iamge ([041bf62](https://github.com/leifermendez/bot-whatsapp/commit/041bf6280e5f6956393716907e0669aa3ca78b4a))
|
||||
* **adapter:** :rocket: venom update - cli - qr iamge ([e37fd0d](https://github.com/leifermendez/bot-whatsapp/commit/e37fd0da3635aa1041664d490d5f9803d2c441ca))
|
||||
* **adapter:** :rocket: venom update - cli - qr iamge ([ca6afbb](https://github.com/leifermendez/bot-whatsapp/commit/ca6afbb87fceec12d4a383486ad693905e36881f))
|
||||
* **adapter:** json db change is made ([386c1bb](https://github.com/leifermendez/bot-whatsapp/commit/386c1bbbac036aa58335fb5f62e3af2493766b6b))
|
||||
* **adapter:** json db change is made ([3bdc7af](https://github.com/leifermendez/bot-whatsapp/commit/3bdc7afe8062527ff08620650d2c1177dfea83f5))
|
||||
* agregamos variables para mysql ([dcf65b8](https://github.com/leifermendez/bot-whatsapp/commit/dcf65b87bc7e7e6381e6448e83118077986898e7))
|
||||
* **bot:** :ambulance: fix callback functions ([d9aa97c](https://github.com/leifermendez/bot-whatsapp/commit/d9aa97c7819aca1446657bc0b75e9732f0f20c6b)), closes [#252](https://github.com/leifermendez/bot-whatsapp/issues/252)
|
||||
* **bot:** :ambulance: fix callback functions ([964a074](https://github.com/leifermendez/bot-whatsapp/commit/964a074aa41324bd09d0c4e2e7aa663a0602b69c))
|
||||
* **bot:** :fire: fix rev ([21407c0](https://github.com/leifermendez/bot-whatsapp/commit/21407c0e37f1ab12efecf887e699cedf05e3946a))
|
||||
* **bot:** :fire: fix rev ([484c8c3](https://github.com/leifermendez/bot-whatsapp/commit/484c8c3bdefbc7824c32a86090bafae0593ecdac))
|
||||
* **bot:** :zap: working callback Phase 1 ([952ce86](https://github.com/leifermendez/bot-whatsapp/commit/952ce86ffaa48a0d6fbc0a00a08c5d1efa14ee8e))
|
||||
* **bot:** :zap: working nested new flow ([2cbc962](https://github.com/leifermendez/bot-whatsapp/commit/2cbc96245d795de749d894a3a0d99b6550f08d9e))
|
||||
* **cli:** :art: starters ([a2be57f](https://github.com/leifermendez/bot-whatsapp/commit/a2be57f0aa42c6b5e13ad19c34abc7d9e81dc135))
|
||||
* **cli:** :art: starters ([670ecf1](https://github.com/leifermendez/bot-whatsapp/commit/670ecf121babf53e76c2ea106c0710cbe59facde))
|
||||
* **cli:** :fire: update instructions ([e585e2f](https://github.com/leifermendez/bot-whatsapp/commit/e585e2f5f644ed0188dc9cd2b3c697c9d6050669))
|
||||
* **cli:** :fire: update instructions ([ed36ce0](https://github.com/leifermendez/bot-whatsapp/commit/ed36ce0a7796320c6a4a452f29c05a3f0f7368db))
|
||||
* **cli:** :fire: update instructions ([bad1694](https://github.com/leifermendez/bot-whatsapp/commit/bad16943fc2089887d6bf0b6d90075d3bec6f9c7))
|
||||
* **cli:** :fire: update instructions ([a21633f](https://github.com/leifermendez/bot-whatsapp/commit/a21633fb7cf348cc37f4e4714f51172b49b193b5))
|
||||
* **cli:** :zap: updated ([a6f4aa8](https://github.com/leifermendez/bot-whatsapp/commit/a6f4aa8d1e809330c06c165aaf9a9f90b8922bb5))
|
||||
* **conflict:** conflict resolution ([71d43b5](https://github.com/leifermendez/bot-whatsapp/commit/71d43b585a0ce173061c84e9879915e4602db026))
|
||||
* **contexts:** :fire: added buttons ([eabef7a](https://github.com/leifermendez/bot-whatsapp/commit/eabef7a92d005cd0190196cfe75828c38885aadf))
|
||||
* **contexts:** :fire: added buttons ([1b878d2](https://github.com/leifermendez/bot-whatsapp/commit/1b878d2ba0daeb3609af74a2ebae7948456e7fb0))
|
||||
* **contexts:** :fire: added buttons ([78b0a9d](https://github.com/leifermendez/bot-whatsapp/commit/78b0a9dddc2a6e0fceb721ee7794efa2047f25fc))
|
||||
* **contexts:** :fire: added buttons ([d8309f7](https://github.com/leifermendez/bot-whatsapp/commit/d8309f77e1d9137c0bec977ed9faef633cd90552))
|
||||
* correccion en app.js para remover addChild en starters ([32db429](https://github.com/leifermendez/bot-whatsapp/commit/32db429f2946f344d949cb169a9595d657c06279))
|
||||
* fix del db provider mysql ([b59d4fc](https://github.com/leifermendez/bot-whatsapp/commit/b59d4fcdd7462cde3f68ab5746d49960b547a592))
|
||||
* provider equivocado en app.js de venom ([4e0a109](https://github.com/leifermendez/bot-whatsapp/commit/4e0a1091ee85cedfaa5a9c3d40e5cd50bc36cda3))
|
||||
* **provider:** :bug: create static site html qr ([c7e56a4](https://github.com/leifermendez/bot-whatsapp/commit/c7e56a4b13c8829f91769eeca7f1f6b3473f68cf))
|
||||
* **provider:** :bug: fix metea provider ([85f50be](https://github.com/leifermendez/bot-whatsapp/commit/85f50be9dcbf3817107898d8d2980baf05acd678))
|
||||
* **provider:** :bug: fix metea provider ([a52aaa1](https://github.com/leifermendez/bot-whatsapp/commit/a52aaa11d883bbaf526cf87720d3c3fd9f89a986))
|
||||
* **provider:** :bug: qr code accurate ([6c4845d](https://github.com/leifermendez/bot-whatsapp/commit/6c4845d733720d9916bb4008f9069ae4fd986a4b))
|
||||
* **provider:** :bug: qr code accurate ([91bfdc4](https://github.com/leifermendez/bot-whatsapp/commit/91bfdc46301207cbc5274308da6f39c7b4652c63))
|
||||
* **provider:** :fire: baileys fix ([928365d](https://github.com/leifermendez/bot-whatsapp/commit/928365dcafb3631acf6b1d0c239a906f8e1c4b0d))
|
||||
* **provider:** :fire: send message togther with media ([78aa23f](https://github.com/leifermendez/bot-whatsapp/commit/78aa23fab094059145f82e6781f9366d5d582b4f))
|
||||
* **provider:** :fire: send message togther with media ([b6bf43d](https://github.com/leifermendez/bot-whatsapp/commit/b6bf43d70fc28c6a229522b9b0de76cec43ac864))
|
||||
* **provider:** :zap: baileys fix restart ([ae83774](https://github.com/leifermendez/bot-whatsapp/commit/ae83774365027e2e86127ab7713ae9ee2df31f33))
|
||||
* **provider:** :zap: edit starter ([ff65832](https://github.com/leifermendez/bot-whatsapp/commit/ff65832012003423cc86d25cf0923452b1f8acb7))
|
||||
* **provider:** :zap: edit starter ([68dd182](https://github.com/leifermendez/bot-whatsapp/commit/68dd1820f05d04780824b318072d053eaf7db654))
|
||||
* **provider:** :zap: json space ([3cef741](https://github.com/leifermendez/bot-whatsapp/commit/3cef741c9ee30024eb42770a5f32931fcd372160))
|
||||
* **provider:** :zap: json space ([9b087e0](https://github.com/leifermendez/bot-whatsapp/commit/9b087e071019a7b6c79195a24dc7ddec498c5716))
|
||||
* **provider:** :zap: json space ([208fb4e](https://github.com/leifermendez/bot-whatsapp/commit/208fb4e9131dd5d4fd7230ba1aa11181337d9181))
|
||||
* **provider:** :zap: json space ([54a59c7](https://github.com/leifermendez/bot-whatsapp/commit/54a59c7f0d4dbaab006ce7e3c74412d8d3613ecd))
|
||||
* **provider:** qr-fix margin ([663641a](https://github.com/leifermendez/bot-whatsapp/commit/663641a1b8bf9234a88b0f3c38381ebc4bfa4bf9))
|
||||
* se quito addChild de las constantes porque no se usa ([ba2291a](https://github.com/leifermendez/bot-whatsapp/commit/ba2291a3ddac0d4101021e11d03cb222c5a4bb3b))
|
||||
* **starters:** :fire: updated staters ([4d4f15c](https://github.com/leifermendez/bot-whatsapp/commit/4d4f15ce73486d9335ad474d9e37c3b155670134))
|
||||
* **starters:** :fire: updated staters ([a30eaac](https://github.com/leifermendez/bot-whatsapp/commit/a30eaac77534d17eb980f6ec126140e9d30aa06e))
|
||||
* **starters:** :memo: update MIGRATION ([37fe323](https://github.com/leifermendez/bot-whatsapp/commit/37fe32322eb1bd41eecd151e52f17ec0588fb85e))
|
||||
* **starters:** :memo: update MIGRATION ([9b30e7d](https://github.com/leifermendez/bot-whatsapp/commit/9b30e7dcfc30bc160b56427cc6cdc2dc982bde2a))
|
||||
* **starters:** base templates are added for meta ([229e017](https://github.com/leifermendez/bot-whatsapp/commit/229e017ae20b84c9d12c7282f97b7034f5f33e6d))
|
||||
* **starters:** base templates are added for meta ([20f6651](https://github.com/leifermendez/bot-whatsapp/commit/20f665175c9b47226df41ce43e05574bd6ab1930))
|
||||
|
||||
### [0.1.2](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.1...v0.1.2) (2022-12-12)
|
||||
|
||||
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
leifer.contacto@gmail.com.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
@@ -1,25 +1,7 @@
|
||||
# CONTRIBUTING
|
||||
|
||||
### 📄 Bienvenido/a
|
||||
Si deseas colaborar con el proyecto existen varias maneras, la primera de ellas es aportando conocimiento y mejorando el repositorio (actualizando documentación, mejorando código, revisando __[issues](https://github.com/codigoencasa/bot-whatsapp/issues)__, etc).
|
||||
|
||||
También es bien recibido los aportes económicos que se utilizaran para diferentes fines __[ver más](https://opencollective.com/bot-whatsapp)__
|
||||
|
||||
El lenguaje principal que se utilizó para desarrollar este proyecto fue __JavaScript__ con el fin de qué personas que están iniciando en el mundo de la programación puedan entender fácilmente.
|
||||
|
||||
|
||||
### 🤔 Preguntas frecuentes
|
||||
- ¿Como puedo hacer aportaciones de código en el proyecto?: [Ver Video](https://youtu.be/Lxt8Acob6aU)
|
||||
- ¿Como ejecutar el entorno de pruebas?: [Ver Video](https://youtu.be/Mf9V-dloBfk)
|
||||
- ¿Como crear un nuevo proveedor?: [Ver Video](https://youtu.be/cahK9zH3SI8)
|
||||
- ¿Que son los GithubActions?: [Ver Video](https://youtu.be/nYBEBFKLiqw)
|
||||
- ¿Canales de comunicación?: [Discord](https://link.codigoencasa.com/DISCORD)
|
||||
|
||||
-----
|
||||
|
||||

|
||||
|
||||
|
||||
__Requerimientos:__
|
||||
- Node v16 o superior __[descargar node](https://nodejs.org/es/download/)__
|
||||
- __[Yarn](https://classic.yarnpkg.com/lang/en/docs/install/#windows-stable)__ como gestor de paquetes. En el link conseguirás las intrucciones para instalar yarn.
|
||||
@@ -31,7 +13,7 @@ __Requerimientos:__
|
||||
|
||||
__Clonar repo rama dev__
|
||||
```
|
||||
git clone --branch dev https://github.com/codigoencasa/bot-whatsapp
|
||||
git clone --branch dev https://github.com/leifermendez/bot-whatsapp
|
||||
```
|
||||
__Instalar dependencias__
|
||||
```
|
||||
@@ -52,49 +34,24 @@ Se ejecuta el CLI (Command Line Interface) para ayudarte a crear un app-bot de e
|
||||
yarn run cli
|
||||
```
|
||||
|
||||
Selecionas (mediante las flechas arriba y abajo) el proveedor que quieras usar y cuando estes sobre el presiona la barra de espacio, igualmente selecciona la base de datos que quieras usar.
|
||||
|
||||
Se creó un subdirecorio con el nombre del proveedor y base de datos que seleccionaste, ejemplo: `base-bailey-mysql`
|
||||
|
||||
Dentro de ese directorio necesitas editar el archivo package.json y borrar las siguientes lineas:
|
||||
Abrir carpeta __example-app-base__ y ejecutar
|
||||
```
|
||||
"@bot-whatsapp/bot": "latest",
|
||||
"@bot-whatsapp/cli": "latest",
|
||||
"@bot-whatsapp/database": "latest",
|
||||
"@bot-whatsapp/provider": "latest",
|
||||
```
|
||||
|
||||
Cambiate al directorio creado ejemplo: `base-bailey-mysql`
|
||||
```
|
||||
cd base-baileys-mysql
|
||||
```
|
||||
Ejecuta los comandos:
|
||||
```
|
||||
npm install
|
||||
cd example-app-base
|
||||
npm i
|
||||
npm run pre-copy
|
||||
npm start
|
||||
```
|
||||
En el caso de MySql y Mongo es necesario especificar en app.js los datos de la conexión, ejemplo de MySql:
|
||||
```
|
||||
const BaileysProvider = require('@bot-whatsapp/provider/baileys')
|
||||
const MySQLAdapter = require('@bot-whatsapp/database/mysql')
|
||||
|
||||
/**
|
||||
* Declaramos las conexiones de MySQL
|
||||
*/
|
||||
const MYSQL_DB_HOST = 'localhost'
|
||||
const MYSQL_DB_USER = 'usr'
|
||||
const MYSQL_DB_PASSWORD = 'pass'
|
||||
const MYSQL_DB_NAME = 'bot'
|
||||
```
|
||||
<!-- __Seguir instrucciones__
|
||||
En la consola encontraras los pasos a seguir -->
|
||||
### __Commit y Push__
|
||||
|
||||

|
||||
El proyecto tiene implementado __[husky](https://typicode.github.io/husky/#/)__, es una herramienta que dispara unas acciones al momento de hacer commit y hacer push.
|
||||
|
||||
__commit:__ Los commit son semánticos, esto quiere decir que deben cumplir un standar al momento de escribirlos ejemplo: ` feat(adapter): new adapter myqsl ` puede ver más info sobre esto __[aquí](https://github.com/conventional-changelog/commitlint/#what-is-commitlint)__
|
||||
|
||||
__push:__ Cada push ejecutar `yarn run test` el cual realiza los test internos que tienen que cumplir con __95% de cobertura__.
|
||||
|
||||
|
||||
> __NOTA:__ [Eres libre de aportar informacion a este documento o arreglar ortografia 🤣](
|
||||
https://github.com/codigoencasa/bot-whatsapp/edit/dev/CONTRIBUTING.md)
|
||||
> Documento en constante actualización....
|
||||
|
||||
------
|
||||
- [Discord](https://link.codigoencasa.com/DISCORD)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
CTX: Es el objeto que representa un mensaje, con opciones, id, ref
|
||||
messageInComming: Objeto entrante del provider {body, from,to,...}
|
||||
messageInComming: Objeto entrante del provider {body, from,...}
|
||||
21
LICENSE.md
21
LICENSE.md
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Leifer Mendez
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
214
MIGRATION.md
214
MIGRATION.md
@@ -1,214 +0,0 @@
|
||||
# Migración
|
||||
|
||||
#### Versión (legacy)
|
||||
|
||||
En la ***versión (legacy)*** se implementaban los flujos de esta manera, en dos archivos independientes.
|
||||
|
||||
> __`initial.json`__ para establecer las palabras claves y el flujo a responder, por otro lado tambien se necesitaba implementar
|
||||
> __`response.json`__ donde se escriben los mensajes a responder.
|
||||
|
||||
```json
|
||||
//initial.json
|
||||
[
|
||||
{
|
||||
"keywords": [
|
||||
"hola",
|
||||
"ola",
|
||||
"alo"
|
||||
],
|
||||
"key": "hola"
|
||||
},
|
||||
{
|
||||
"keywords": ["productos", "info"],
|
||||
"key": "productos"
|
||||
},
|
||||
{
|
||||
"keywords": ["adios", "bye"],
|
||||
"key": "adios"
|
||||
},
|
||||
{
|
||||
"keywords": ["imagen", "foto"],
|
||||
"key": "catalogo"
|
||||
}
|
||||
]
|
||||
```
|
||||
```json
|
||||
//response.json
|
||||
{
|
||||
"hola":{
|
||||
"replyMessage":[
|
||||
"Gracias a ti! \n"
|
||||
],
|
||||
"media":null,
|
||||
"trigger":null
|
||||
},
|
||||
"adios":{
|
||||
"replyMessage":[
|
||||
"Que te vaya bien!!"
|
||||
],
|
||||
},
|
||||
"productos":{
|
||||
"replyMessage":[
|
||||
"Más productos aquí"
|
||||
],
|
||||
"trigger":null,
|
||||
"actions":{
|
||||
"title":"¿Que te interesa ver?",
|
||||
"message":"Abajo unos botons",
|
||||
"footer":"",
|
||||
"buttons":[
|
||||
{"body":"Telefonos"},
|
||||
{"body":"Computadoras"},
|
||||
{"body":"Otros"}
|
||||
]
|
||||
}
|
||||
},
|
||||
"catalogo":{
|
||||
"replyMessage":[
|
||||
"Te envio una imagen"
|
||||
],
|
||||
"media":"https://media2.giphy.com/media/VQJu0IeULuAmCwf5SL/giphy.gif",
|
||||
"trigger":null,
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Versión 2 (0.2.X)
|
||||
|
||||
En esta versión es mucho más sencillo, abajo encontraras un ejemplo del mismo flujo anteriormente mostrado.
|
||||
|
||||
```js
|
||||
//app.js
|
||||
const {
|
||||
createBot,
|
||||
createProvider,
|
||||
createFlow,
|
||||
addKeyword,
|
||||
addChild,
|
||||
} = require('@bot-whatsapp/bot')
|
||||
|
||||
const BaileysProvider = require('@bot-whatsapp/provider/baileys')
|
||||
const MockAdapter = require('@bot-whatsapp/database/mock')
|
||||
/**
|
||||
* Declarando flujos principales.
|
||||
*/
|
||||
const flowHola = addKeyword(['hola', 'ola', 'alo'])
|
||||
.addAnswer('Bienvenido a tu tienda online!')
|
||||
|
||||
const flowAdios = addKeyword(['adios', 'bye'])
|
||||
.addAnswer('Que te vaya bien!!')
|
||||
.addAnswer('Hasta luego!')
|
||||
|
||||
const flowProductos = addKeyword(['productos', 'info'])
|
||||
.addAnswer('Te envio una imagen', {
|
||||
buttons:[
|
||||
{body:"Telefonos"},
|
||||
{body:"Computadoras"},
|
||||
{body:"Otros"}
|
||||
]
|
||||
})
|
||||
|
||||
const flowCatalogo = addKeyword(['imagen', 'foto'])
|
||||
.addAnswer('Te envio una imagen', {media:'https://media2.giphy.com/media/VQJu0IeULuAmCwf5SL/giphy.gif'})
|
||||
|
||||
|
||||
const main = async () => {
|
||||
const adapterDB = new MockAdapter()
|
||||
const adapterFlow = createFlow([flowHola, flowAdios, flowProductos, flowCatalogo])
|
||||
const adapterProvider = createProvider(BaileysProvider)
|
||||
createBot({
|
||||
flow: adapterFlow,
|
||||
provider: adapterProvider,
|
||||
database: adapterDB,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
#### Flujos hijos
|
||||
|
||||
A continuación se muestra un ejemplo de flujos hijos, estos nos sirven para crear flujos que solo se disparan cuando el flujo anterior es el especificado, ejemplo:
|
||||
|
||||
> Menu Principal (Escoge zapatos o bolsos)
|
||||
> - SubMenu 1 (Elegiste bolsos, ahora escoge piel o tela)
|
||||
> - Submenu 1.1 (piel)
|
||||
> - Submenu 2 (Elegiste zapatos, ahora escoge piel o tela)
|
||||
> - Submenu 2.1 (piel)
|
||||
|
||||
El __submenu 1__ solo se va a disparar cuando el flujo anterior sea el __principal__, e igualmente el __submenu 1.1__, solo cuando el flujo anterior sea el __submenu 1__, ejemplo:
|
||||
|
||||
```js
|
||||
/**
|
||||
* Aqui declaramos los flujos hijos, los flujos se declaran de atras para adelante, es decir que si tienes un flujo de este tipo:
|
||||
*
|
||||
* Menu Principal
|
||||
* - SubMenu 1
|
||||
* - Submenu 1.1
|
||||
* - Submenu 2
|
||||
* - Submenu 2.1
|
||||
*
|
||||
* Primero declaras los submenus 1.1 y 2.1, luego el 1 y 2 y al final el principal.
|
||||
*/
|
||||
const flowBolsos2 = addKeyword(['bolsos2', '2'])
|
||||
.addAnswer('🤯 *MUCHOS* bolsos ...')
|
||||
.addAnswer('y mas bolsos... bla bla')
|
||||
|
||||
const flowZapatos2 = addKeyword(['zapatos2', '2'])
|
||||
.addAnswer('🤯 repito que tengo *MUCHOS* zapatos.')
|
||||
.addAnswer('y algunas otras cosas.')
|
||||
|
||||
const flowZapatos = addKeyword(['1', 'zapatos', 'ZAPATOS'])
|
||||
.addAnswer('🤯 Veo que elegiste zapatos')
|
||||
.addAnswer('Tengo muchos zapatos...bla bla')
|
||||
.addAnswer(
|
||||
['Manda:', '*(2) Zapatos2*', 'para mas información'],
|
||||
{ capture: true },
|
||||
(ctx) => {
|
||||
console.log('Aqui puedes ver más info del usuario...')
|
||||
console.log('Puedes enviar un mail, hook, etc..')
|
||||
console.log(ctx)
|
||||
},
|
||||
[...addChild(flowZapatos2)]
|
||||
)
|
||||
|
||||
const flowBolsos = addKeyword(['2', 'bolsos', 'BOLSOS'])
|
||||
.addAnswer('🙌 Veo que elegiste bolsos')
|
||||
.addAnswer('Tengo muchos bolsos...bla bla')
|
||||
.addAnswer(
|
||||
['Manda:', '*(2) Bolsos2*', 'para mas información.'],
|
||||
{ capture: true },
|
||||
(ctx) => {
|
||||
console.log('Aqui puedes ver más info del usuario...')
|
||||
console.log('Puedes enviar un mail, hook, etc..')
|
||||
console.log(ctx)
|
||||
},
|
||||
[...addChild(flowBolsos2)]
|
||||
)
|
||||
|
||||
/**
|
||||
* Declarando flujo principal
|
||||
*/
|
||||
|
||||
const flowPrincipal = addKeyword(['hola', 'ole', 'alo'])
|
||||
.addAnswer(['Hola, bienvenido a mi tienda', '¿Como puedo ayudarte?'])
|
||||
.addAnswer(['Tengo:', 'Zapatos', 'Bolsos', 'etc ...'])
|
||||
.addAnswer(
|
||||
['Para continuar escribe:', '*(1) Zapatos*', '*(2) Bolsos*'],
|
||||
{ capture: true },
|
||||
(ctx) => {
|
||||
console.log('Aqui puedes ver más info del usuario...')
|
||||
console.log('Puedes enviar un mail, hook, etc..')
|
||||
console.log(ctx)
|
||||
},
|
||||
[...addChild(flowBolsos), ...addChild(flowZapatos)]
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
> Forma parte de este proyecto.
|
||||
|
||||
- [Discord](https://link.codigoencasa.com/DISCORD)
|
||||
- [Twitter](https://twitter.com/leifermendez)
|
||||
- [Youtube](https://www.youtube.com/watch?v=5lEMCeWEJ8o&list=PL_WGMLcL4jzWPhdhcUyhbFU6bC0oJd2BR)
|
||||
- [Telegram](https://t.me/leifermendez)
|
||||
144
README.md
144
README.md
@@ -1,45 +1,16 @@
|
||||
# Chatbot Library
|
||||

|
||||
[](https://github.com/leifermendez/bot-whatsapp/actions/workflows/ci.yml)
|
||||
[](http://commitizen.github.io/cz-cli/)
|
||||
[](https://link.codigoencasa.com/DISCORD)
|
||||
--------
|
||||
🦊 Documentación: [https://bot-whatsapp.pages.dev/](https://bot-whatsapp.pages.dev/)
|
||||
Video como hacer PR: https://youtu.be/Lxt8Acob6aU
|
||||
|
||||
<p align="center">
|
||||
<img width="300" src="https://i.imgur.com/Oauef6t.png">
|
||||
</p>
|
||||
🚀 __Roadmap:__ [https://github.com/users/leifermendez/projects/4/views/1](https://github.com/users/leifermendez/projects/4/views/1)
|
||||
|
||||
|
||||
**Con esta librería, puedes construir flujos automatizados de conversación de manera agnóstica al proveedor de WhatsApp,** 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, puedes configurar fácilmente disparadores que te ayudaran a expandir las funcionalidades sin límites. **[Ver más informacion](https://bot-whatsapp.netlify.app/)**
|
||||
|
||||
## Comenzar
|
||||
|
||||
```
|
||||
npm create bot-whatsapp@latest
|
||||
```
|
||||
|
||||
Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
|
||||
|
||||
- Instalacion
|
||||
- Base de datos
|
||||
- Proveedores
|
||||
|
||||
## Recursos
|
||||
- [📄 Documentación](https://bot-whatsapp.netlify.app/)
|
||||
- [🚀 Roadmap](https://github.com/orgs/codigoencasa/projects/1)
|
||||
- [💻 Discord](https://link.codigoencasa.com/DISCORD)
|
||||
- [👌 Twitter](https://twitter.com/leifermendez)
|
||||
- [🎥 Youtube](https://www.youtube.com/watch?v=5lEMCeWEJ8o&list=PL_WGMLcL4jzWPhdhcUyhbFU6bC0oJd2BR)
|
||||
|
||||
## Comunidad
|
||||
**Comunidad**
|
||||
<!-- readme: collaborators,contributors -start -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/cheveguerra">
|
||||
<img src="https://avatars.githubusercontent.com/u/5891114?v=4" width="50;" alt="cheveguerra"/>
|
||||
<br />
|
||||
<sub><b>Jose Alberto Guerra Ugalde</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/leifermendez">
|
||||
<img src="https://avatars.githubusercontent.com/u/15802366?v=4" width="50;" alt="leifermendez"/>
|
||||
@@ -48,10 +19,10 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/leifermendezfroged">
|
||||
<img src="https://avatars.githubusercontent.com/u/97020486?v=4" width="50;" alt="leifermendezfroged"/>
|
||||
<a href="https://github.com/aurik3">
|
||||
<img src="https://avatars.githubusercontent.com/u/37228512?v=4" width="50;" alt="aurik3"/>
|
||||
<br />
|
||||
<sub><b>Leifer Mendez</b></sub>
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
@@ -62,46 +33,10 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/danielcasta0398">
|
||||
<img src="https://avatars.githubusercontent.com/u/98791147?v=4" width="50;" alt="danielcasta0398"/>
|
||||
<a href="https://github.com/leifermendezfroged">
|
||||
<img src="https://avatars.githubusercontent.com/u/97020486?v=4" width="50;" alt="leifermendezfroged"/>
|
||||
<br />
|
||||
<sub><b>Juan Daniel Castaño</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/aurik3">
|
||||
<img src="https://avatars.githubusercontent.com/u/37228512?v=4" width="50;" alt="aurik3"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/marianarolfo">
|
||||
<img src="https://avatars.githubusercontent.com/u/68322254?v=4" width="50;" alt="marianarolfo"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/HKong31">
|
||||
<img src="https://avatars.githubusercontent.com/u/113340082?v=4" width="50;" alt="HKong31"/>
|
||||
<br />
|
||||
<sub><b>HLKong</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jzvi12">
|
||||
<img src="https://avatars.githubusercontent.com/u/10729787?v=4" width="50;" alt="jzvi12"/>
|
||||
<br />
|
||||
<sub><b>Zvi</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/JosephVTX">
|
||||
<img src="https://avatars.githubusercontent.com/u/91026290?v=4" width="50;" alt="JosephVTX"/>
|
||||
<br />
|
||||
<sub><b>Joseph Vega Callupe</b></sub>
|
||||
<sub><b>Leifer Mendez</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
@@ -112,61 +47,25 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/devrlbusiness">
|
||||
<img src="https://avatars.githubusercontent.com/u/66280283?v=4" width="50;" alt="devrlbusiness"/>
|
||||
<a href="https://github.com/jzvi12">
|
||||
<img src="https://avatars.githubusercontent.com/u/10729787?v=4" width="50;" alt="jzvi12"/>
|
||||
<br />
|
||||
<sub><b>Developer RL Business</b></sub>
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Gregoriotecnico">
|
||||
<img src="https://avatars.githubusercontent.com/u/118696506?v=4" width="50;" alt="Gregoriotecnico"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jlferrete">
|
||||
<img src="https://avatars.githubusercontent.com/u/36698913?v=4" width="50;" alt="jlferrete"/>
|
||||
<br />
|
||||
<sub><b>Jose Luis Ferrete Olarte</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/lisandroprada">
|
||||
<img src="https://avatars.githubusercontent.com/u/7232326?v=4" width="50;" alt="lisandroprada"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/6rak0">
|
||||
<img src="https://avatars.githubusercontent.com/u/12260031?v=4" width="50;" alt="6rak0"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Jhonarias13">
|
||||
<img src="https://avatars.githubusercontent.com/u/19483021?v=4" width="50;" alt="Jhonarias13"/>
|
||||
<br />
|
||||
<sub><b>Jhon Freiman Arias</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/tonyvazgar">
|
||||
<img src="https://avatars.githubusercontent.com/u/21047090?v=4" width="50;" alt="tonyvazgar"/>
|
||||
<br />
|
||||
<sub><b>Luis Antonio Vázquez García</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Zamphiropolos">
|
||||
<img src="https://avatars.githubusercontent.com/u/40876040?v=4" width="50;" alt="Zamphiropolos"/>
|
||||
<a href="https://github.com/ulisesvina">
|
||||
<img src="https://avatars.githubusercontent.com/u/20508563?v=4" width="50;" alt="ulisesvina"/>
|
||||
<br />
|
||||
<sub><b>Zamphi</b></sub>
|
||||
<sub><b>Ulises Viña</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
@@ -186,4 +85,9 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
|
||||
</table>
|
||||
<!-- readme: collaborators,contributors -end -->
|
||||
|
||||
> Forma parte de este proyecto.
|
||||
|
||||
- [Discord](https://link.codigoencasa.com/DISCORD)
|
||||
- [Twitter](https://twitter.com/leifermendez)
|
||||
- [Youtube](https://www.youtube.com/watch?v=5lEMCeWEJ8o&list=PL_WGMLcL4jzWPhdhcUyhbFU6bC0oJd2BR)
|
||||
- [Telegram](https://t.me/leifermendez)
|
||||
21
SECURITY.md
21
SECURITY.md
@@ -1,21 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Use this section to tell people about which versions of your project are
|
||||
currently being supported with security updates.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 5.1.x | :white_check_mark: |
|
||||
| 5.0.x | :x: |
|
||||
| 4.0.x | :white_check_mark: |
|
||||
| < 4.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Use this section to tell people how to report a vulnerability.
|
||||
|
||||
Tell them where to go, how often they can expect to get an update on a
|
||||
reported vulnerability, what to expect if the vulnerability is accepted or
|
||||
declined, etc.
|
||||
@@ -1,36 +0,0 @@
|
||||
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 - 01] Flow Basico`, async () => {
|
||||
const [VALUE_A, VALUE_B] = ['hola', 'buenas']
|
||||
|
||||
const flow = addKeyword(VALUE_A).addAnswer(VALUE_B)
|
||||
const provider = createProvider(PROVIDER_DB)
|
||||
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)
|
||||
})
|
||||
|
||||
test.run()
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((res) => setTimeout(res, ms))
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
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 = []) => {
|
||||
console.log('⚡ Server request!')
|
||||
await delay(50)
|
||||
console.log('⚡ Server return!')
|
||||
const data = fakeData.map((u, i) => ({ body: `${i + 1} ${u}` }))
|
||||
console.log(data)
|
||||
return Promise.resolve(data)
|
||||
}
|
||||
|
||||
test(`[Caso - 02] Flow (flowDynamic)`, async () => {
|
||||
const MOCK_VALUES = [
|
||||
'Bienvenido te envio muchas marcas (5510)',
|
||||
'Seleccione marca del auto a cotizar, con el *número* correspondiente',
|
||||
'Seleccione la sub marca del auto a cotizar, con el *número* correspondiente:',
|
||||
'Los precios rondan:',
|
||||
]
|
||||
const provider = createProvider(PROVIDER_DB)
|
||||
const database = new MOCK_DB()
|
||||
|
||||
const flujoPrincipal = addKeyword(['hola'])
|
||||
.addAnswer(MOCK_VALUES[0], null, async (ctx, { flowDynamic }) => {
|
||||
console.log('execute...')
|
||||
const data = await fakeHTTP(['Ford', 'GM', 'BMW'])
|
||||
return flowDynamic(data)
|
||||
})
|
||||
.addAnswer(MOCK_VALUES[1], null, async (ctx, { flowDynamic }) => {
|
||||
const data = await fakeHTTP(['Ranger', 'Explorer'])
|
||||
return flowDynamic(data)
|
||||
})
|
||||
.addAnswer(MOCK_VALUES[2], null, async (ctx, { flowDynamic }) => {
|
||||
const data = await fakeHTTP(['Usado', 'Nuevos'])
|
||||
return flowDynamic(data)
|
||||
})
|
||||
.addAnswer(MOCK_VALUES[3], null, async (ctx, { flowDynamic }) => {
|
||||
const data = await fakeHTTP(['1000', '2000', '3000'])
|
||||
return flowDynamic(data)
|
||||
})
|
||||
|
||||
createBot({
|
||||
database,
|
||||
flow: createFlow([flujoPrincipal]),
|
||||
provider,
|
||||
})
|
||||
|
||||
provider.delaySendMessage(0, 'message', {
|
||||
from: '000',
|
||||
body: 'hola',
|
||||
})
|
||||
|
||||
await delay(1200)
|
||||
const getHistory = database.listHistory.map((i) => i.answer)
|
||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
||||
|
||||
//FlowDynamic
|
||||
assert.is('1 Ford', getHistory[1])
|
||||
assert.is('2 GM', getHistory[2])
|
||||
assert.is('3 BMW', getHistory[3])
|
||||
|
||||
assert.is(MOCK_VALUES[1], getHistory[4])
|
||||
|
||||
//FlowDynamic
|
||||
assert.is('1 Ranger', getHistory[5])
|
||||
assert.is('2 Explorer', getHistory[6])
|
||||
|
||||
assert.is(MOCK_VALUES[2], getHistory[7])
|
||||
|
||||
//FlowDynamic
|
||||
assert.is('1 Usado', getHistory[8])
|
||||
assert.is('2 Nuevos', getHistory[9])
|
||||
|
||||
assert.is(MOCK_VALUES[3], getHistory[10])
|
||||
|
||||
//FlowDynamic
|
||||
assert.is('1 1000', getHistory[11])
|
||||
assert.is('2 2000', getHistory[12])
|
||||
assert.is('3 3000', getHistory[13])
|
||||
})
|
||||
|
||||
test.run()
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((res) => setTimeout(res, ms))
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
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 - 03] Flow puro`, async () => {
|
||||
const MOCK_VALUES = ['Bienvenido a mi tienda', 'Como estas?']
|
||||
|
||||
const provider = createProvider(PROVIDER_DB)
|
||||
const database = new MOCK_DB()
|
||||
|
||||
const flujoPrincipal = addKeyword(['hola'])
|
||||
.addAnswer(MOCK_VALUES[0])
|
||||
.addAnswer(MOCK_VALUES[1])
|
||||
|
||||
createBot({
|
||||
database,
|
||||
flow: createFlow([flujoPrincipal]),
|
||||
provider,
|
||||
})
|
||||
|
||||
provider.delaySendMessage(0, 'message', {
|
||||
from: '000',
|
||||
body: 'hola',
|
||||
})
|
||||
|
||||
await delay(10)
|
||||
const getHistory = database.listHistory.map((i) => i.answer)
|
||||
|
||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
||||
assert.is(MOCK_VALUES[1], getHistory[1])
|
||||
})
|
||||
|
||||
test.run()
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((res) => setTimeout(res, ms))
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
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 = []) => {
|
||||
console.log('⚡ Server request!')
|
||||
await delay(50)
|
||||
console.log('⚡ Server return!')
|
||||
const data = fakeData.map((u, i) => ({ body: `${i + 1} ${u}` }))
|
||||
console.log(data)
|
||||
return Promise.resolve(data)
|
||||
}
|
||||
|
||||
test(`[Caso - 04] Romper flujo (endFlow)`, async () => {
|
||||
const MOCK_VALUES = [
|
||||
'Bienvenido te envio muchas marcas (5510)',
|
||||
'Seleccione marca del auto a cotizar, con el *número* correspondiente',
|
||||
'Seleccione la sub marca del auto a cotizar, con el *número* correspondiente:',
|
||||
'Los precios rondan:',
|
||||
]
|
||||
const provider = createProvider(PROVIDER_DB)
|
||||
const database = new MOCK_DB()
|
||||
|
||||
const flujoPrincipal = addKeyword(['hola'])
|
||||
.addAnswer(MOCK_VALUES[0], null, async (ctx, { flowDynamic }) => {
|
||||
console.log('execute...')
|
||||
const data = await fakeHTTP(['Ford', 'GM', 'BMW'])
|
||||
return flowDynamic(data)
|
||||
})
|
||||
.addAnswer(MOCK_VALUES[1], null, async (ctx, { endFlow }) => {
|
||||
return endFlow()
|
||||
})
|
||||
.addAnswer(MOCK_VALUES[2], null, async (ctx, { flowDynamic }) => {
|
||||
const data = await fakeHTTP(['Usado', 'Nuevos'])
|
||||
return flowDynamic(data)
|
||||
})
|
||||
.addAnswer(MOCK_VALUES[3], null, async (ctx, { flowDynamic }) => {
|
||||
const data = await fakeHTTP(['1000', '2000', '3000'])
|
||||
return flowDynamic(data)
|
||||
})
|
||||
|
||||
createBot({
|
||||
database,
|
||||
flow: createFlow([flujoPrincipal]),
|
||||
provider,
|
||||
})
|
||||
|
||||
provider.delaySendMessage(0, 'message', {
|
||||
from: '000',
|
||||
body: 'hola',
|
||||
})
|
||||
|
||||
await delay(1200)
|
||||
const getHistory = database.listHistory.map((i) => i.answer)
|
||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
||||
|
||||
//FlowDynamic
|
||||
assert.is('1 Ford', getHistory[1])
|
||||
assert.is('2 GM', getHistory[2])
|
||||
assert.is('3 BMW', getHistory[3])
|
||||
|
||||
assert.is(MOCK_VALUES[1], getHistory[4])
|
||||
assert.is(undefined, getHistory[5])
|
||||
})
|
||||
|
||||
test.run()
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((res) => setTimeout(res, ms))
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
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)
|
||||
}
|
||||
|
||||
test(`[Caso - 05] Continuar Flujo (continueFlow)`, async () => {
|
||||
const MOCK_VALUES = ['¿CUal es tu email?', 'Continuamos....', '¿Cual es tu edad?']
|
||||
const provider = createProvider(PROVIDER_DB)
|
||||
const database = new MOCK_DB()
|
||||
|
||||
const flujoPrincipal = addKeyword(['hola'])
|
||||
.addAnswer(
|
||||
MOCK_VALUES[0],
|
||||
{
|
||||
capture: true,
|
||||
},
|
||||
async (ctx, { flowDynamic, fallBack }) => {
|
||||
const validation = ctx.body.includes('@')
|
||||
|
||||
if (validation) {
|
||||
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('Puedes pasar')
|
||||
|
||||
createBot({
|
||||
database,
|
||||
flow: createFlow([flujoPrincipal]),
|
||||
provider,
|
||||
})
|
||||
|
||||
provider.delaySendMessage(0, 'message', {
|
||||
from: '000',
|
||||
body: 'hola',
|
||||
})
|
||||
|
||||
provider.delaySendMessage(10, 'message', {
|
||||
from: '000',
|
||||
body: 'this is not email value',
|
||||
})
|
||||
|
||||
provider.delaySendMessage(20, 'message', {
|
||||
from: '000',
|
||||
body: 'test@test.com',
|
||||
})
|
||||
|
||||
provider.delaySendMessage(90, 'message', {
|
||||
from: '000',
|
||||
body: '20',
|
||||
})
|
||||
|
||||
provider.delaySendMessage(200, 'message', {
|
||||
from: '000',
|
||||
body: '18',
|
||||
})
|
||||
|
||||
await delay(1200)
|
||||
const getHistory = database.listHistory.map((i) => i.answer)
|
||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
||||
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(MOCK_VALUES[1], getHistory[5])
|
||||
assert.is(MOCK_VALUES[2], getHistory[6])
|
||||
assert.is('20', getHistory[7])
|
||||
assert.is('Ups creo que no eres mayor de edad', getHistory[8])
|
||||
assert.is('18', getHistory[9])
|
||||
assert.is('Bien tu edad es correcta!', getHistory[10])
|
||||
assert.is('Puedes pasar', getHistory[11])
|
||||
})
|
||||
|
||||
test.run()
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((res) => setTimeout(res, ms))
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
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)
|
||||
}
|
||||
|
||||
test(`[Caso - 06] Finalizar Flujo (endFlow)`, async () => {
|
||||
const MOCK_VALUES = [
|
||||
'¿CUal es tu email?',
|
||||
'Continuamos....',
|
||||
'¿Cual es tu edad?',
|
||||
]
|
||||
const provider = createProvider(PROVIDER_DB)
|
||||
const database = new MOCK_DB()
|
||||
|
||||
const flujoPrincipal = addKeyword(['hola'])
|
||||
.addAnswer(
|
||||
MOCK_VALUES[0],
|
||||
{
|
||||
capture: true,
|
||||
},
|
||||
async (ctx, { flowDynamic, fallBack }) => {
|
||||
const validation = ctx.body.includes('@')
|
||||
|
||||
if (validation) {
|
||||
const getDataFromApi = await fakeHTTP([
|
||||
'Gracias por tu email se ha validado de manera correcta',
|
||||
])
|
||||
return flowDynamic(getDataFromApi)
|
||||
}
|
||||
return fallBack(validation)
|
||||
}
|
||||
)
|
||||
.addAnswer(MOCK_VALUES[1], null, async (_, { endFlow }) => {
|
||||
return endFlow()
|
||||
})
|
||||
.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({
|
||||
database,
|
||||
flow: createFlow([flujoPrincipal]),
|
||||
provider,
|
||||
})
|
||||
|
||||
provider.delaySendMessage(0, 'message', {
|
||||
from: '000',
|
||||
body: 'hola',
|
||||
})
|
||||
|
||||
provider.delaySendMessage(10, 'message', {
|
||||
from: '000',
|
||||
body: 'this is not email value',
|
||||
})
|
||||
|
||||
provider.delaySendMessage(20, 'message', {
|
||||
from: '000',
|
||||
body: 'test@test.com',
|
||||
})
|
||||
|
||||
provider.delaySendMessage(90, 'message', {
|
||||
from: '000',
|
||||
body: '20',
|
||||
})
|
||||
|
||||
await delay(1200)
|
||||
const getHistory = database.listHistory.map((i) => i.answer)
|
||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
||||
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(MOCK_VALUES[1], getHistory[5])
|
||||
assert.is('20', getHistory[6])
|
||||
assert.is(undefined, getHistory[7])
|
||||
})
|
||||
|
||||
test.run()
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((res) => setTimeout(res, ms))
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
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))
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
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))
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
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))
|
||||
}
|
||||
17
package.json
17
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@bot-whatsapp/root",
|
||||
"version": "0.1.20",
|
||||
"version": "0.1.2",
|
||||
"description": "Bot de wahtsapp open source para MVP o pequeños negocios",
|
||||
"main": "app.js",
|
||||
"private": true,
|
||||
@@ -10,22 +10,17 @@
|
||||
"create-bot:rollup": "rollup --config ./packages/create-bot-whatsapp/rollup-create.config.js ",
|
||||
"bot:rollup": "rollup --config ./packages/bot/rollup-bot.config.js",
|
||||
"provider:rollup": "rollup --config ./packages/provider/rollup-provider.config.js ",
|
||||
"contexts:rollup": "rollup --config ./packages/contexts/rollup-contexts.config.js",
|
||||
"database:rollup": "rollup --config ./packages/database/rollup-database.config.js",
|
||||
"create-bot-whatsapp:rollup": "rollup --config ./packages/create-bot-whatsapp/rollup-create.config.js",
|
||||
"portal:rollup": "rollup --config ./packages/portal/rollup-portal.config.js",
|
||||
"format:check": "prettier --check ./packages",
|
||||
"format:write": "prettier --write ./packages",
|
||||
"fmt.staged": "pretty-quick --staged",
|
||||
"lint:check": "eslint ./packages",
|
||||
"lint:fix": "eslint --fix ./packages",
|
||||
"build:portal-web": "cd ./packages/portal/ && yarn run build.types && yarn run build.client && yarn run build.server && yarn run lint --fix",
|
||||
"build:full": "yarn run build:portal-web && yarn run cli:rollup && yarn run bot:rollup && yarn run provider:rollup && yarn run database:rollup && yarn run contexts:rollup && yarn run create-bot-whatsapp:rollup && yarn run portal:rollup",
|
||||
"build": "yarn run cli:rollup && yarn run bot:rollup && yarn run provider:rollup && yarn run database:rollup && yarn run contexts:rollup && yarn run create-bot-whatsapp:rollup && yarn run portal:rollup",
|
||||
"build": "yarn run cli:rollup && yarn run bot:rollup && yarn run provider:rollup && yarn run database:rollup && yarn run create-bot-whatsapp:rollup",
|
||||
"copy.lib": "node ./scripts/move.js",
|
||||
"test.unit": "node ./node_modules/uvu/bin.js packages test",
|
||||
"test.e2e": "node ./node_modules/uvu/bin.js __test__",
|
||||
"test.coverage": "node ./node_modules/c8/bin/c8.js npm run test.unit && npm run test.e2e",
|
||||
"test.coverage": "node ./node_modules/c8/bin/c8.js npm run test.unit",
|
||||
"test": "npm run test.coverage",
|
||||
"cli": "node ./packages/cli/bin/cli.js",
|
||||
"create": "node ./packages/create-bot-whatsapp/bin/create.js",
|
||||
@@ -34,7 +29,7 @@
|
||||
"prepare": "npx husky install",
|
||||
"preinstall": "npx only-allow yarn",
|
||||
"postinstall": "npx prettier --write .",
|
||||
"release": "standard-version -- --prerelease --global"
|
||||
"release": "standard-version -- --prerelease"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/create-bot-whatsapp",
|
||||
@@ -42,8 +37,6 @@
|
||||
"packages/cli",
|
||||
"packages/database",
|
||||
"packages/provider",
|
||||
"packages/contexts",
|
||||
"packages/portal",
|
||||
"packages/docs"
|
||||
],
|
||||
"keywords": [
|
||||
@@ -68,7 +61,6 @@
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.3.0",
|
||||
"@commitlint/config-conventional": "^17.3.0",
|
||||
"@octokit/core": "^4.1.0",
|
||||
"@rollup/plugin-commonjs": "^23.0.2",
|
||||
"@rollup/plugin-json": "^5.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
@@ -81,7 +73,6 @@
|
||||
"fs-extra": "^11.1.0",
|
||||
"git-cz": "^4.9.0",
|
||||
"husky": "^8.0.2",
|
||||
"mime-types": "^2.1.35",
|
||||
"only-allow": "^1.1.1",
|
||||
"prettier": "^2.8.0",
|
||||
"pretty-quick": "^3.1.3",
|
||||
|
||||
@@ -8,9 +8,6 @@ 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
|
||||
@@ -21,12 +18,10 @@ class CoreClass {
|
||||
flowClass
|
||||
databaseClass
|
||||
providerClass
|
||||
generalArgs = { blackList: [] }
|
||||
constructor(_flow, _database, _provider, _args) {
|
||||
constructor(_flow, _database, _provider) {
|
||||
this.flowClass = _flow
|
||||
this.databaseClass = _database
|
||||
this.providerClass = _provider
|
||||
this.generalArgs = { ...this.generalArgs, ..._args }
|
||||
|
||||
for (const { event, func } of this.listenerBusEvents()) {
|
||||
this.providerClass.on(event, func)
|
||||
@@ -43,7 +38,8 @@ 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',
|
||||
@@ -51,7 +47,8 @@ class CoreClass {
|
||||
},
|
||||
{
|
||||
event: 'auth_failure',
|
||||
func: ({ instructions }) => printer(instructions, '⚡⚡ ERROR AUTH ⚡⚡'),
|
||||
func: ({ instructions }) =>
|
||||
printer(instructions, '⚡⚡ ERROR AUTH ⚡⚡'),
|
||||
},
|
||||
|
||||
{
|
||||
@@ -61,22 +58,22 @@ class CoreClass {
|
||||
]
|
||||
|
||||
/**
|
||||
* GLOSSARY.md
|
||||
* @param {*} messageCtxInComming
|
||||
*
|
||||
* @param {*} messageInComming
|
||||
* @returns
|
||||
*/
|
||||
handleMsg = async (messageCtxInComming) => {
|
||||
logger.log(`[handleMsg]: `, messageCtxInComming)
|
||||
const { body, from } = messageCtxInComming
|
||||
handleMsg = async (messageInComming) => {
|
||||
logger.log(`[handleMsg]: `, messageInComming)
|
||||
const { body, from } = messageInComming
|
||||
let msgToSend = []
|
||||
let endFlowFlag = false
|
||||
let fallBackFlag = false
|
||||
if (this.generalArgs.blackList.includes(from)) return
|
||||
if (!body) return
|
||||
|
||||
if (!body.length) return
|
||||
|
||||
let prevMsg = await this.databaseClass.getPrevByNumber(from)
|
||||
const refToContinue = this.flowClass.findBySerialize(prevMsg?.refSerialize)
|
||||
const prevMsg = await this.databaseClass.getPrevByNumber(from)
|
||||
const refToContinue = this.flowClass.findBySerialize(
|
||||
prevMsg?.refSerialize
|
||||
)
|
||||
|
||||
if (prevMsg?.ref) {
|
||||
const ctxByNumber = toCtx({
|
||||
@@ -87,152 +84,48 @@ class CoreClass {
|
||||
this.databaseClass.save(ctxByNumber)
|
||||
}
|
||||
|
||||
// 📄 Crar CTX de mensaje (uso private)
|
||||
const createCtxMessage = (payload = {}, index = 0) => {
|
||||
const body = typeof payload === 'string' ? payload : payload?.body ?? payload?.answer
|
||||
const media = payload?.media ?? null
|
||||
const buttons = payload?.buttons ?? []
|
||||
const capture = payload?.capture ?? false
|
||||
|
||||
return toCtx({
|
||||
body,
|
||||
from,
|
||||
keyword: null,
|
||||
index,
|
||||
options: { media, buttons, capture },
|
||||
})
|
||||
// 📄 [options: fallback]: esta funcion se encarga de repetir el ultimo mensaje
|
||||
const fallBack = () => {
|
||||
fallBackFlag = true
|
||||
msgToSend = this.flowClass.find(refToContinue?.keyword, true) || []
|
||||
this.sendFlow(msgToSend, from)
|
||||
return refToContinue
|
||||
}
|
||||
|
||||
// 📄 Limpiar cola de procesos
|
||||
const clearQueue = () => {
|
||||
QueuePrincipal.pendingPromise = false
|
||||
QueuePrincipal.queue = []
|
||||
}
|
||||
|
||||
// 📄 Finalizar flujo
|
||||
const endFlow = async (message = null) => {
|
||||
endFlowFlag = true
|
||||
if (message) this.sendProviderAndSave(from, createCtxMessage(message))
|
||||
clearQueue()
|
||||
sendFlow([])
|
||||
return
|
||||
}
|
||||
|
||||
// 📄 Esta funcion se encarga de enviar un array de mensajes dentro de este ctx
|
||||
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) {
|
||||
if (endFlowFlag) return
|
||||
const delayMs = ctxMessage?.options?.delay || 0
|
||||
if (delayMs) await delay(delayMs)
|
||||
QueuePrincipal.enqueue(() =>
|
||||
Promise.all([
|
||||
this.sendProviderAndSave(numberOrId, ctxMessage).then(() => resolveCbEveryCtx(ctxMessage)),
|
||||
])
|
||||
)
|
||||
}
|
||||
return Promise.all(queue)
|
||||
}
|
||||
|
||||
// 📄 [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje
|
||||
const fallBack = async (validation = false, message = null) => {
|
||||
QueuePrincipal.queue = []
|
||||
|
||||
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,
|
||||
options: {
|
||||
...prevMsg.options,
|
||||
buttons: prevMsg.options?.buttons,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 📄 [options: flowDynamic]: esta funcion se encarga de responder un array de respuesta esta limitado a 5 mensajes
|
||||
// para evitar bloque de whatsapp
|
||||
|
||||
const flowDynamic = async (listMsg = []) => {
|
||||
if (!Array.isArray(listMsg)) listMsg = [listMsg]
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// 📄 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,
|
||||
// 📄 [options: callback]: Si se tiene un callback se ejecuta
|
||||
if (!fallBackFlag && refToContinue && prevMsg?.options?.callback) {
|
||||
const indexFlow = this.flowClass.findIndexByRef(refToContinue?.ref)
|
||||
this.flowClass.allCallbacks[indexFlow].callback(messageInComming, {
|
||||
fallBack,
|
||||
flowDynamic,
|
||||
endFlow,
|
||||
})
|
||||
}
|
||||
|
||||
// 📄🤘(tiene return) [options: nested(array)]: Si se tiene flujos hijos los implementa
|
||||
if (!endFlowFlag && prevMsg?.options?.nested?.length) {
|
||||
if (!fallBackFlag && prevMsg?.options?.nested?.length) {
|
||||
const nestedRef = prevMsg.options.nested
|
||||
const flowStandalone = nestedRef.map((f) => ({
|
||||
...nestedRef.find((r) => r.refSerialize === f.refSerialize),
|
||||
}))
|
||||
|
||||
msgToSend = this.flowClass.find(body, false, flowStandalone) || []
|
||||
|
||||
sendFlow(msgToSend, from)
|
||||
this.sendFlow(msgToSend, from)
|
||||
return
|
||||
}
|
||||
|
||||
// 📄🤘(tiene return) Si el mensaje previo implementa capture
|
||||
if (!endFlowFlag && !prevMsg?.options?.nested?.length) {
|
||||
// 📄🤘(tiene return) [options: capture (boolean)]: Si se tiene option boolean
|
||||
if (!fallBackFlag && !prevMsg?.options?.nested?.length) {
|
||||
const typeCapture = typeof prevMsg?.options?.capture
|
||||
const valueCapture = prevMsg?.options?.capture
|
||||
|
||||
if (typeCapture === 'boolean' && fallBackFlag) {
|
||||
if (['string', 'boolean'].includes(typeCapture) && valueCapture) {
|
||||
msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
|
||||
sendFlow(msgToSend, from)
|
||||
this.sendFlow(msgToSend, from)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
msgToSend = this.flowClass.find(body) || []
|
||||
sendFlow(msgToSend, from)
|
||||
this.sendFlow(msgToSend, from)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,13 +136,25 @@ class CoreClass {
|
||||
*/
|
||||
sendProviderAndSave = (numberOrId, ctxMessage) => {
|
||||
const { answer } = ctxMessage
|
||||
return this.providerClass
|
||||
.sendMessage(numberOrId, answer, ctxMessage)
|
||||
.then(() => this.databaseClass.save({ ...ctxMessage, from: numberOrId }))
|
||||
return Promise.all([
|
||||
this.providerClass.sendMessage(numberOrId, answer, ctxMessage),
|
||||
this.databaseClass.save({ ...ctxMessage, from: numberOrId }),
|
||||
])
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @private
|
||||
* @param {*} message
|
||||
* @param {*} ref
|
||||
@@ -262,22 +167,5 @@ class CoreClass {
|
||||
this.continue(null, responde.ref)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Funcion dedicada a enviar el mensaje sin pasar por el flow
|
||||
* (dialogflow)
|
||||
* @param {*} messageToSend
|
||||
* @param {*} numberOrId
|
||||
* @returns
|
||||
*/
|
||||
sendFlowSimple = async (messageToSend, numberOrId) => {
|
||||
const queue = []
|
||||
for (const ctxMessage of messageToSend) {
|
||||
const delayMs = ctxMessage?.options?.delay || 0
|
||||
if (delayMs) await delay(delayMs)
|
||||
QueuePrincipal.enqueue(() => this.sendProviderAndSave(numberOrId, ctxMessage))
|
||||
}
|
||||
return Promise.all(queue)
|
||||
}
|
||||
}
|
||||
module.exports = CoreClass
|
||||
|
||||
@@ -8,7 +8,8 @@ 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 }) =>
|
||||
new CoreClass(flow, database, provider)
|
||||
|
||||
/**
|
||||
* Crear instancia de clase Io (Flow)
|
||||
@@ -28,7 +29,8 @@ 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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const { toSerialize } = require('./methods/toSerialize')
|
||||
const { flatObject } = require('../utils/flattener')
|
||||
|
||||
class FlowClass {
|
||||
allCallbacks = []
|
||||
@@ -9,7 +8,10 @@ class FlowClass {
|
||||
if (!Array.isArray(_flow)) throw new Error('Esto debe ser un ARRAY')
|
||||
this.flowRaw = _flow
|
||||
|
||||
this.allCallbacks = flatObject(_flow)
|
||||
this.allCallbacks = _flow
|
||||
.map((cbIn) => cbIn.ctx.callbacks)
|
||||
.flat(2)
|
||||
.map((c, i) => ({ callback: c?.callback, index: i }))
|
||||
|
||||
const mergeToJsonSerialize = Object.keys(_flow)
|
||||
.map((indexObjectFlow) => _flow[indexObjectFlow].toJson())
|
||||
@@ -25,17 +27,9 @@ 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, mapOptions = { sensitive: false, regex: false }) => {
|
||||
if (mapOptions.regex) return customRegex(str)
|
||||
|
||||
const regexSensitive = mapOptions.sensitive ? 'g' : 'i'
|
||||
const mapSensitive = (str, flag = false) => {
|
||||
const regexSensitive = flag ? 'g' : 'i'
|
||||
if (Array.isArray(str)) {
|
||||
return new RegExp(str.join('|'), regexSensitive)
|
||||
}
|
||||
@@ -44,7 +38,6 @@ 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
|
||||
@@ -55,7 +48,7 @@ class FlowClass {
|
||||
if (refSymbol?.ref) findIn(refSymbol.ref, true)
|
||||
} else {
|
||||
refSymbol = flow.find((c) => {
|
||||
return mapSensitive(c.keyword, { sensitive, regex }).test(keyOrWord)
|
||||
return mapSensitive(c.keyword, sensitive).test(keyOrWord)
|
||||
})
|
||||
if (refSymbol?.ref) findIn(refSymbol.ref, true)
|
||||
return messages
|
||||
@@ -65,7 +58,8 @@ 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)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
const { flatObject } = require('../../utils/flattener')
|
||||
const { generateRef } = require('../../utils/hash')
|
||||
const { addChild } = require('./addChild')
|
||||
const { toJson } = require('./toJson')
|
||||
/**
|
||||
*
|
||||
@@ -17,36 +15,26 @@ 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,
|
||||
})
|
||||
|
||||
const getNested = () => {
|
||||
let flatNested = []
|
||||
if (Array.isArray(nested)) {
|
||||
for (const iterator of nested) {
|
||||
flatNested = [...flatNested, ...addChild(iterator)]
|
||||
}
|
||||
const getNested = () => ({
|
||||
nested: Array.isArray(nested) ? nested : [],
|
||||
})
|
||||
|
||||
return {
|
||||
nested: flatNested,
|
||||
}
|
||||
}
|
||||
return {
|
||||
nested: addChild(nested),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Esta funcion aplana y busca los callback anidados de los hijos
|
||||
* @returns
|
||||
*/
|
||||
const getCbFromNested = () => flatObject(Array.isArray(nested) ? nested : [nested])
|
||||
|
||||
const callback = typeof cb === 'function' ? cb : () => null
|
||||
const callback =
|
||||
typeof cb === 'function'
|
||||
? cb
|
||||
: () => console.log('Callback no definida')
|
||||
|
||||
const lastCtx = inCtx.hasOwnProperty('ctx') ? inCtx.ctx : inCtx
|
||||
|
||||
@@ -74,12 +62,12 @@ const addAnswer =
|
||||
},
|
||||
])
|
||||
|
||||
getCbFromNested()
|
||||
const callbacks = {
|
||||
...inCtx.callbacks,
|
||||
...getCbFromNested(),
|
||||
[ref]: callback,
|
||||
}
|
||||
const callbacks = [].concat(inCtx.callbacks).concat([
|
||||
{
|
||||
ref: lastCtx.ref,
|
||||
callback,
|
||||
},
|
||||
])
|
||||
|
||||
return {
|
||||
...lastCtx,
|
||||
|
||||
@@ -8,14 +8,12 @@ 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,
|
||||
regex: typeof options?.regex === 'boolean' ? options?.regex : false,
|
||||
sensitive:
|
||||
typeof options?.sensitive === 'boolean'
|
||||
? options?.sensitive
|
||||
: false,
|
||||
}
|
||||
|
||||
return defaultProperties
|
||||
|
||||
@@ -5,12 +5,12 @@ const { generateRef, generateRefSerialize } = require('../../utils/hash')
|
||||
* @param options {media:string, buttons:[], capture:true default false}
|
||||
* @returns
|
||||
*/
|
||||
const toCtx = ({ body, from, prevRef, options = {}, index }) => {
|
||||
const toCtx = ({ body, from, prevRef, index }) => {
|
||||
return {
|
||||
ref: generateRef(),
|
||||
keyword: prevRef,
|
||||
answer: body,
|
||||
options: options ?? {},
|
||||
options: {},
|
||||
from,
|
||||
refSerialize: generateRefSerialize({ index, answer: body }),
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@bot-whatsapp/bot",
|
||||
"version": "0.0.96-alpha.0",
|
||||
"version": "0.0.21-alpha.0",
|
||||
"description": "",
|
||||
"main": "./lib/bundle.bot.cjs",
|
||||
"scripts": {
|
||||
@@ -28,9 +28,5 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": "^16.0.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/bot"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,14 @@ const commonjs = require('@rollup/plugin-commonjs')
|
||||
const { nodeResolve } = require('@rollup/plugin-node-resolve')
|
||||
const { join } = require('path')
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
const PATH = join(__dirname, 'lib', 'bundle.bot.cjs')
|
||||
|
||||
module.exports = {
|
||||
input: join(__dirname, 'index.js'),
|
||||
output: {
|
||||
banner: banner['banner.output'].join(''),
|
||||
file: join(__dirname, 'lib', 'bundle.bot.cjs'),
|
||||
format: 'cjs',
|
||||
sourcemap: true,
|
||||
},
|
||||
plugins: [commonjs(), nodeResolve()],
|
||||
},
|
||||
{
|
||||
input: join(__dirname, 'index.js'),
|
||||
output: {
|
||||
banner: banner['banner.output'].join(''),
|
||||
file: join(__dirname, 'lib', 'bundle.bot.cjs'),
|
||||
file: PATH,
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [commonjs(), nodeResolve()],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,10 +2,16 @@ 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 }
|
||||
allCallbacks = [{ callback: () => console.log('') }]
|
||||
flowSerialize = []
|
||||
flowRaw = []
|
||||
find = (arg) => {
|
||||
@@ -94,13 +100,20 @@ 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)
|
||||
@@ -108,12 +121,21 @@ 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 () => {
|
||||
@@ -144,13 +166,20 @@ 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)
|
||||
@@ -158,12 +187,21 @@ 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 () => {
|
||||
@@ -196,13 +234,20 @@ 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)
|
||||
@@ -210,12 +255,21 @@ 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()
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
const { test } = require('uvu')
|
||||
const assert = require('uvu/assert')
|
||||
const FlowClass = require('../io/flow.class')
|
||||
const { addKeyword } = require('../index')
|
||||
|
||||
test(`[FlowClass] Probando instanciamiento de clase`, async () => {
|
||||
const MOCK_FLOW = addKeyword('hola').addAnswer('Buenas!')
|
||||
const flowClass = new FlowClass([MOCK_FLOW])
|
||||
assert.is(flowClass instanceof FlowClass, true)
|
||||
})
|
||||
|
||||
test(`[FlowClass] Probando find`, async () => {
|
||||
const MOCK_FLOW = addKeyword('hola').addAnswer('Buenas!')
|
||||
const flowClass = new FlowClass([MOCK_FLOW])
|
||||
|
||||
flowClass.find('hola')
|
||||
assert.is(flowClass instanceof FlowClass, true)
|
||||
})
|
||||
|
||||
test(`[FlowClass] Probando findBySerialize`, async () => {
|
||||
const MOCK_FLOW = addKeyword('hola').addAnswer('Buenas!')
|
||||
const flowClass = new FlowClass([MOCK_FLOW])
|
||||
|
||||
flowClass.findBySerialize('')
|
||||
assert.is(flowClass instanceof FlowClass, true)
|
||||
})
|
||||
|
||||
test.run()
|
||||
@@ -35,7 +35,10 @@ 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
|
||||
|
||||
@@ -68,7 +71,9 @@ 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)
|
||||
})
|
||||
@@ -102,7 +107,10 @@ 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_/)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
const delay = (miliseconds) => new Promise((res) => setTimeout(res, miliseconds))
|
||||
const delay = (miliseconds) =>
|
||||
new Promise((res) => setTimeout(res, miliseconds))
|
||||
|
||||
module.exports = { delay }
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
const flatObject = (listArray = []) => {
|
||||
const cbNestedList = Array.isArray(listArray) ? listArray : []
|
||||
|
||||
if (!listArray.length) return {}
|
||||
|
||||
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) => ({
|
||||
[icb]: Object.values(current)[i],
|
||||
}))
|
||||
return [...acc, ...parse]
|
||||
}, [])
|
||||
|
||||
const flatObj = {}
|
||||
for (const iteration of queueCb) {
|
||||
const [keyCb] = Object.keys(iteration)
|
||||
flatObj[keyCb] = iteration[keyCb]
|
||||
}
|
||||
return flatObj
|
||||
}
|
||||
|
||||
module.exports = { flatObject }
|
||||
@@ -16,6 +16,9 @@ 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 }
|
||||
|
||||
@@ -4,7 +4,9 @@ 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(``)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
class Queue {
|
||||
queue = []
|
||||
pendingPromise = false
|
||||
static queue = []
|
||||
static pendingPromise = false
|
||||
|
||||
enqueue(promise) {
|
||||
static enqueue(promise) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.queue.push({
|
||||
promise,
|
||||
@@ -13,7 +13,7 @@ class Queue {
|
||||
})
|
||||
}
|
||||
|
||||
dequeue() {
|
||||
static dequeue() {
|
||||
if (this.workingOnPromise) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
const { red, yellow, green, bgCyan } = require('kleur')
|
||||
const { exec } = require('node:child_process')
|
||||
|
||||
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())
|
||||
if (majorVersion < 16) {
|
||||
console.error(red(`🔴 Se require Node.js 16 o superior. Actualmente esta ejecutando Node.js ${version}`))
|
||||
console.log(``)
|
||||
reject('ERROR_NODE')
|
||||
console.error(
|
||||
red(
|
||||
`🔴 Se require Node.js 16 o superior. Actualmente esta ejecutando Node.js ${version}`
|
||||
)
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
console.log(green(`Node.js: ${version} compatible ✅`))
|
||||
console.log(green(`Node.js compatible ${version}`))
|
||||
console.log(``)
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
const checkOs = () => {
|
||||
return new Promise((resolve) => {
|
||||
console.log(bgCyan('🙂 Revisando tu sistema operativo'))
|
||||
const os = process.platform
|
||||
if (!os.includes('win32')) {
|
||||
@@ -33,27 +31,8 @@ const checkOs = () => {
|
||||
|
||||
console.log(yellow(messages.join(' \n')))
|
||||
}
|
||||
console.log(green(`OS: compatible ✅`))
|
||||
|
||||
console.log(``)
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
const checkGit = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log(bgCyan('🤓 Revisando GIT'))
|
||||
exec('git --version', (error) => {
|
||||
if (error) {
|
||||
console.error(red(`🔴 Se require instalar GIT`))
|
||||
console.log(``)
|
||||
reject('ERROR_GIT')
|
||||
} else {
|
||||
console.log(green(`Git: Compatible ✅`))
|
||||
console.log(``)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { checkNodeVersion, checkOs, checkGit }
|
||||
module.exports = { checkNodeVersion, checkOs }
|
||||
|
||||
@@ -2,7 +2,10 @@ 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 = []
|
||||
|
||||
@@ -23,7 +23,11 @@ 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 }
|
||||
|
||||
@@ -20,9 +20,13 @@ const installDeps = (pkgManager, packageList) => {
|
||||
const installSingle = (pkgInstall) => () => {
|
||||
new Promise((resolve) => {
|
||||
try {
|
||||
childProcess = spawn(pkgManager, [PKG_OPTION[pkgManager], pkgInstall], {
|
||||
childProcess = spawn(
|
||||
pkgManager,
|
||||
[PKG_OPTION[pkgManager], pkgInstall],
|
||||
{
|
||||
stdio: 'inherit',
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
childProcess.on('error', (e) => {
|
||||
console.error(e)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const prompts = require('prompts')
|
||||
const { join } = require('path')
|
||||
const { yellow, red, cyan, bgMagenta, bgRed } = require('kleur')
|
||||
const { existsSync } = require('fs')
|
||||
const { yellow, red, cyan, bgMagenta } = require('kleur')
|
||||
const { copyBaseApp } = require('../create-app')
|
||||
const { checkNodeVersion, checkOs, checkGit } = require('../check')
|
||||
const { join } = require('path')
|
||||
const { existsSync } = require('fs')
|
||||
const { checkNodeVersion, checkOs } = require('../check')
|
||||
|
||||
const bannerDone = () => {
|
||||
console.log(``)
|
||||
@@ -12,7 +12,7 @@ const bannerDone = () => {
|
||||
[
|
||||
`[Agradecimientos]: Este es un proyecto OpenSource, si tienes intenciones de colaborar puedes hacerlo:`,
|
||||
`[😉] Comprando un cafe https://www.buymeacoffee.com/leifermendez`,
|
||||
`[⭐] Dar estrella https://github.com/codigoencasa/bot-whatsapp`,
|
||||
`[⭐] Dar estrella https://github.com/leifermendez/bot-whatsapp`,
|
||||
`[🚀] Realizando mejoras en el codigo`,
|
||||
].join('\n')
|
||||
)
|
||||
@@ -21,20 +21,6 @@ const bannerDone = () => {
|
||||
}
|
||||
|
||||
const startInteractive = async () => {
|
||||
try {
|
||||
console.clear()
|
||||
await checkNodeVersion()
|
||||
checkOs()
|
||||
await checkGit()
|
||||
console.clear()
|
||||
await nextSteps()
|
||||
} catch (e) {
|
||||
console.error(bgRed(`Ups! 🙄 algo no va bien.`))
|
||||
console.error(bgRed(`Revisa los requerimientos minimos en la documentacion`))
|
||||
}
|
||||
}
|
||||
|
||||
const nextSteps = async () => {
|
||||
const questions = [
|
||||
{
|
||||
type: 'text',
|
||||
@@ -46,11 +32,11 @@ const nextSteps = async () => {
|
||||
name: 'providerWs',
|
||||
message: '¿Cuál proveedor de whatsapp quieres utilizar?',
|
||||
choices: [
|
||||
{ title: 'Baileys (gratis)', value: 'baileys' },
|
||||
{ title: 'Venom (gratis)', value: 'venom' },
|
||||
{ title: 'whatsapp-web.js (gratis)', value: 'wweb' },
|
||||
{ title: 'Twilio', value: 'twilio' },
|
||||
{ title: 'Meta', value: 'meta' },
|
||||
{ title: 'Venom (gratis)', value: 'venom' },
|
||||
{ title: 'Baileys (gratis)', value: 'bailey' },
|
||||
{ title: 'API Oficial (Meta)', value: 'meta', disabled: true },
|
||||
],
|
||||
max: 1,
|
||||
hint: 'Espacio para seleccionar',
|
||||
@@ -62,9 +48,9 @@ const nextSteps = async () => {
|
||||
message: '¿Cuál base de datos quieres utilizar?',
|
||||
choices: [
|
||||
{ title: 'Memory', value: 'memory' },
|
||||
{ title: 'Json', value: 'json' },
|
||||
{ title: 'Mongo', value: 'mongo' },
|
||||
{ title: 'MySQL', value: 'mysql' },
|
||||
{ title: 'Json', value: 'json', disabled: true },
|
||||
],
|
||||
max: 1,
|
||||
hint: 'Espacio para seleccionar',
|
||||
@@ -72,6 +58,9 @@ const nextSteps = async () => {
|
||||
},
|
||||
]
|
||||
|
||||
console.clear()
|
||||
checkNodeVersion()
|
||||
checkOs()
|
||||
const onCancel = () => {
|
||||
console.log('¡Proceso cancelado!')
|
||||
return true
|
||||
@@ -80,7 +69,8 @@ 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),
|
||||
@@ -95,7 +85,7 @@ const nextSteps = async () => {
|
||||
const indexOfPath = possiblesPath.find((a) => existsSync(a))
|
||||
await copyBaseApp(indexOfPath, join(process.cwd(), templateName))
|
||||
console.log(``)
|
||||
console.log(bgMagenta(`⚡⚡⚡ INSTRUCCIONES ⚡⚡⚡`))
|
||||
console.log(bgMagenta(`⚡⚡⚡INSTRUCCIONES⚡⚡⚡`))
|
||||
console.log(yellow(`cd ${templateName}`))
|
||||
console.log(yellow(`npm install`))
|
||||
console.log(yellow(`npm start`))
|
||||
@@ -112,7 +102,11 @@ 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
|
||||
@@ -125,7 +119,11 @@ 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@bot-whatsapp/cli",
|
||||
"version": "0.0.72-alpha.0",
|
||||
"version": "0.0.28-alpha.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"devDependencies": {
|
||||
@@ -15,9 +15,5 @@
|
||||
],
|
||||
"bin": {
|
||||
"bot": "./bin/cli.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/cli"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "@bot-whatsapp/contexts",
|
||||
"version": "0.0.16-alpha.0",
|
||||
"description": "",
|
||||
"main": "./lib/bundle.contexts.cjs",
|
||||
"files": [
|
||||
"./lib/"
|
||||
],
|
||||
"exports": {
|
||||
"./mock": "./lib/mock/index.cjs",
|
||||
"./dialogflow": "./lib/dialogflow/index.cjs",
|
||||
"./dialogflowcx": "./lib/dialogflow-cx/index.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bot-whatsapp/bot": "*"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/contexts"
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
const banner = require('../../config/banner.rollup.json')
|
||||
const commonjs = require('@rollup/plugin-commonjs')
|
||||
const { join } = require('path')
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
input: join(__dirname, 'src', 'mock', 'index.js'),
|
||||
output: {
|
||||
banner: banner['banner.output'].join(''),
|
||||
file: join(__dirname, 'lib', 'mock', 'index.cjs'),
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [commonjs()],
|
||||
},
|
||||
{
|
||||
input: join(__dirname, 'src', 'dialogflow', 'index.js'),
|
||||
output: {
|
||||
banner: banner['banner.output'].join(''),
|
||||
file: join(__dirname, 'lib', 'dialogflow', 'index.cjs'),
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [commonjs()],
|
||||
},
|
||||
{
|
||||
input: join(__dirname, 'src', 'dialogflow-cx', 'index.js'),
|
||||
output: {
|
||||
banner: banner['banner.output'].join(''),
|
||||
file: join(__dirname, 'lib', 'dialogflow-cx', 'index.cjs'),
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [commonjs()],
|
||||
},
|
||||
]
|
||||
@@ -1,114 +0,0 @@
|
||||
const { CoreClass } = require('@bot-whatsapp/bot')
|
||||
const { SessionsClient } = require('@google-cloud/dialogflow-cx').v3beta1
|
||||
const { existsSync, readFileSync } = require('fs')
|
||||
const { join } = require('path')
|
||||
|
||||
/**
|
||||
* Necesita extender de core.class
|
||||
* handleMsg(messageInComming) // const { body, from } = messageInComming
|
||||
*/
|
||||
|
||||
const GOOGLE_ACCOUNT_PATH = join(process.cwd(), 'google-key.json')
|
||||
|
||||
class DialogFlowCXContext extends CoreClass {
|
||||
// Opciones del usuario
|
||||
optionsDX = {
|
||||
language: 'es',
|
||||
location: '',
|
||||
agentId: '',
|
||||
}
|
||||
projectId = null
|
||||
configuration = null
|
||||
sessionClient = null
|
||||
|
||||
constructor(_database, _provider, _optionsDX = {}) {
|
||||
super(null, _database, _provider)
|
||||
this.optionsDX = { ...this.optionsDX, ..._optionsDX }
|
||||
this.init()
|
||||
}
|
||||
|
||||
/**
|
||||
* Verificar conexión con servicio de DialogFlow
|
||||
*/
|
||||
init = () => {
|
||||
if (!existsSync(GOOGLE_ACCOUNT_PATH)) {
|
||||
console.log(`[ERROR]: No se encontro ${GOOGLE_ACCOUNT_PATH}`)
|
||||
/**
|
||||
* Emitir evento de error para que se mueste por consola dicinedo que no tiene el json
|
||||
* */
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
this.projectId = project_id
|
||||
|
||||
this.sessionClient = new SessionsClient({
|
||||
credentials: { private_key, client_email },
|
||||
apiEndpoint: `${this.optionsDX.location}-dialogflow.googleapis.com`,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* GLOSSARY.md
|
||||
* @param {*} messageCtxInComming
|
||||
* @returns
|
||||
*/
|
||||
handleMsg = async (messageCtxInComming) => {
|
||||
const languageCode = this.optionsDX.language
|
||||
const { from, body } = messageCtxInComming
|
||||
|
||||
/**
|
||||
* 📄 Creamos session de contexto basado en el numero de la persona
|
||||
* para evitar este problema.
|
||||
* https://github.com/codigoencasa/bot-whatsapp/pull/140
|
||||
*/
|
||||
|
||||
const session = this.sessionClient.projectLocationAgentSessionPath(
|
||||
this.projectId,
|
||||
this.optionsDX.location,
|
||||
this.optionsDX.agentId,
|
||||
from
|
||||
)
|
||||
|
||||
const reqDialog = {
|
||||
session,
|
||||
queryInput: {
|
||||
text: {
|
||||
text: body,
|
||||
},
|
||||
languageCode,
|
||||
},
|
||||
}
|
||||
|
||||
const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [null]
|
||||
|
||||
const listMessages = single.queryResult.responseMessages.map((res) => {
|
||||
if (res.message == 'text') {
|
||||
return { answer: res.text.text[0] }
|
||||
}
|
||||
|
||||
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 }
|
||||
})
|
||||
return {
|
||||
answer: answer?.stringValue,
|
||||
options: {
|
||||
media: media?.stringValue,
|
||||
buttons: buttonsArray,
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.sendFlowSimple(listMessages, from)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DialogFlowCXContext
|
||||
@@ -1,13 +0,0 @@
|
||||
const DialogCXFlowClass = require('./dialogflow-cx.class')
|
||||
|
||||
/**
|
||||
* Crear instancia de clase Bot
|
||||
* @param {*} args
|
||||
* @returns
|
||||
*/
|
||||
const createBotDialog = async ({ database, provider }, _options) => new DialogCXFlowClass(database, provider, _options)
|
||||
|
||||
module.exports = {
|
||||
createBotDialog,
|
||||
DialogCXFlowClass,
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
const { CoreClass } = require('@bot-whatsapp/bot')
|
||||
const dialogflow = require('@google-cloud/dialogflow')
|
||||
const { existsSync, readFileSync } = require('fs')
|
||||
const { join } = require('path')
|
||||
|
||||
/**
|
||||
* Necesita extender de core.class
|
||||
* handleMsg(messageInComming) // const { body, from } = messageInComming
|
||||
*/
|
||||
|
||||
const GOOGLE_ACCOUNT_PATH = join(process.cwd(), 'google-key.json')
|
||||
|
||||
class DialogFlowContext extends CoreClass {
|
||||
projectId = null
|
||||
configuration = null
|
||||
sessionClient = null
|
||||
optionsDX = {
|
||||
language: 'es',
|
||||
}
|
||||
|
||||
constructor(_database, _provider, _optionsDX = {}) {
|
||||
super(null, _database, _provider)
|
||||
this.optionsDX = { ...this.optionsDX, ..._optionsDX }
|
||||
this.init()
|
||||
}
|
||||
|
||||
/**
|
||||
* Verificar conexión con servicio de DialogFlow
|
||||
*/
|
||||
init = () => {
|
||||
if (!existsSync(GOOGLE_ACCOUNT_PATH)) {
|
||||
console.log(`[ERROR]: No se encontro ${GOOGLE_ACCOUNT_PATH}`)
|
||||
/**
|
||||
* Emitir evento de error para que se mueste por consola dicinedo que no tiene el json
|
||||
* */
|
||||
}
|
||||
|
||||
const rawJson = readFileSync(GOOGLE_ACCOUNT_PATH, 'utf-8')
|
||||
const { project_id, private_key, client_email } = JSON.parse(rawJson)
|
||||
|
||||
this.projectId = project_id
|
||||
this.configuration = {
|
||||
credentials: {
|
||||
private_key,
|
||||
client_email,
|
||||
},
|
||||
}
|
||||
|
||||
this.sessionClient = new dialogflow.SessionsClient(this.configuration)
|
||||
}
|
||||
|
||||
/**
|
||||
* GLOSSARY.md
|
||||
* @param {*} messageCtxInComming
|
||||
* @returns
|
||||
*/
|
||||
handleMsg = async (messageCtxInComming) => {
|
||||
const languageCode = this.optionsDX.language
|
||||
const { from, body } = messageCtxInComming
|
||||
|
||||
let customPayload = {}
|
||||
|
||||
/**
|
||||
* 📄 Creamos session de contexto basado en el numero de la persona
|
||||
* para evitar este problema.
|
||||
* https://github.com/codigoencasa/bot-whatsapp/pull/140
|
||||
*/
|
||||
const session = this.sessionClient.projectAgentSessionPath(this.projectId, from)
|
||||
const reqDialog = {
|
||||
session,
|
||||
queryInput: {
|
||||
text: {
|
||||
text: body,
|
||||
languageCode,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [null]
|
||||
|
||||
const { queryResult } = single
|
||||
|
||||
const msgPayload = queryResult?.fulfillmentMessages?.find((a) => a.message === 'payload')
|
||||
|
||||
// Revisamos si el dialogFlow tiene multimedia
|
||||
if (msgPayload && msgPayload?.payload) {
|
||||
const { fields } = msgPayload.payload
|
||||
const mapButtons = fields?.buttons?.listValue?.values.map((m) => {
|
||||
return { body: m?.structValue?.fields?.body?.stringValue }
|
||||
})
|
||||
|
||||
customPayload = {
|
||||
options: {
|
||||
media: fields?.media?.stringValue,
|
||||
buttons: mapButtons,
|
||||
},
|
||||
}
|
||||
|
||||
const ctxFromDX = {
|
||||
...customPayload,
|
||||
answer: fields?.answer?.stringValue,
|
||||
}
|
||||
this.sendFlowSimple([ctxFromDX], from)
|
||||
return
|
||||
}
|
||||
|
||||
const ctxFromDX = {
|
||||
answer: queryResult?.fulfillmentText,
|
||||
}
|
||||
|
||||
this.sendFlowSimple([ctxFromDX], from)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DialogFlowContext
|
||||
@@ -1,13 +0,0 @@
|
||||
const DialogFlowClass = require('./dialogflow.class')
|
||||
|
||||
/**
|
||||
* Crear instancia de clase Bot
|
||||
* @param {*} args
|
||||
* @returns
|
||||
*/
|
||||
const createBotDialog = async ({ database, provider }) => new DialogFlowClass(database, provider)
|
||||
|
||||
module.exports = {
|
||||
createBotDialog,
|
||||
DialogFlowClass,
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
const MockClass = require('./mock.class')
|
||||
|
||||
/**
|
||||
* Crear instancia de clase Bot
|
||||
* @param {*} args
|
||||
* @returns
|
||||
*/
|
||||
const createBotMock = async ({ database, provider }) => new MockClass(database, provider)
|
||||
|
||||
module.exports = {
|
||||
createBotMock,
|
||||
MockClass,
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
const { CoreClass } = require('@bot-whatsapp/bot')
|
||||
/**
|
||||
* Necesita extender de core.class
|
||||
* handleMsg(messageInComming) // const { body, from } = messageInComming
|
||||
*/
|
||||
|
||||
class MockContext extends CoreClass {
|
||||
constructor(_database, _provider) {
|
||||
super(null, _database, _provider)
|
||||
}
|
||||
|
||||
init = () => {}
|
||||
|
||||
/**
|
||||
* GLOSSARY.md
|
||||
* @param {*} messageCtxInComming
|
||||
* @returns
|
||||
*/
|
||||
handleMsg = async () => {
|
||||
console.log('DEBUG:')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MockContext
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-bot-whatsapp",
|
||||
"version": "0.0.93-alpha.0",
|
||||
"version": "0.0.39-alpha.0",
|
||||
"description": "",
|
||||
"main": "./lib/bundle.create-bot-whatsapp.cjs",
|
||||
"files": [
|
||||
@@ -11,9 +11,5 @@
|
||||
"bin": "./bin/create.js",
|
||||
"dependencies": {
|
||||
"@bot-whatsapp/cli": "*"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/create-bot-whatsapp"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@bot-whatsapp/database",
|
||||
"version": "0.0.64-alpha.0",
|
||||
"version": "0.0.20-alpha.0",
|
||||
"description": "Esto es el conector a mysql, pg, mongo",
|
||||
"main": "./lib/mock/index.cjs",
|
||||
"keywords": [],
|
||||
@@ -12,16 +12,13 @@
|
||||
"dependencies": {
|
||||
"dotenv": "^16.0.3",
|
||||
"mongodb": "^4.11.0",
|
||||
"mysql2": "^2.3.3"
|
||||
"mysql2": "^2.3.3",
|
||||
"stormdb": "^0.6.0"
|
||||
},
|
||||
"exports": {
|
||||
"./mock": "./lib/mock/index.cjs",
|
||||
"./mongo": "./lib/mongo/index.cjs",
|
||||
"./json": "./lib/json/index.cjs",
|
||||
"./json-file": "./lib/json-file/index.cjs",
|
||||
"./mysql": "./lib/mysql/index.cjs"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/database"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,10 @@ module.exports = [
|
||||
plugins: [commonjs()],
|
||||
},
|
||||
{
|
||||
input: join(__dirname, 'src', 'json', 'index.js'),
|
||||
input: join(__dirname, 'src', 'json-file', 'index.js'),
|
||||
output: {
|
||||
banner: banner['banner.output'].join(''),
|
||||
file: join(__dirname, 'lib', 'json', 'index.cjs'),
|
||||
format: 'cjs',
|
||||
file: join(__dirname, 'lib', 'json-file', 'index.cjs'),
|
||||
},
|
||||
plugins: [commonjs()],
|
||||
},
|
||||
|
||||
48
packages/database/src/json-file/index.js
Normal file
48
packages/database/src/json-file/index.js
Normal file
@@ -0,0 +1,48 @@
|
||||
const path = require('path')
|
||||
const StormDB = require('stormdb')
|
||||
const engine = new StormDB.localFileEngine(
|
||||
path.join(process.cwd(), './db.stormdb')
|
||||
)
|
||||
|
||||
class JsonFileAdapter {
|
||||
db
|
||||
listHistory = []
|
||||
|
||||
constructor() {
|
||||
this.init().then()
|
||||
}
|
||||
|
||||
init() {
|
||||
return new Promise((resolve) => {
|
||||
this.db = new StormDB(engine)
|
||||
this.db.default({ history: [] })
|
||||
resolve(this.db)
|
||||
})
|
||||
}
|
||||
|
||||
getPrevByNumber = async (from) => {
|
||||
const response = await this.db.get('history')
|
||||
const { history } = response.state
|
||||
|
||||
if (!history.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const result = history.filter((res) => res.from === from).pop()
|
||||
|
||||
return {
|
||||
...result,
|
||||
}
|
||||
}
|
||||
|
||||
save = async (ctx) => {
|
||||
await this.db
|
||||
.get('history')
|
||||
.push({ ...ctx })
|
||||
.save()
|
||||
console.log('Guardado en DB...', ctx)
|
||||
this.listHistory.push(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = JsonFileAdapter
|
||||
@@ -1,64 +0,0 @@
|
||||
const { join } = require('path')
|
||||
const { existsSync, writeFileSync, readFileSync } = require('fs')
|
||||
|
||||
class JsonFileAdapter {
|
||||
db
|
||||
pathFile
|
||||
listHistory = []
|
||||
|
||||
constructor() {
|
||||
this.pathFile = join(process.cwd(), 'db.json')
|
||||
this.init().then()
|
||||
}
|
||||
|
||||
databaseExists() {
|
||||
return existsSync(this.pathFile)
|
||||
}
|
||||
|
||||
async init() {
|
||||
const dbExists = await this.databaseExists()
|
||||
|
||||
if (!dbExists) {
|
||||
const data = {
|
||||
history: [],
|
||||
}
|
||||
await this.saveData(data)
|
||||
}
|
||||
}
|
||||
|
||||
readDatabase() {
|
||||
const db = readFileSync(this.pathFile)
|
||||
return JSON.parse(db)
|
||||
}
|
||||
|
||||
saveData(data) {
|
||||
writeFileSync(this.pathFile, JSON.stringify(data, null, 2))
|
||||
}
|
||||
|
||||
getPrevByNumber = async (from) => {
|
||||
const { history } = await this.readDatabase()
|
||||
|
||||
if (!history.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const result = history.filter((res) => res.from === from).pop()
|
||||
|
||||
return {
|
||||
...result,
|
||||
}
|
||||
}
|
||||
|
||||
save = async (ctx) => {
|
||||
this.db = await this.readDatabase()
|
||||
|
||||
this.db.history.push(ctx)
|
||||
|
||||
await this.saveData(this.db)
|
||||
|
||||
this.listHistory.push(ctx)
|
||||
console.log('Guardado en DB...', ctx)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = JsonFileAdapter
|
||||
@@ -10,10 +10,7 @@ class MockDatabase {
|
||||
constructor() {}
|
||||
|
||||
getPrevByNumber = (from) => {
|
||||
const history = this.listHistory
|
||||
.slice()
|
||||
.reverse()
|
||||
.filter((i) => !!i.keyword)
|
||||
const history = this.listHistory.slice().reverse()
|
||||
return history.find((a) => a.from === from)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
require('dotenv').config()
|
||||
const { MongoClient } = require('mongodb')
|
||||
|
||||
const DB_URI = process.env.DB_URI || 'mongodb://0.0.0.0:27017'
|
||||
const DB_NAME = process.env.DB_NAME || 'db_bot'
|
||||
|
||||
class MongoAdapter {
|
||||
db
|
||||
listHistory = []
|
||||
credentials = { dbUri: null, dbName: null }
|
||||
constructor(_credentials) {
|
||||
this.credentials = _credentials
|
||||
|
||||
constructor() {
|
||||
this.init().then()
|
||||
}
|
||||
|
||||
init = async () => {
|
||||
try {
|
||||
const client = new MongoClient(this.credentials.dbUri, {})
|
||||
const client = new MongoClient(DB_URI, {})
|
||||
await client.connect()
|
||||
console.log('🆗 Conexión Correcta DB')
|
||||
const db = client.db(this.credentials.dbName)
|
||||
const db = client.db(DB_NAME)
|
||||
this.db = db
|
||||
return true
|
||||
} catch (e) {
|
||||
@@ -24,7 +27,12 @@ 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]
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ const mysql = require('mysql2')
|
||||
class MyslAdapter {
|
||||
db
|
||||
listHistory = []
|
||||
credentials = { host: null, user: null, database: null, password: null }
|
||||
credentials = { host: null, user: null, database: null }
|
||||
|
||||
constructor(_credentials) {
|
||||
this.credentials = _credentials
|
||||
@@ -46,8 +46,18 @@ 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
|
||||
@@ -67,8 +77,8 @@ class MyslAdapter {
|
||||
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`
|
||||
options longtext NOT NULL
|
||||
)`
|
||||
|
||||
this.db.query(sql, (err) => {
|
||||
if (err) throw err
|
||||
|
||||
3
packages/docs/.gitignore
vendored
3
packages/docs/.gitignore
vendored
@@ -41,6 +41,3 @@ package-lock.json
|
||||
|
||||
# Cloudflare
|
||||
functions/**/*.js
|
||||
|
||||
# Netlify
|
||||
.netlify
|
||||
|
||||
@@ -238,119 +238,3 @@ By default, the Cloudflare pages adaptor _does not_ include a `public/_routes.js
|
||||
In the above example, it's saying _all_ pages should be SSR'd. However, the root static files such as `/favicon.ico` and any static assets in `/build/*` should be excluded from the Functions, and instead treated as a static file.
|
||||
|
||||
In most cases the generated `dist/_routes.json` file is ideal. However, if you need more granular control over each path, you can instead provide you're own `public/_routes.json` file. When the project provides its own `public/_routes.json` file, then the Cloudflare adaptor will not auto-generate the routes config and instead use the committed one within the `public` directory.
|
||||
|
||||
## Cloudflare Pages
|
||||
|
||||
Cloudflare's [wrangler](https://github.com/cloudflare/wrangler) CLI can be used to preview a production build locally. To start a local server, run:
|
||||
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
Then visit [http://localhost:8787/](http://localhost:8787/)
|
||||
|
||||
### Deployments
|
||||
|
||||
[Cloudflare Pages](https://pages.cloudflare.com/) are deployable through their [Git provider integrations](https://developers.cloudflare.com/pages/platform/git-integration/).
|
||||
|
||||
If you don't already have an account, then [create a Cloudflare account here](https://dash.cloudflare.com/sign-up/pages). Next go to your dashboard and follow the [Cloudflare Pages deployment guide](https://developers.cloudflare.com/pages/framework-guides/deploy-anything/).
|
||||
|
||||
Within the projects "Settings" for "Build and deployments", the "Build command" should be `npm run build`, and the "Build output directory" should be set to `dist`.
|
||||
|
||||
### Function Invocation Routes
|
||||
|
||||
Cloudflare Page's [function-invocation-routes config](https://developers.cloudflare.com/pages/platform/functions/function-invocation-routes/) can be used to include, or exclude, certain paths to be used by the worker functions. Having a `_routes.json` file gives developers more granular control over when your Function is invoked.
|
||||
This is useful to determine if a page response should be Server-Side Rendered (SSR) or if the response should use a static-site generated (SSG) `index.html` file.
|
||||
|
||||
By default, the Cloudflare pages adaptor _does not_ include a `public/_routes.json` config, but rather it is auto-generated from the build by the Cloudflare adaptor. An example of an auto-generate `dist/_routes.json` would be:
|
||||
|
||||
```
|
||||
{
|
||||
"include": [
|
||||
"/*"
|
||||
],
|
||||
"exclude": [
|
||||
"/_headers",
|
||||
"/_redirects",
|
||||
"/build/*",
|
||||
"/favicon.ico",
|
||||
"/manifest.json",
|
||||
"/service-worker.js",
|
||||
"/about"
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
```
|
||||
|
||||
In the above example, it's saying _all_ pages should be SSR'd. However, the root static files such as `/favicon.ico` and any static assets in `/build/*` should be excluded from the Functions, and instead treated as a static file.
|
||||
|
||||
In most cases the generated `dist/_routes.json` file is ideal. However, if you need more granular control over each path, you can instead provide you're own `public/_routes.json` file. When the project provides its own `public/_routes.json` file, then the Cloudflare adaptor will not auto-generate the routes config and instead use the committed one within the `public` directory.
|
||||
|
||||
## Express Server
|
||||
|
||||
This app has a minimal [Express server](https://expressjs.com/) implementation. After running a full build, you can preview the build using the command:
|
||||
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
Then visit [http://localhost:8080/](http://localhost:8080/)
|
||||
|
||||
## Netlify
|
||||
|
||||
This starter site is configured to deploy to [Netlify Edge Functions](https://docs.netlify.com/edge-functions/overview/), which means it will be rendered at an edge location near to your users.
|
||||
|
||||
### Local development
|
||||
|
||||
The [Netlify CLI](https://docs.netlify.com/cli/get-started/) can be used to preview a production build locally. To do so: First build your site, then to start a local server, run:
|
||||
|
||||
1. Install Netlify CLI globally `npm i -g netlify-cli`.
|
||||
2. Build your site with both ssr and static `npm run build`.
|
||||
3. Start a local server with `npm run serve`.
|
||||
In this project, `npm run serve` uses the `netlify dev` command to spin up a server that can handle Netlify's Edge Functions locally.
|
||||
4. Visit [http://localhost:8888/](http://localhost:8888/) to check out your site.
|
||||
|
||||
### Edge Functions Declarations
|
||||
|
||||
[Netlify Edge Functions declarations](https://docs.netlify.com/edge-functions/declarations/)
|
||||
can be configured to run on specific URL patterns. Each edge function declaration associates
|
||||
one site path pattern with one function to execute on requests that match the path. A single request can execute a chain of edge functions from a series of declarations. A single edge function can be associated with multiple paths across various declarations.
|
||||
|
||||
This is useful to determine if a page response should be Server-Side Rendered (SSR) or
|
||||
if the response should use a static-site generated (SSG) `index.html` file instead.
|
||||
|
||||
By default, the Netlify Edge adaptor will generate a `.netlify/edge-middleware/manifest.json` file, which is used by the Netlify deployment to determine which paths should, and should not, use edge functions.
|
||||
|
||||
To override the generated manifest, you can [add a declaration](https://docs.netlify.com/edge-functions/declarations/#add-a-declaration) to the `netlify.toml` using the `[[edge_functions]]` config. For example:
|
||||
|
||||
```toml
|
||||
[[edge_functions]]
|
||||
path = "/admin"
|
||||
function = "auth"
|
||||
```
|
||||
|
||||
### Deployments
|
||||
|
||||
You can [deploy your site to Netlify](https://docs.netlify.com/site-deploys/create-deploys/) either via a Git provider integration or through the Netlify CLI. This starter site includes a `netlify.toml` file to configure your build for deployment.
|
||||
|
||||
#### Deploying via Git
|
||||
|
||||
Once your site has been pushed to your Git provider, you can either link it [in the Netlify UI](https://app.netlify.com/start) or use the CLI. To link your site to a Git provider from the Netlify CLI, run the command:
|
||||
|
||||
```shell
|
||||
netlify link
|
||||
```
|
||||
|
||||
This sets up [continuous deployment](https://docs.netlify.com/site-deploys/create-deploys/#deploy-with-git) for your site's repo. Whenever you push new commits to your repo, Netlify starts the build process..
|
||||
|
||||
#### Deploying manually via the CLI
|
||||
|
||||
If you wish to deploy from the CLI rather than using Git, you can use the command:
|
||||
|
||||
```shell
|
||||
netlify deploy --build
|
||||
```
|
||||
|
||||
You must use the `--build` flag whenever you deploy. This ensures that the Edge Functions that this starter site relies on are generated and available when you deploy your site.
|
||||
|
||||
Add `--prod` flag to deploy to production.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { netifyEdgeAdaptor } from '@builder.io/qwik-city/adaptors/netlify-edge/vite'
|
||||
import { cloudflarePagesAdaptor } from '@builder.io/qwik-city/adaptors/cloudflare-pages/vite'
|
||||
import { extendConfig } from '@builder.io/qwik-city/vite'
|
||||
import baseConfig from '../../vite.config'
|
||||
|
||||
@@ -7,12 +7,11 @@ export default extendConfig(baseConfig, () => {
|
||||
build: {
|
||||
ssr: true,
|
||||
rollupOptions: {
|
||||
input: ['src/entry.netlify-edge.tsx', '@qwik-city-plan'],
|
||||
input: ['src/entry.cloudflare-pages.tsx', '@qwik-city-plan'],
|
||||
},
|
||||
outDir: '.netlify/edge-functions/entry.netlify-edge',
|
||||
},
|
||||
plugins: [
|
||||
netifyEdgeAdaptor({
|
||||
cloudflarePagesAdaptor({
|
||||
staticGenerate: true,
|
||||
}),
|
||||
],
|
||||
@@ -1,7 +0,0 @@
|
||||
[build]
|
||||
publish = "dist"
|
||||
command = "npm run build"
|
||||
|
||||
[[edge_functions]]
|
||||
path = "/*"
|
||||
function = "entry.netlify-edge"
|
||||
@@ -2,14 +2,15 @@
|
||||
"name": "qwind",
|
||||
"description": "A template to make your website using Qwik + Tailwind CSS.",
|
||||
"version": "0.1.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "qwik build && npm run subfont",
|
||||
"build.client": "vite build",
|
||||
"build.preview": "vite build --ssr src/entry.preview.tsx",
|
||||
"build.server": "vite build -c adaptors/netlify-edge/vite.config.ts",
|
||||
"build.server": "vite build -c adaptors/cloudflare-pages/vite.config.ts",
|
||||
"build.types": "tsc --incremental --noEmit",
|
||||
"deploy": "netlify deploy --prod",
|
||||
"dev": "vite --host --mode ssr",
|
||||
"deploy": "wrangler pages dev ./dist",
|
||||
"dev": "vite --mode ssr",
|
||||
"dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
|
||||
"fmt": "prettier --write .",
|
||||
"fmt.check": "prettier --check .",
|
||||
@@ -20,37 +21,29 @@
|
||||
"qwik": "qwik"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@builder.io/qwik": "0.16.1",
|
||||
"@builder.io/qwik": "0.15.0",
|
||||
"@builder.io/qwik-city": "0.0.128",
|
||||
"@fontsource/inter": "^4.5.14",
|
||||
"@iconify-json/tabler": "^1.1.49",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.0",
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
"@tailwindcss/line-clamp": "^0.3.1",
|
||||
"@tailwindcss/typography": "^0.5.0",
|
||||
"@types/compression": "^1.7.2",
|
||||
"@types/eslint": "8.4.10",
|
||||
"@types/node": "latest",
|
||||
"@typescript-eslint/eslint-plugin": "5.45.0",
|
||||
"@typescript-eslint/parser": "5.45.0",
|
||||
"autoprefixer": "10.4.13",
|
||||
"compression": "^1.7.4",
|
||||
"eslint": "8.29.0",
|
||||
"eslint-plugin-qwik": "0.15.0",
|
||||
"imagetools-core": "^3.2.3",
|
||||
"netlify-cli": "^12.0.11",
|
||||
"node-fetch": "^3.3.0",
|
||||
"node-fetch": "3.3.0",
|
||||
"postcss": "^8.4.19",
|
||||
"prettier": "2.8.0",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"subfont": "^6.12.2",
|
||||
"tailwindcss": "^3.1.8",
|
||||
"typescript": "4.8.4",
|
||||
"vite": "3.2.4",
|
||||
"vite-imagetools": "^4.0.11",
|
||||
"vite-tsconfig-paths": "3.6.0"
|
||||
"vite-tsconfig-paths": "3.6.0",
|
||||
"wrangler": "latest"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=17.0.0"
|
||||
"node": ">=15.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
# https://developers.cloudflare.com/pages/platform/headers/
|
||||
|
||||
/build/*
|
||||
Cache-Control: public, max-age=31536000, s-maxage=31536000, immutable
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 947 B After Width: | Height: | Size: 947 B |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user