Merge branch 'codigoencasa:main' into patch-1

This commit is contained in:
2023-01-06 07:02:55 -06:00
committed by GitHub
155 changed files with 11399 additions and 1829 deletions

58
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
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 Normal file
View File

@@ -0,0 +1,4 @@
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 Normal file
View File

@@ -0,0 +1,79 @@
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 Normal file
View File

@@ -0,0 +1,17 @@
# 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)

View File

@@ -0,0 +1,46 @@
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
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: 'ci(providers): 🚩 Check BREAKING CHANGE'
create_branch: true
branch: feature/breaking-change

45
.github/workflows/check-providers.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
name: Rev Providers
on:
pull_request:
branches:
- dev
jobs:
check-npm:
name: Install Dependencies
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: 'yarn'
registry-url: https://registry.npmjs.org/
- run: corepack enable
- name: Install NPM Dependencies
run: yarn install --immutable --network-timeout 300000
- name: Check Baileys
run: yarn node ./scripts/checker.js --name=baileys --stable=true
- name: Check Venom
run: yarn node ./scripts/checker.js --name=venom --stable=true
- name: Check web-whatsapp
run: yarn node ./scripts/checker.js --name=web-whatsapp --stable=true
- name: Check Meta
run: yarn node ./scripts/checker.js --name=meta --stable=true
- name: Check Twilio
run: yarn node ./scripts/checker.js --name=twilio --stable=true
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: 'ci(providers): 👍 updated versions stable providers'

View File

@@ -1,4 +1,4 @@
name: BotWhatsapp Build-Test
name: Build and Test
on:
pull_request:

75
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
# 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: ['main', dev, next-release]
pull_request:
# The branches below must be a subset of the branches above
branches: ['main']
schedule:
- cron: '21 16 * * 5'
jobs:
analyze:
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}}'

View File

@@ -1,9 +1,11 @@
name: Add contributors
name: Revisando Colaboradores
on:
push:
branches:
- main
pull_request:
branches:
- dev
- main
types: [closed]
jobs:

46
.github/workflows/netlify-dev.yml vendored Normal file
View File

@@ -0,0 +1,46 @@
name: 📄 Desplegando documentacion
on:
pull_request:
branches:
- 'feat/docs-**'
- 'fix/docs-**'
push:
branches:
- 'feat/docs-**'
- 'fix/docs-**'
jobs:
############ DOCUMENTATION BUILD ############
build-documentation:
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 }}

42
.github/workflows/netlify.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: 📄 (PROD) Desplegando documentacion
on:
push:
branches:
- main
- next-release
jobs:
############ DOCUMENTATION BUILD ############
build-documentation:
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 }}

View File

@@ -1,4 +1,4 @@
name: BotWhatsapp Releases(DEV)
name: 🚀 (DEV) Liberando versiones
on:
push:
@@ -13,10 +13,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
persist-credentials: false
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v3
@@ -49,8 +45,7 @@ jobs:
run: yarn node ./scripts/release.js --name=provider --version= --token="${{ secrets.NPM_TOKEN }}"
- name: Commit Versioning & Push changes
uses: actions-js/push@master
uses: stefanzweifel/git-auto-commit-action@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
message: 'ci(version): :zap: automatic - "${date}" updated versions every packages'
branch: 'dev'
commit_message: 'ci(version): :zap: automatic - "${date}" updated versions every packages'
branch: dev

View File

@@ -1,4 +1,4 @@
name: BotWhatsapp Releases(Prod)
name: 🚀⚡ Liberando versiones
on:
push:
@@ -13,10 +13,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
persist-credentials: false
fetch-depth: 0
- name: Set output
id: vars
@@ -52,9 +48,11 @@ jobs:
- name: Release @bot-whatsapp/provider
run: yarn node ./scripts/release.js --name=provider --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
- name: Set CHANGELOG
run: yarn release
- name: Commit Versioning & Push changes
uses: actions-js/push@master
uses: stefanzweifel/git-auto-commit-action@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
message: 'ci(version): :zap: automatic - "${date}" updated versions every packages'
branch: 'dev'
commit_message: 'release(version): 🚀 - "${{ steps.vars.outputs.tag }}" release'
branch: dev

27
.github/workflows/stale.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
# 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'

4
.gitignore vendored
View File

@@ -35,4 +35,6 @@ base-*/
qr.svg
package-lock.json
yarn-error.log
.npmrc
.npmrc
# Local Netlify folder
.netlify

View File

@@ -2,6 +2,113 @@
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.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)

128
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,128 @@
# 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.

21
LICENSE.md Normal file
View File

@@ -0,0 +1,21 @@
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.

View File

@@ -1,15 +1,36 @@
[![Test / Coverage](https://github.com/leifermendez/bot-whatsapp/actions/workflows/ci.yml/badge.svg)](https://github.com/leifermendez/bot-whatsapp/actions/workflows/ci.yml)
# Chatbot Library
![](https://img.shields.io/npm/v/@bot-whatsapp/bot?color=%2300c200&label=%40bot-whatsapp)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
--------
🐤 Tablero de tareas : [https://github.com/users/leifermendez/projects/4/views/1](https://github.com/users/leifermendez/projects/4/views/1)
🦊 Documentación: [https://bot-whatsapp-codigoencasa.pages.dev/](https://bot-whatsapp-codigoencasa.pages.dev/)
Video como hacer PR: https://youtu.be/Lxt8Acob6aU
🚀 __Roadmap:__ [https://github.com/users/leifermendez/projects/4/views/1](https://github.com/users/leifermendez/projects/4/views/1)
[![BotWhatsapp Releases(Prod)](https://github.com/codigoencasa/bot-whatsapp/actions/workflows/releases.yml/badge.svg)](https://github.com/codigoencasa/bot-whatsapp/actions/workflows/releases.yml)
**Comunidad**
<p align="center">
<img width="300" src="https://i.imgur.com/Oauef6t.png">
</p>
**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
<!-- readme: collaborators,contributors -start -->
<table>
<tr>
@@ -45,7 +66,7 @@ Video como hacer PR: https://youtu.be/Lxt8Acob6aU
<a href="https://github.com/HKong31">
<img src="https://avatars.githubusercontent.com/u/113340082?v=4" width="50;" alt="HKong31"/>
<br />
<sub><b>Null</b></sub>
<sub><b>HLKong</b></sub>
</a>
</td>
<td align="center">
@@ -94,9 +115,4 @@ Video como hacer PR: https://youtu.be/Lxt8Acob6aU
</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 Normal file
View File

@@ -0,0 +1,21 @@
# 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.

View File

@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/root",
"version": "0.1.2",
"version": "0.1.3",
"description": "Bot de wahtsapp open source para MVP o pequeños negocios",
"main": "app.js",
"private": true,
@@ -30,7 +30,7 @@
"prepare": "npx husky install",
"preinstall": "npx only-allow yarn",
"postinstall": "npx prettier --write .",
"release": "standard-version -- --prerelease"
"release": "standard-version -- --prerelease --global"
},
"workspaces": [
"packages/create-bot-whatsapp",

View File

@@ -115,24 +115,17 @@ class CoreClass {
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback y ejecutarlo
const cbEveryCtx = (inRef) => {
const indexFlow = this.flowClass.findIndexByRef(inRef)
this.flowClass.allCallbacks[indexFlow].callback(
messageCtxInComming,
{
fallBack,
flowDynamic,
}
)
this.flowClass.allCallbacks[inRef](messageCtxInComming, {
fallBack,
flowDynamic,
})
}
// 📄 [options: callback]: Si se tiene un callback se ejecuta
if (!fallBackFlag) {
if (refToContinue && prevMsg?.options?.callback) {
cbEveryCtx(refToContinue?.ref)
} else {
for (const ite of this.flowClass.find(body)) {
cbEveryCtx(ite?.ref)
}
if (refToContinue?.options?.capture) cbEveryCtx(refToContinue?.ref)
for (const ite of this.flowClass.find(body)) {
if (!ite?.options?.capture) cbEveryCtx(ite?.ref)
}
}
@@ -144,6 +137,11 @@ class CoreClass {
}))
msgToSend = this.flowClass.find(body, false, flowStandalone) || []
for (const ite of msgToSend) {
cbEveryCtx(ite?.ref)
}
this.sendFlow(msgToSend, from)
return
}

View File

@@ -1,4 +1,5 @@
const { toSerialize } = require('./methods/toSerialize')
const { flatObject } = require('../utils/flattener')
class FlowClass {
allCallbacks = []
@@ -8,10 +9,7 @@ class FlowClass {
if (!Array.isArray(_flow)) throw new Error('Esto debe ser un ARRAY')
this.flowRaw = _flow
this.allCallbacks = _flow
.map((cbIn) => cbIn.ctx.callbacks)
.flat(2)
.map((c, i) => ({ callback: c?.callback, index: i }))
this.allCallbacks = flatObject(_flow)
const mergeToJsonSerialize = Object.keys(_flow)
.map((indexObjectFlow) => _flow[indexObjectFlow].toJson())

View File

@@ -1,4 +1,6 @@
const { flatObject } = require('../../utils/flattener')
const { generateRef } = require('../../utils/hash')
const { addChild } = require('./addChild')
const { toJson } = require('./toJson')
/**
*
@@ -27,9 +29,28 @@ const addAnswer =
delay: typeof options?.delay === 'number' ? options?.delay : 0,
})
const getNested = () => ({
nested: Array.isArray(nested) ? nested : [],
})
const getNested = () => {
let flatNested = []
if (Array.isArray(nested)) {
for (const iterator of nested) {
flatNested = [...flatNested, ...addChild(iterator)]
}
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
@@ -59,12 +80,12 @@ const addAnswer =
},
])
const callbacks = [].concat(inCtx.callbacks).concat([
{
ref: lastCtx.ref,
callback,
},
])
getCbFromNested()
const callbacks = {
...inCtx.callbacks,
...getCbFromNested(),
[ref]: callback,
}
return {
...lastCtx,

View File

@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/bot",
"version": "0.0.26-alpha.0",
"version": "0.0.41-alpha.0",
"description": "",
"main": "./lib/bundle.bot.cjs",
"scripts": {

View File

@@ -3,14 +3,23 @@ const commonjs = require('@rollup/plugin-commonjs')
const { nodeResolve } = require('@rollup/plugin-node-resolve')
const { join } = require('path')
const PATH = join(__dirname, 'lib', 'bundle.bot.cjs')
module.exports = {
input: join(__dirname, 'index.js'),
output: {
banner: banner['banner.output'].join(''),
file: PATH,
format: 'cjs',
module.exports = [
{
input: join(__dirname, 'index.js'),
output: {
banner: banner['banner.output'].join(''),
file: join(__dirname, 'lib', 'bundle.bot.cjs'),
format: 'cjs',
},
plugins: [commonjs(), nodeResolve()],
},
plugins: [commonjs(), nodeResolve()],
}
{
input: join(__dirname, 'index.js'),
output: {
banner: banner['banner.output'].join(''),
file: join(__dirname, 'lib', 'bundle.bot.cjs'),
format: 'cjs',
},
plugins: [commonjs(), nodeResolve()],
},
]

View File

@@ -11,7 +11,7 @@ const {
} = require('../index')
class MockFlow {
allCallbacks = [{ callback: () => console.log('') }]
allCallbacks = { ref: () => 1 }
flowSerialize = []
flowRaw = []
find = (arg) => {

View File

@@ -0,0 +1,25 @@
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 }

View File

@@ -1,8 +1,8 @@
const prompts = require('prompts')
const { yellow, red, cyan, bgMagenta } = require('kleur')
const { copyBaseApp } = require('../create-app')
const { join } = require('path')
const { yellow, red, cyan, bgMagenta } = require('kleur')
const { existsSync } = require('fs')
const { copyBaseApp } = require('../create-app')
const { checkNodeVersion, checkOs } = require('../check')
const bannerDone = () => {
@@ -34,7 +34,7 @@ const startInteractive = async () => {
choices: [
{ title: 'whatsapp-web.js (gratis)', value: 'wweb' },
{ title: 'Venom (gratis)', value: 'venom' },
{ title: 'Baileys (gratis)', value: 'bailey' },
{ title: 'Baileys (gratis)', value: 'baileys' },
{ title: 'Twilio', value: 'twilio' },
{ title: 'API Oficial (Meta)', value: 'meta' },
],
@@ -48,9 +48,9 @@ const startInteractive = 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',

View File

@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/cli",
"version": "0.0.33-alpha.0",
"version": "0.0.48-alpha.0",
"description": "",
"main": "index.js",
"devDependencies": {

View File

@@ -96,12 +96,24 @@ class DialogFlowCXContext extends CoreClass {
}
if (res.message == 'payload') {
const { values } = res.payload.fields.buttons.listValue
const buttonsArray = values.map((values) => {
const { stringValue } = values.structValue.fields.body
return { body: stringValue }
})
return { buttons: buttonsArray }
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,
},
}
}
})

View File

@@ -93,8 +93,9 @@ class DialogFlowContext extends CoreClass {
if (msgPayload && msgPayload?.payload) {
const { fields } = msgPayload.payload
const mapButtons = fields?.buttons?.listValue?.values.map((m) => {
return m?.structValue?.fields?.body?.stringValue
return { body: m?.structValue?.fields?.body?.stringValue }
})
customPayload = {
media: fields?.media?.stringValue,
buttons: mapButtons,

View File

@@ -1,6 +1,6 @@
{
"name": "create-bot-whatsapp",
"version": "0.0.44-alpha.0",
"version": "0.0.59-alpha.0",
"description": "",
"main": "./lib/bundle.create-bot-whatsapp.cjs",
"files": [

View File

@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/database",
"version": "0.0.25-alpha.0",
"version": "0.0.40-alpha.0",
"description": "Esto es el conector a mysql, pg, mongo",
"main": "./lib/mock/index.cjs",
"keywords": [],

View File

@@ -35,6 +35,7 @@ module.exports = [
output: {
banner: banner['banner.output'].join(''),
file: join(__dirname, 'lib', 'json', 'index.cjs'),
format: 'cjs',
},
plugins: [commonjs()],
},

View File

@@ -32,7 +32,7 @@ class JsonFileAdapter {
}
saveData(data) {
writeFileSync(this.pathFile, JSON.stringify(data))
writeFileSync(this.pathFile, JSON.stringify(data, null, 2))
}
getPrevByNumber = async (from) => {

View File

@@ -41,3 +41,6 @@ package-lock.json
# Cloudflare
functions/**/*.js
# Netlify
.netlify

View File

@@ -285,3 +285,72 @@ 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.
## 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.

View File

@@ -1,4 +1,4 @@
import { cloudflarePagesAdaptor } from '@builder.io/qwik-city/adaptors/cloudflare-pages/vite'
import { netifyEdgeAdaptor } from '@builder.io/qwik-city/adaptors/netlify-edge/vite'
import { extendConfig } from '@builder.io/qwik-city/vite'
import baseConfig from '../../vite.config'
@@ -7,11 +7,12 @@ export default extendConfig(baseConfig, () => {
build: {
ssr: true,
rollupOptions: {
input: ['src/entry.cloudflare-pages.tsx', '@qwik-city-plan'],
input: ['src/entry.netlify-edge.tsx', '@qwik-city-plan'],
},
outDir: '.netlify/edge-functions/entry.netlify-edge',
},
plugins: [
cloudflarePagesAdaptor({
netifyEdgeAdaptor({
staticGenerate: true,
}),
],

View File

@@ -1,7 +1,7 @@
[build]
publish = "dist"
command = "npm run build"
[[headers]]
for = "/build/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
publish = "dist"
command = "npm run build"
[[edge_functions]]
path = "/*"
function = "entry.netlify-edge"

View File

@@ -6,9 +6,9 @@
"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/cloudflare-pages/vite.config.ts",
"build.server": "vite build -c adaptors/netlify-edge/vite.config.ts",
"build.types": "tsc --incremental --noEmit",
"deploy": "wrangler pages dev ./dist",
"deploy": "netlify deploy --prod",
"dev": "vite --host --mode ssr",
"dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
"fmt": "prettier --write .",
@@ -20,7 +20,7 @@
"qwik": "qwik"
},
"devDependencies": {
"@builder.io/qwik": "0.15.0",
"@builder.io/qwik": "0.16.1",
"@builder.io/qwik-city": "0.0.128",
"@fontsource/inter": "^4.5.14",
"@iconify-json/tabler": "^1.1.49",
@@ -28,15 +28,18 @@
"@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",
"node-fetch": "3.3.0",
"netlify-cli": "^12.0.11",
"node-fetch": "^3.3.0",
"postcss": "^8.4.19",
"prettier": "2.8.0",
"rehype-autolink-headings": "^6.1.1",
@@ -45,10 +48,9 @@
"typescript": "4.8.4",
"vite": "3.2.4",
"vite-imagetools": "^4.0.11",
"vite-tsconfig-paths": "3.6.0",
"wrangler": "latest"
"vite-tsconfig-paths": "3.6.0"
},
"engines": {
"node": ">=15.0.0"
"node": ">=17.0.0"
}
}

View File

@@ -1,4 +1,2 @@
# https://developers.cloudflare.com/pages/platform/headers/
/build/*
Cache-Control: public, max-age=31536000, s-maxage=31536000, immutable

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

View File

@@ -5,6 +5,7 @@
font-style: normal;
font-named-instance: 'Regular';
src: url('../fonts/Inter-roman-latin.var.woff2') format('woff2');
font-display: swap;
}
@font-face {
@@ -14,6 +15,7 @@
font-style: italic;
font-named-instance: 'Italic';
src: url('../fonts/Inter-italic-latin.var.woff2') format('woff2');
font-display: swap;
}
@font-face {
@@ -22,6 +24,7 @@
font-style: normal;
src: url('../fonts/FiraCode-VF.woff2') format('woff2-variations'),
url('../fonts/FiraCode-VF.woff') format('woff-variations');
font-display: swap;
}
.font-mono {
@@ -34,6 +37,7 @@
font-weight: 400;
font-display: swap;
src: url('../fonts/SourceSansPro-Regular.otf') format('opentype');
font-display: swap;
}
@font-face {
@@ -41,4 +45,5 @@
font-weight: 700;
font-style: normal;
src: url('../fonts/Ubuntu-Mono-bold.woff2') format('woff2');
font-display: swap;
}

View File

@@ -39,6 +39,10 @@
@apply text-xs font-mono bg-stone-100 dark:bg-slate-600 dark:text-white text-red-500 p-1 rounded;
}
.slote video {
@apply rounded drop-shadow-xl w-full md:w-full max-w-screen-md;
}
.slot pre {
@apply w-full flex my-2;
}
@@ -47,6 +51,9 @@
@apply p-3 rounded md:w-full max-w-screen-md overflow-x-auto w-fit bg-gray-800 dark:bg-slate-800 ease-in duration-75 text-gray-100 text-xs shadow-xl;
}
.slot iframe {
@apply rounded ease-in duration-75 text-gray-100 text-xs shadow-xl;
}
.slot a {
@apply text-sky-900 font-medium dark:text-sky-400 dark:hover:text-white;
}

View File

@@ -0,0 +1,17 @@
export const Netlify = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={147}
height={40}
role="img"
fill="currentColor"
>
<g fill-rule="evenodd">
<path d="M53.37 12.978l.123 2.198c1.403-1.7 3.245-2.55 5.525-2.55 3.951 0 5.962 2.268 6.032 6.804v12.568H60.79V19.676c0-1.207-.26-2.1-.78-2.681-.52-.58-1.371-.87-2.552-.87-1.719 0-3 .78-3.84 2.338v13.535h-4.262v-19.02h4.016zM77.748 32.35c-2.7 0-4.89-.852-6.567-2.557-1.678-1.705-2.517-3.976-2.517-6.812v-.527c0-1.898.365-3.595 1.096-5.089.73-1.494 1.757-2.657 3.078-3.49 1.321-.831 2.794-1.247 4.42-1.247 2.583 0 4.58.826 5.988 2.478 1.41 1.653 2.114 3.99 2.114 7.014v1.723h-12.4c.13 1.57.652 2.812 1.57 3.726.918.914 2.073 1.371 3.464 1.371 1.952 0 3.542-.79 4.77-2.373l2.297 2.198c-.76 1.136-1.774 2.018-3.042 2.645-1.269.627-2.692.94-4.27.94zm-.508-16.294c-1.17 0-2.113.41-2.832 1.23-.72.82-1.178 1.963-1.377 3.428h8.12v-.317c-.094-1.43-.474-2.51-1.14-3.243-.667-.732-1.59-1.098-2.771-1.098zm16.765-7.7v4.623h3.35v3.164h-3.35V26.76c0 .726.144 1.25.43 1.573.286.322.798.483 1.535.483a6.55 6.55 0 0 0 1.49-.176v3.305c-.97.27-1.905.404-2.806.404-3.273 0-4.91-1.81-4.91-5.431V16.142H86.62v-3.164h3.122V8.355h4.261zm11.137 23.643h-4.262v-27h4.262v27zm9.172 0h-4.262v-19.02h4.262v19.02zm-4.525-23.96c0-.655.207-1.2.622-1.634.416-.433 1.009-.65 1.78-.65.772 0 1.368.217 1.79.65.42.434.63.979.63 1.635 0 .644-.21 1.18-.63 1.608-.422.428-1.018.642-1.79.642-.771 0-1.364-.214-1.78-.642-.415-.427-.622-.964-.622-1.608zm10.663 23.96V16.142h-2.894v-3.164h2.894v-1.74c0-2.11.584-3.738 1.753-4.887 1.17-1.148 2.806-1.722 4.91-1.722.749 0 1.544.105 2.386.316l-.105 3.34a8.375 8.375 0 0 0-1.631-.14c-2.035 0-3.052 1.048-3.052 3.146v1.687h3.858v3.164h-3.858v15.856h-4.261zm17.87-6.117l3.858-12.903h4.542l-7.54 21.903c-1.158 3.199-3.122 4.799-5.893 4.799-.62 0-1.304-.106-2.052-.317v-3.305l.807.053c1.075 0 1.885-.196 2.429-.589.543-.392.973-1.051 1.289-1.977l.613-1.635-6.664-18.932h4.595l4.016 12.903z" />
<path
fill-rule="nonzero"
d="M27.887 14.135l-.014-.006c-.008-.003-.016-.006-.023-.013a.11.11 0 0 1-.028-.093l.773-4.726 3.625 3.626-3.77 1.604a.083.083 0 0 1-.033.006h-.015c-.005-.003-.01-.007-.02-.017a1.716 1.716 0 0 0-.495-.381zm5.258-.288l3.876 3.876c.805.806 1.208 1.208 1.355 1.674.022.069.04.138.054.209l-9.263-3.923a.728.728 0 0 0-.015-.006c-.037-.015-.08-.032-.08-.07 0-.038.044-.056.081-.071l.012-.005 3.98-1.684zm5.127 7.003c-.2.376-.59.766-1.25 1.427l-4.37 4.369L27 25.469l-.03-.006c-.05-.008-.103-.017-.103-.062a1.706 1.706 0 0 0-.655-1.193c-.023-.023-.017-.059-.01-.092 0-.005 0-.01.002-.014l1.063-6.526.004-.022c.006-.05.015-.108.06-.108a1.73 1.73 0 0 0 1.16-.665c.009-.01.015-.021.027-.027.032-.015.07 0 .103.014l9.65 4.082zm-6.625 6.801l-7.186 7.186 1.23-7.56.002-.01c.001-.01.003-.02.006-.029.01-.024.036-.034.061-.044l.012-.005a1.85 1.85 0 0 0 .695-.517c.024-.028.053-.055.09-.06a.09.09 0 0 1 .029 0l5.06 1.04zm-8.707 8.707l-.81.81-8.955-12.942a.424.424 0 0 0-.01-.014c-.014-.019-.029-.038-.026-.06 0-.016.011-.03.022-.042l.01-.013c.027-.04.05-.08.075-.123l.02-.035.003-.003c.014-.024.027-.047.051-.06.021-.01.05-.006.073-.001l9.921 2.046a.164.164 0 0 1 .076.033c.013.013.016.027.019.043a1.757 1.757 0 0 0 1.028 1.175c.028.014.016.045.003.078a.238.238 0 0 0-.015.045c-.125.76-1.197 7.298-1.485 9.063zm-1.692 1.691c-.597.591-.949.904-1.347 1.03a2 2 0 0 1-1.206 0c-.466-.148-.869-.55-1.674-1.356L8.028 28.73l2.349-3.643c.011-.018.022-.034.04-.047.025-.018.061-.01.091 0a2.434 2.434 0 0 0 1.638-.083c.027-.01.054-.017.075.002a.19.19 0 0 1 .028.032l8.999 13.058zM7.16 27.863L5.098 25.8l4.074-1.738a.084.084 0 0 1 .033-.007c.034 0 .054.034.072.065a2.91 2.91 0 0 0 .13.184l.013.016c.012.017.004.034-.008.05l-2.25 3.493zm-2.976-2.976l-2.61-2.61c-.444-.444-.766-.766-.99-1.043l7.936 1.646a.84.84 0 0 0 .03.005c.049.008.103.017.103.063 0 .05-.059.073-.109.092l-.023.01-4.337 1.837zM.13 19.892a2 2 0 0 1 .09-.495c.148-.466.55-.868 1.356-1.674l3.34-3.34a2175.525 2175.525 0 0 0 4.626 6.687c.027.036.057.076.026.106-.146.161-.292.337-.395.528a.16.16 0 0 1-.05.062c-.013.008-.027.005-.042.002h-.002L.129 19.891zm5.68-6.403l4.49-4.491c.423.185 1.96.834 3.333 1.414 1.04.44 1.988.84 2.286.97.03.012.057.024.07.054.008.018.004.041 0 .06a2.003 2.003 0 0 0 .523 1.828c.03.03 0 .073-.026.11l-.014.021-4.56 7.063c-.012.02-.023.037-.043.05-.024.015-.058.008-.086.001a2.274 2.274 0 0 0-.543-.074c-.164 0-.342.03-.522.063h-.001c-.02.003-.038.007-.054-.005a.21.21 0 0 1-.045-.051l-4.808-7.013zm5.398-5.398l5.814-5.814c.805-.805 1.208-1.208 1.674-1.355a2 2 0 0 1 1.206 0c.466.147.869.55 1.674 1.355l1.26 1.26L18.7 9.94a.155.155 0 0 1-.041.048c-.025.017-.06.01-.09 0a2.097 2.097 0 0 0-1.92.37c-.027.028-.067.012-.101-.003-.54-.235-4.74-2.01-5.341-2.265zm12.506-3.676l3.818 3.818-.92 5.698v.015a.135.135 0 0 1-.008.038c-.01.02-.03.024-.05.03a1.83 1.83 0 0 0-.548.273.154.154 0 0 0-.02.017c-.011.012-.022.023-.04.025a.114.114 0 0 1-.043-.007l-5.818-2.472-.011-.005c-.037-.015-.081-.033-.081-.071a2.198 2.198 0 0 0-.31-.915c-.028-.046-.059-.094-.035-.141l4.066-6.303zM19.78 13.02l5.454 2.31c.03.014.063.027.076.058a.106.106 0 0 1 0 .057c-.016.08-.03.171-.03.263v.153c0 .038-.039.054-.075.069l-.011.004c-.864.369-12.13 5.173-12.147 5.173-.017 0-.035 0-.052-.017-.03-.03 0-.072.027-.11a.76.76 0 0 0 .014-.02l4.482-6.94.008-.012c.026-.042.056-.089.104-.089l.045.007c.102.014.192.027.283.027.68 0 1.31-.331 1.69-.897a.16.16 0 0 1 .034-.04c.027-.02.067-.01.098.004zm-6.246 9.185l12.28-5.237s.018 0 .035.017c.067.067.124.112.179.154l.027.017c.025.014.05.03.052.056 0 .01 0 .016-.002.025L25.054 23.7l-.004.026c-.007.05-.014.107-.061.107a1.729 1.729 0 0 0-1.373.847l-.005.008c-.014.023-.027.045-.05.057-.021.01-.048.006-.07.001l-9.793-2.02c-.01-.002-.152-.519-.163-.52z"
/>
</g>
</svg>
)

View File

@@ -0,0 +1,27 @@
export const Qwik = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="147"
height="40"
role="img"
fill="currentColor"
viewBox="0 0 649 201"
>
<path
fill="#18B6F6"
d="m153.3 186.54-29.35-29.2-.42.07v-.3L61.12 95.37l15.41-14.85-9.06-51.93-42.89 53.2c-7.28 7.36-8.68 19.39-3.4 28.21l26.8 44.49c4.1 6.82 10.54 11.2 19.53 10.88 19.03-.67 27.4-.67 27.4-.67l58.37 21.81.02.02Z"
/>
<path
fill="#AC7EF4"
d="M167.8 104.72c4.23-8.72 5.74-16.35 1.57-24l-5.93-10.92-3.08-5.6-1.2-2.2-.1.14-16.15-28A22.57 22.57 0 0 0 123.1 22.8l-14.16.4-42.25.11A22.66 22.66 0 0 0 47.31 34.5L21.64 85.48l45.94-57.15 60.27 66.27-10.8 10.93 6.45 51.84.09-.1v.14h-.1l.14.13 5.02 4.9 24.3 23.74c1.03.98 2.68-.2 2-1.42l-15.02-29.57"
/>
<path
fill="#fff"
d="M127.99 94.43 67.56 28.5l8.59 51.64-15.38 14.92 62.62 62.23-5.64-51.66 10.24-11.17v-.02Z"
/>
<path
stroke-linejoin="round"
d="M319.08 188.1c.83 0 1.5-.68 1.5-1.5V61.78a1.5 1.5 0 0 0-1.03-1.43c-12.58-4.07-26.24-6.1-41.15-6.1-15.89 0-27.69 3.7-35.21 11.61l-.01.02c-7.34 7.9-10.8 21.53-10.8 39.7 0 18.12 2.9 31.18 9.08 38.73 6.24 7.58 16.04 11.12 28.9 11.12a45.6 45.6 0 0 0 24.04-6.58v37.75c0 .82.68 1.5 1.5 1.5h23.18Zm-24.7-110.05V124c0 1.83-1.37 3.8-4.4 5.4-2.97 1.57-7.24 2.59-12.16 2.59-7.63 0-12.35-1.95-15.04-5.44-1.36-1.75-2.43-4.37-3.16-8.01-.73-3.63-1.09-8.18-1.09-13.7 0-5.86.41-10.72 1.19-14.61.77-3.9 1.9-6.73 3.27-8.58 2.68-3.62 7.73-5.58 15.4-5.58 5.83 0 11.16.62 16 1.98Zm57.89-21.23h-23.52a1.5 1.5 0 0 0-1.4 2.02c10.56 28.23 20.4 59.2 29.52 93.1a1.5 1.5 0 0 0 1.44 1.1h27.18c.64 0 1.2-.4 1.42-1a553.09 553.09 0 0 0 16.4-54.94c5.8 21.37 10.17 39.52 13 54.72a1.5 1.5 0 0 0 1.48 1.23h27.18a1.5 1.5 0 0 0 1.39-.94 1032.42 1032.42 0 0 0 32.34-93.37 1.5 1.5 0 0 0-1.44-1.92h-22.8a1.5 1.5 0 0 0-1.46 1.13c-4.94 19.41-11.47 40.57-19.74 63.65a683.17 683.17 0 0 0-18.07-63.76 1.5 1.5 0 0 0-1.42-1.02H393.5c-.69 0-1.3.47-1.45 1.15a745.57 745.57 0 0 1-18.45 63.76 795.63 795.63 0 0 0-19.84-63.7 1.5 1.5 0 0 0-1.48-1.21h-.02ZM490 58.34v93.23c0 .83.68 1.5 1.5 1.5h23.18c.83 0 1.5-.67 1.5-1.5V58.34c0-.83-.67-1.5-1.5-1.5h-22.93a1.5 1.5 0 0 0-1.74 1.48v.02Zm-1.63-25.93c0 5.22.7 9.05 3.2 11.46 2.48 2.4 6.33 3 11.44 3 5.1 0 8.96-.6 11.44-3 2.5-2.41 3.2-6.24 3.2-11.46 0-4.7-.71-8.2-3.27-10.39-2.47-2.1-6.3-2.62-11.37-2.62-5.08 0-8.9.52-11.37 2.62-2.56 2.18-3.27 5.69-3.27 10.39Zm135.61 24.41h-26.81c-.5 0-.95.24-1.23.64a669.19 669.19 0 0 1-21.85 29.9c-4.19 5.32-7.48 9.12-9.91 11.48V18c0-.83-.67-1.5-1.5-1.5H539.5c-.83 0-1.5.67-1.5 1.5v133.57c0 .83.67 1.5 1.5 1.5h23.18c.83 0 1.5-.67 1.5-1.5V104.9c.67.57 1.44 1.3 2.32 2.24 1.97 2.1 4.4 5.06 7.36 9.03 5.92 7.92 13.93 19.7 24.78 36.21.28.42.75.68 1.26.68h26.64a1.5 1.5 0 0 0 1.28-2.28c-8.77-14.54-16.69-26.35-23.08-34.98-3.2-4.3-6.03-7.83-8.4-10.5a47.47 47.47 0 0 0-4.28-4.35c3.17-2.84 7.23-7.37 12.18-13.51a566.95 566.95 0 0 0 20.85-28.1 1.5 1.5 0 0 0-1.09-2.53h-.02Z"
/>
</svg>
)

View File

@@ -0,0 +1,61 @@
export const Social = () => {
return (
<>
{/* <title>
💻 Conviértete en un Programador Backend aprendiendo todo de
Cloud y Nodejs
</title>
<meta
property="og:site_name"
content="💻 Conviértete en un Programador Backend aprendiendo todo de Cloud y Nodejs"
/>
<meta
name="description"
content="🚀 Comienza haciendo tus despliegues directamente a la Nube. 🙌 Qué esperas mejorar tus habilidades en la programación ahora mismo."
/>
<meta property="og:type" content="website" />
<meta
name="keywords"
content="cursos programacion, cursos backend, curso de aws, curso de cloud computing, curso de node, curso de typescript, curso de api rest con node, curso de api rest con mongo, curso de api rest con aws"
/>
<meta
property="og:title"
content="💻 Conviértete en un Programador Backend aprendiendo todo de Cloud Computing y Nodejs"
/>
<meta
property="og:description"
content="🚀 Comienza haciendo tus despliegues directamente a la Nube. 🙌 Qué esperas mejorar tus habilidades en la programación ahora mismo."
/>
<meta property="og:type" content="article" />
<meta property="og:locale" content="es_ES" />
<meta
property="og:url"
content="https://campaign.codigoencasa.com"
/>
<meta property="og:site_name" content="campaign.codigoencasa.com" /> */}
<meta
property="og:image"
content="https://i.imgur.com/0HpzsEm.png"
></meta>
<meta
property="og:image:secure_url"
content="https://i.imgur.com/0HpzsEm.png"
/>
<meta property="og:image:type" content="image/png"></meta>
<meta property="og:image:width" content="1200"></meta>
<meta property="og:image:height" content="630"></meta>
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@LeiferMendez" />
<meta
name="twitter:title"
content="💻 Conviértete en un Programador Backend aprendiendo todo de Cloud y Nodejs"
/>
<meta
name="twitter:image"
content="https://i.imgur.com/0HpzsEm.png"
/>
</>
)
}

View File

@@ -1,17 +1,23 @@
import { component$ } from '@builder.io/qwik'
import { $, component$, QwikMouseEvent } from '@builder.io/qwik'
export const handleVideo = $((ev: QwikMouseEvent<HTMLVideoElement>) => {
const targetVideo = ev.target as HTMLVideoElement
targetVideo.play()
})
export default component$(() => {
return (
<section class="relative">
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<div class="py-12 md:py-20">
<section class="relative ">
<div class="max-w-6xl mx-auto px-4 sm:px-6 ">
<div class="py-0 md:py-5">
<video
class={'cursor-pointer'}
onClick$={handleVideo}
style={'height:600px'}
width="100%"
height="400"
autoPlay
muted
loop
playsInline
>
<source

View File

@@ -0,0 +1,32 @@
import { component$ } from '@builder.io/qwik'
export default component$(
(props: {
user: {
id: number
login: string
html_url: string
avatar_url: string
}
}) => {
return (
<figure class="bg-gray-50 rounded p-4 dark:bg-slate-800">
<a href={props.user.html_url} target="_blank">
<img
class="w-16 h-16 rounded-full mx-auto object-cover"
src={props.user.avatar_url + '&s=80'}
alt={props.user.login}
width="80"
height="80"
/>
</a>
<div class="pt-2 space-y-4 justify-center flex">
<figcaption class="text-sm">
<div class={'font-semibold'}>{props.user.login}</div>
</figcaption>
</div>
</figure>
)
}
)

View File

@@ -1,46 +1,49 @@
import { component$ } from '@builder.io/qwik'
import { RequestHandlerCloudflarePages } from '@builder.io/qwik-city/middleware/cloudflare-pages'
import { User } from '~/contexts'
import Collaborator from './Collaborator'
export default component$(() => {
export const onRequest: RequestHandlerCloudflarePages = async () => {
console.log('??heree')
}
export const TaleUsers = component$((props: { users: User[] }) => {
return (
<div class={'pt-4'}>
<div class="flex items-center space-x-2 text-base">
<h4 class="font-semibold text-slate-900">Contributors</h4>
<span class="rounded-full bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-700">
204
</span>
</div>
<div class="mt-3 flex -space-x-2 overflow-hidden">
<img
class="inline-block h-12 w-12 rounded-full ring-2 ring-white"
src="https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
alt=""
/>
<img
class="inline-block h-12 w-12 rounded-full ring-2 ring-white"
src="https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
alt=""
/>
<img
class="inline-block h-12 w-12 rounded-full ring-2 ring-white"
src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80"
alt=""
/>
<img
class="inline-block h-12 w-12 rounded-full ring-2 ring-white"
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
alt=""
/>
<img
class="inline-block h-12 w-12 rounded-full ring-2 ring-white"
src="https://images.unsplash.com/photo-1517365830460-955ce3ccd263?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
alt=""
/>
</div>
<div class="mt-3 text-sm font-medium">
<a href="#" class="text-blue-500">
+ 198 others
</a>
</div>
</div>
<>
{props.users.map((user) => (
<div class="col-span-2 ">
{' '}
<Collaborator user={user} />
</div>
))}
</>
)
})
export default component$((props: { users: User[] }) => {
return (
<section class="relative ">
<div class={'px-4 py-16 mx-auto max-w-6xl lg:py-20'}>
<div class="mb-10 md:mx-auto sm:text-center md:mb-12 max-w-3xl">
<p class="text-base text-primary-600 dark:text-purple-200 font-semibold tracking-wide uppercase">
Colaboradores
</p>
<h2 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-4 font-heading">
Super estrellas
</h2>
<p class="max-w-3xl mx-auto sm:text-center text-xl text-gray-600 dark:text-slate-400">
Todo es posible gracias a el mayor recursos de todos, el
recurso humano. Tu tambien puedes{' '}
<a class={'font-semibold'} href="/docs/contributing">
formar parte
</a>
</p>
</div>
<div class="grid lg:grid-cols-12 grid-cols-1 gap-4 ">
<TaleUsers users={props.users} />
</div>
</div>
</section>
)
})

View File

@@ -5,45 +5,36 @@ export default component$(() => {
const items = [
[
{
question: 'What do I need to start?',
answer: `Space, the final frontier. These are the voyages of the Starship Enterprise. Its five-year mission: to explore strange new worlds.
Many say exploration is part of our destiny, but its actually our duty to future generations.`,
question: '¿Que necesitas para iniciar?',
answer: `Deseable tener conocimientos previos en JavaScript o ejecución de proyectos Node. La comunidad siempre se encargará de mantener la documentación lo más clara posible para que con solo unos minutos tengas tu chatbot funcionando correctamente`,
},
{
question: 'How to install the Qwik + Tailwind CSS template?',
answer: `Well, the way they make shows is, they make one show. That show's called a pilot.
Then they show that show to the people who make shows, and on the strength of that one show they decide if they're going to make more shows. Some pilots get picked and become television programs. Some don't, become nothing. She starred in one of the ones that became nothing.`,
question: '¿Es Gratis?',
answer: `Si. Es un proyecto Open Source que ofrece el código para que puedas aplicarlo de manera totalmente gratuita. Siempre destacando el valor aportado por toda la comunidad`,
},
{
question:
"What's something that you completely don't understand?",
answer: `A flower in my garden, a mystery in my panties. Heart attack never stopped old Big Bear. I didn't even know we were calling him Big Bear.`,
question: '¿Funciona en Ubuntu/Windows?',
answer: `El proyecto funciona perfectamente Linux/Windows/Mac. Cabe destacar que dependiendo del sistema operativo será necesario realizar algunos ajustes puntuales. En la documentación se explica más estos casos de usos`,
},
],
[
{
question: "What's an example of when you changed your mind?",
answer: `Michael Knight a young loner on a crusade to champion the cause of the innocent. The helpless. The powerless in a world of criminals who operate above the law. Here he comes Here comes Speed Racer. He's a demon on wheels.`,
question: '¿Existe un plan de pago?',
answer: `Actualmente, no contamos con un plan de pago, las aportaciones económicas recibidas se destinan a gastos en comunes: servidores para pruebas, servicios de api externos, recursos de marketing y diseño, recintos para capacitaciones, entre otras cosas.`,
},
{
question:
'What is something that you would really like to try again?',
answer: `A business big enough that it could be listed on the NASDAQ goes belly up. Disappears!
It ceases to exist without me. No, you clearly don't know who you're talking to, so let me clue you in.`,
question: '¿Riesgos dé bloqueo?',
answer: `Depende. Esta librería es una capa superior agnóstica al proveedor que facilita el escribir flujos de conversación. Esto significa que la conexión con "Whatsapp" es delegada al proveedor de turno, el cual dependiendo de cuál elijas, puede tener limitaciones o riesgos. Ver más información`,
},
{
question:
'If you could only ask one question to each person you meet, what would that question be?',
answer: `This is not about revenge. This is about justice. A lot of things can change in twelve years, Admiral. Well, that's certainly good to know. About four years. I got tired of hearing how young I looked.`,
question: '¿Casos de usos?',
answer: `Basado en los relatos compartidos por la comunidad, hasta el momento hemos registrado más de 100 casos de usos. Los más populares suelen ser: asistencia técnica. (preguntas y respuestas), gestión de pedidos de restaurantes, chatbot con inteligencia artificial gracias a dialogflow`,
},
],
]
return (
<section class="border-t border-gray-200 dark:border-slate-800">
<section class="">
<div class="px-4 py-16 mx-auto max-w-6xl lg:py-20">
<div class="max-w-xl sm:mx-auto lg:max-w-2xl">
<div class="max-w-xl mb-10 md:mx-auto sm:text-center lg:max-w-2xl md:mb-12">
@@ -61,10 +52,10 @@ export default component$(() => {
<div class="space-y-8">
{subitems.map(({ question, answer }) => (
<div>
<p class="mb-4 text-xl font-bold">
<IconArrowDownRight class="w-7 h-7 text-secondary-500 inline-block" />
<div class="mb-4 text-xl font-bold">
<IconArrowDownRight class="w-7 h-7 text-primary-600 inline-block" />
{question}
</p>
</div>
{answer
.split('\n\n')
.map((paragraph) => (

View File

@@ -15,14 +15,14 @@ export default component$(() => {
'Se pueden automatizar tareas repetitivas y ahorrar tiempo y esfuerzo en tareas administrativas, como enviar recordatorios a tus clientes sobre pagos pendientes o para confirmar citas o reservas.',
},
{
title: 'Experiencia personalizada para tus clientes',
title: 'Experiencia personalizada',
description:
'Podrás enviar mensajes automatizados con ofertas especiales o recomendaciones de productos basadas en el historial de compras de tus clientes, lo que significa que tus clientes pueden recibir una experiencia más personalizada.',
},
],
[
{
title: 'Análisis de datos y toma de decisiones informadas',
title: 'Análisis de datos',
description:
'Te permite recopilar y analizar datos sobre tus clientes para ayudarte a entender mejor sus necesidades y preferencias, y ofrecerles un servicio aún más destacado.',
icon: 'tabler:rocket',

View File

@@ -2,50 +2,20 @@ import { component$ } from '@builder.io/qwik'
import { Link } from '@builder.io/qwik-city'
import { IconTwitter } from '~/components/icons/IconTwitter'
import { IconInstagram } from '~/components/icons/IconInstagram'
import { IconFacebook } from '~/components/icons/IconFacebook'
import { IconGithub } from '~/components/icons/IconGithub'
import { Netlify } from '../atoms/Netlify'
export default component$(() => {
const links = [
{
title: 'Product',
items: [
{ title: 'Features', href: '#' },
{ title: 'Security', href: '#' },
],
},
{
title: 'Platform',
items: [
{ title: 'Developer API', href: '#' },
{ title: 'Partners', href: '#' },
],
},
{
title: 'Support',
items: [
{ title: 'Docs', href: '#' },
{ title: 'Community Forum', href: '#' },
],
},
{
title: 'Company',
items: [
{ title: 'About', href: '#' },
{ title: 'Blog', href: '#' },
],
},
]
const social = [
{ label: 'Twitter', icon: IconTwitter, href: '#' },
{ label: 'Instagram', icon: IconInstagram, href: '#' },
{ label: 'Facebook', icon: IconFacebook, href: '#' },
{
label: 'Twitter',
icon: IconTwitter,
href: 'https://twitter.com/leifermendez',
},
{
label: 'Github',
icon: IconGithub,
href: 'https://github.com/onwidget/qwind',
href: 'https://github.com/codigoencasa/bot-whatsapp',
},
]
@@ -54,36 +24,15 @@ export default component$(() => {
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<div class="grid grid-cols-12 gap-4 gap-y-8 sm:gap-8 py-8 md:py-12">
<div class="col-span-12 lg:col-span-4 pr-8">
<div class="text-sm text-gray-600 dark:text-gray-400">
Nos sentimos muy afortunados de poder contribuir a
este proyecto y esperamos poder seguir trabajando
juntos para ayudar a los pequeños comercios a
impulsar sus ventas y fortalecer la economía local.
<div class="text-sm text-gray-600 dark:text-gray-400"></div>
</div>
<div class="col-span-12 flex justify-center lg:col-span-4 pr-8">
<div class={'flex flex-col justify-center gap-1'}>
<a target={'_blank'} href="https://www.netlify.com">
<Netlify />
</a>
</div>
</div>
{links.map(({ title, items }) => (
<div class="col-span-6 md:col-span-3 lg:col-span-2">
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">
{title}
</div>
{items &&
Array.isArray(items) &&
items.length > 0 && (
<ul class="text-sm">
{items.map(({ title, href }) => (
<li class="mb-2">
<Link
class="text-gray-600 hover:text-gray-700 hover:underline dark:text-gray-400 transition duration-150 ease-in-out"
href={href}
>
{title}
</Link>
</li>
))}
</ul>
)}
</div>
))}
</div>
<div class="md:flex md:items-center md:justify-between py-6 md:py-8">
<ul class="flex mb-4 md:order-1 -ml-2 md:ml-4 md:mb-0">
@@ -101,7 +50,7 @@ export default component$(() => {
))}
</ul>
<div class="text-sm text-gray-700 mr-4 dark:text-slate-400">
{/* <div class="text-sm text-gray-700 mr-4 dark:text-slate-400">
<span class="w-5 h-5 md:w-6 md:h-6 md:-mt-0.5 bg-cover mr-1.5 float-left rounded-sm bg-[url(https://onwidget.com/favicon/favicon-32x32.png)]"></span>
Made by{' '}
<a
@@ -112,7 +61,7 @@ export default component$(() => {
onWidget
</a>{' '}
· All rights reserved.
</div>
</div> */}
</div>
</div>
</footer>

View File

@@ -45,9 +45,12 @@ export default component$(() => {
>
<ul class="flex flex-col pt-8 md:pt-0 md:flex-row md:self-center w-full md:w-auto text-xl md:text-base">
<li class="dropdown">
<button class="font-medium hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out">
<a
href="/docs"
class="font-medium hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
>
Documentación
</button>
</a>
<ul class="dropdown-menu rounded md:absolute pl-4 md:pl-0 md:hidden font-medium md:bg-white md:min-w-[200px] dark:md:bg-slate-800 drop-shadow-xl">
{store.map((ctx) => {
return ctx.list.map((listCtx) => {

View File

@@ -26,10 +26,10 @@ export default component$(() => {
</h1>
<div class="max-w-3xl mx-auto">
<p class="text-xl text-gray-600 mb-8 dark:text-slate-400">
<span class="font-semibold underline decoration-wavy decoration-1 decoration-secondary-600 underline-offset-2">
<span class="font-semibold ">
Con esta libreria,{' '}
</span>
<span class="font-semibold underline decoration-wavy decoration-1 decoration-secondary-600 underline-offset-2">
<span class="font-semibold ">
puedes configurar respuestas
automatizadas para preguntas frecuentes
</span>{' '}
@@ -52,7 +52,7 @@ export default component$(() => {
href="/docs"
class="btn bg-gray-50 dark:bg-transparent"
>
Más información
Ver documentación
</a>
</div>
</div>

View File

@@ -5,6 +5,8 @@ import { useLocation } from '@builder.io/qwik-city'
import { src as qwik } from '~/assets/images/qwik.png?width=100&metadata'
// @ts-ignore
import { src as leanga } from '~/assets/images/leanga.png?width=40&metadata'
// @ts-ignore
import { src as netlify } from '~/assets/images/full-logo-light.png?width=100&metadata'
/**
* options = [] array con la lista de opciones de la documentacion
@@ -33,6 +35,19 @@ export default component$(() => {
</picture>
</a>
</li>
<li>
<a target={'_blank'} href="https://www.netlify.com">
<picture>
<img
src={netlify}
class="border border-slate-200 rounded my-2 p-1 bg-gray-50 dark:border-gray-600 dark:bg-gray-700"
alt="Qwind Hero Image (Cool dog)"
loading="eager"
decoding="async"
/>
</picture>
</a>
</li>
<li>
<a target={'_blank'} href="https://leangasoftware.es/">
<picture>

View File

@@ -6,7 +6,12 @@ export interface DocumentationCtx {
list: { link: string; name: string }[]
}
export interface User {
id: number
login: string
html_url: string
avatar_url: string
}
export const GlobalStore =
createContext<DocumentationCtx[]>('documentation-site')
export const AppSetting = createContext<{ repo: string }>('app-settings')

View File

@@ -0,0 +1,50 @@
/*
* WHAT IS THIS FILE?
*
* It's the entry point for the express server when building for production.
*
* Learn more about the cloudflare integration here:
* - https://qwik.builder.io/qwikcity/adaptors/node/
*
*/
import { createQwikCity } from '@builder.io/qwik-city/middleware/node'
import qwikCityPlan from '@qwik-city-plan'
import render from './entry.ssr'
import express from 'express'
import { fileURLToPath } from 'node:url'
import { join } from 'node:path'
import compression from 'compression'
// Directories where the static assets are located
const distDir = join(fileURLToPath(import.meta.url), '..', '..', 'dist')
const buildDir = join(distDir, 'build')
// Allow for dynamic port
const PORT = process.env.PORT ?? 3000
// Create the Qwik City express middleware
const { router, notFound } = createQwikCity({ render, qwikCityPlan })
// Create the express server
// https://expressjs.com/
const app = express()
// Enable gzip compression
app.use(compression())
// Static asset handlers
// https://expressjs.com/en/starter/static-files.html
app.use(`/build`, express.static(buildDir, { immutable: true, maxAge: '1y' }))
app.use(express.static(distDir, { redirect: false }))
// Use Qwik City's page and endpoint request handler
app.use(router)
// Use Qwik City's 404 handler
app.use(notFound)
// Start the express server
app.listen(PORT, () => {
/* eslint-disable */
console.log(`Server starter: http://localhost:${PORT}/`)
})

View File

@@ -0,0 +1,14 @@
/*
* WHAT IS THIS FILE?
*
* It's the entry point for netlify-edge when building for production.
*
* Learn more about the cloudflare integration here:
* - https://qwik.builder.io/qwikcity/adaptors/netlify-edge/
*
*/
import { createQwikCity } from '@builder.io/qwik-city/middleware/netlify-edge'
import qwikCityPlan from '@qwik-city-plan'
import render from './entry.ssr'
export default createQwikCity({ render, qwikCityPlan })

View File

@@ -16,6 +16,7 @@ import { DarkThemeLauncher } from '~/components/core/DarkThemeLauncher'
import fontStyles from '~/assets/styles/fonts.css?inline'
import globalStyles from '~/assets/styles/global.css?inline'
import { DocumentationCtx, GlobalStore } from './contexts'
import { Social } from './components/core/Social'
export default component$(() => {
/**
@@ -33,6 +34,7 @@ export default component$(() => {
title: 'Primeros pasos',
list: [
{ name: 'Vista rápida', link: '/docs' },
{ name: 'Requerimientos', link: '/docs/requirements' },
{ name: 'Instalación', link: '/docs/install' },
{ name: 'Pruebalo', link: '/docs/example' },
],
@@ -57,6 +59,7 @@ export default component$(() => {
title: 'Comunidad',
list: [
{ name: 'MasterClass', link: '/docs/masterclass' },
{ name: 'Colabores', link: '/docs/contributing' },
{ name: 'Unirme al proyecto', link: '/docs/join' },
{ name: 'Sponsors', link: '/docs/sponsors' },
],
@@ -77,6 +80,7 @@ export default component$(() => {
<RouterHead />
<DarkThemeLauncher />
<Social />
</head>
<body class="text-gray-900 dark:text-slate-300 tracking-tight bg-white dark:bg-gray-900 antialiased">
<RouterOutlet />

View File

@@ -0,0 +1 @@
export const GITHUB_TOKEN = import.meta.env.VITE_GITHUB_TOKEN ?? 'SIN_TOKEN'

View File

@@ -1 +0,0 @@
# Personas que quieran unirse

View File

@@ -0,0 +1,121 @@
# Colaboradores
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/Mf9V-dloBfk"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
### 📄 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)
---
![](https://i.giphy.com/media/ntMt6TvalpstTIx7Ak/giphy.webp)
**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.
- **[VSCode](https://code.visualstudio.com/download)** (recomendado): Editor de código con plugins.
- **[Conventional Commits](https://marketplace.visualstudio.com/items?itemName=vivaxy.vscode-conventional-commits&ssr=false#overview)** (plugin-vscode) este plugin te ayudará a crear commit semántico.
- Se usará la rama **dev** _(https://github.com/leifermendez/bot-whatsapp/tree/dev)_ como rama principal hasta que se haga oficialmente el lanzamiento de la V2.
### 🚀 Iniciando
**Clonar repo rama dev**
```
git clone --branch dev https://github.com/codigoencasa/bot-whatsapp
```
**Instalar dependencias**
```
cd bot-whatsapp
yarn install
```
**Compilar (build)**
Para compilar la aplicación es necesario ejecutar este comando, el cual genera un directorio `lib` dentro de los paquetes del monorepo.
```
yarn build
```
**Example-app**
Se ejecuta el CLI (Command Line Interface) para ayudarte a crear un app-bot de ejemplo.
```
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:
```
"@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
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'
```
![](https://i.imgur.com/dC6lEwy.png)
> **NOTA:** [Eres libre de aportar informacion a este documento o arreglar ortografia 🤣](https://github.com/codigoencasa/bot-whatsapp/edit/dev/CONTRIBUTING.md)
---
- [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)

View File

@@ -1,4 +1,5 @@
import Alert from '../../../components/widgets/Alert'
import Navigation from '../../../components/widgets/Navigation'
# DataBase (Base de datos)
@@ -30,3 +31,12 @@ Los conectores disponibles hasta el momento son los siguientes:
`require('@bot-whatsapp/database/mysql')`
`require('@bot-whatsapp/database/json')`
---
<Navigation
pages={[
{ name: 'Proveedores', link: '/docs/providers' },
{ name: 'Migración', link: '/docs/migration' },
]}
/>

View File

@@ -1,4 +1,5 @@
import Alert from '../../../components/widgets/Alert'
import Navigation from '../../../components/widgets/Navigation'
# Conceptos
@@ -97,3 +98,12 @@ Los conectores disponibles hasta el momento son los siguientes:
`require('@bot-whatsapp/database/mysql')`
`require('@bot-whatsapp/database/json')`
---
<Navigation
pages={[
{ name: 'Pruebalo', link: '/docs/example' },
{ name: 'Conversaciones', link: '/docs/flows' },
]}
/>

View File

@@ -1,3 +1,5 @@
import Navigation from '../../../components/widgets/Navigation'
# Ejemplo
Si copias y pegas este codigo y tu entorno de trabajo cumple con todos los requesitos te debe funcionar abajo explico muy por encima
@@ -66,3 +68,12 @@ const flowPrincipal = addKeyword(['hola', 'alo'])
.addAnswer(['Hola, bienvenido a mi tienda', '¿Como puedo ayudarte?'])
.addAnswer(['Tengo:', 'Zapatos', 'Bolsos', 'etc ...'])
```
---
<Navigation
pages={[
{ name: 'Instalación', link: '/docs/install' },
{ name: 'Conceptos', link: '/docs/essential' },
]}
/>

View File

@@ -1,3 +1,5 @@
import Navigation from '../../../components/widgets/Navigation'
# Flow (Flujos)
Los flujos hacen referencia al hecho de construir un flujo de conversación. Estos son flows y en ellos podemos observar que estan presente dos metodos importantes **addKeyword** y el **addAnswer**.
@@ -18,3 +20,12 @@ const flowPrincipal = addKeyword(['hola', 'alo'])
.addAnswer(['Hola, bienvenido a mi tienda', '¿Como puedo ayudarte?'])
.addAnswer(['Tengo:', 'Zapatos', 'Bolsos', 'etc ...'])
```
---
<Navigation
pages={[
{ name: 'Conceptos', link: '/docs/essential' },
{ name: 'Proveedores', link: '/docs/providers' },
]}
/>

View File

@@ -1,20 +1,21 @@
import Alert from '../../components/widgets/Alert'
import Navigation from '../../components/widgets/Navigation'
# Introducción
<Alert>
**Atención** estás leyendo la documentación de la **versión estable
(0.2.x)** de esta librería, si vienes de la versión anterior te recomendamos
pasarte por la sección de **[migración](/docs/migration/)** para que puedas
disfrutar de las nuevas características.
**Atención** estás leyendo la documentación de la **versión v2** de esta
librería, si vienes de la versión anterior te recomendamos pasarte por la
sección de **[migración](/docs/migration/)** para que puedas disfrutar de
las nuevas características.
</Alert>
## ¿Que es esto?
## ¿Qué es esto?
**@bot-whatsapp** es una librería que te permitirá **crear chatbot para WhatsApp** en tan solo minutos de una manera ágil y rápida. A lo largo de esta documentación encontrarás ejemplos y material de ayuda.
Si eres una persona con **poco tiempo y gran capacidad** de comprensión con conocimientos, ejecutando proyectos en Node.js y manejo de terminal.
Esta documentación te ayudará a instalar tu bot de WhatsApp en simples pasos con el propósito de que tengas un chatbot funcional **en solo minutos.**
Si eres una persona con **poco tiempo y gran capacidad** de comprensión, con conocimientos ejecutando proyectos en Node.js y manejo de terminal.
Esta documentación te ayudará a instalar tu bot de WhatsApp en simples pasos; con el propósito de que tengas un chatbot funcional **en solo minutos.**
---
@@ -40,5 +41,14 @@ npm create bot-whatsapp@latest
</video>
</div>
**¿Algun error?**
Recuerda que debes de cumplir con los [requisitos minimos](/docs/install) del sistema
**¿Algún error?**
Recuerda que debes de cumplir con los [requisitos minimos](/docs/requirements) del sistema
---
<Navigation
pages={[
{ name: 'Home', link: '/' },
{ name: 'Requerimientos', link: '/docs/requirements' },
]}
/>

View File

@@ -1,32 +1,27 @@
import Alert from '../../../components/widgets/Alert'
import Navigation from '../../../components/widgets/Navigation'
# Instalación
A continuación se describen los puntos técnicos que debes de tener en cuenta antes de trabajar con esta herramienta
**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.
## Requerimientos
---
- Node v16 o superior **[descargar node](https://nodejs.org/es/download/)**
### Comenzamos
## ¿Como saber que tengo el Node?
Solo debes ejecutar el siguiente comando y esperar que la versión que te arroja sea superior a v16
Crear un bot es tan sencillo como ejecutar el siguiente comando y seguir las instrucciones
```shell
$ node -v
v18.12.1
npm create bot-whatsapp@latest
```
## Opcionales
_Para seleccionar usa la tecla de **espacio** y para confirmar la tecla **enter**_
Dependiendo de las opciones de configuraciones que has marcado al momento de crear el bot **Command Line Interface (CLI)** puede que necesites instalar más cosas.
El **CLI** te hace una revisión previa, de versión de Node y sistema operativo, con la finalidad de informarte si cumples los requisitos o mostrarte información de interés.
**Ejemplo**: Si elegiste _(MySQL)_ como proveedor de base de datos, lógicamente necesitaras tener un entorno de MySQL.
📄 Pronto se agregará más información y videos explicando esto a fondo.
<div class="my-4 w-full ">
<div class="my-4 ">
<video
class="rounded drop-shadow-xl rounded "
width="100%"
class="rounded drop-shadow-xl w-full md:w-full max-w-screen-md"
height="100%"
autoplay
loop
@@ -39,3 +34,37 @@ Dependiendo de las opciones de configuraciones que has marcado al momento de cre
/>
</video>
</div>
### Plantilla
Luego de seleccionar las opciones de tu preferencia se creara una carpeta con una plantilla de un flujo de un bot listo para ejecutar y que puedes modificar a tu gusto.
**[Ver más plantillas](https://github.com/codigoencasa/bot-whatsapp/tree/dev/starters/apps)**
Cada plantilla tiene sus dependencias necesarias basadas en tu previa selección. **Ejemplo**, si seleccionas el proveedor de MySQL, la plantilla incorpora lo necesario para que tu conexión con la base de datos sea exitosa.
```json
"dependencies": {
"@bot-whatsapp/bot": "latest",
"@bot-whatsapp/cli": "latest",
"@bot-whatsapp/database": "latest",
"@bot-whatsapp/provider": "latest",
"@adiwajshing/baileys": "4.4.0",
"mysql2": "^2.3.3", 👈
},
```
<Alert>
📄 Si deseas cambiar tu **proveedor o tu motor** de base de datos no es
necesario volver ejecutar el CLI (lo puedes hacer sin problema) aunque
tambien basta con solo modificar un par de lineas. [Ver
explicación](/docs/essential)
</Alert>
---
<Navigation
pages={[
{ name: 'Requerimientos', link: '/docs/requirements' },
{ name: 'Pruebalo', link: '/docs/example' },
]}
/>

View File

@@ -1,3 +1,25 @@
# Unirme
...
Bienvenido al proyecto! Estamos emocionados de tenerte a bordo y esperamos trabajar contigo.
Deseamos que te sientas cómodo y que puedas aportar tu valioso conocimiento y habilidades.
Recuerda que si tienes alguna inquietud, o simplemente deseas interactuar con los otros colaboradores puedes unirte a la comunidad.
---
## Ventajas al unirme
Participar en un proyecto de código abierto te permite aprender de manera práctica sobre tecnologías y metodologías de desarrollo de software. También puedes aprender de otros desarrolladores y contribuir a la comunidad de código abierto.
Al unirte te estará brindando la oportunidad de **adquirir experiencia en el desarrollo de software** y en el trabajo en equipo. Esto puede ser muy valioso para tu currículum y para tu carrera profesional.
La visibilidad es uno de los puntos que más se requieren hoy en día, al unirte se te brinda la oportunidad de **mayor visibilidad en la comunidad de desarrolladores y de demostrar tus habilidades**. Esto puede ayudarte a encontrar oportunidades de trabajo o a colaborar con otros proyectos.
Colaboración con otros desarrolladores de todo el mundo y **trabajar juntos para mejorar el proyecto** Al trabajar en equipo y colaborar con otros, podrás mejorar tu comunicación, resolución de problemas y liderazgo, habilidades que cada vez son más demandadas en el entorno laboral.
Contribución al bien común Participar en un proyecto de código abierto te permite contribuir a la comunidad y a la sociedad en general, ya que el código abierto es accesible y utilizable por cualquier persona. **Esto puede ser muy gratificante y sentirte parte de algo más grande**.
Es una excelente manera de incrementar tus habilidades tecnológicas y **estar al tanto de las últimas tendencias y desarrollos en el mundo del software**. Al trabajar con otros desarrolladores y contribuir a proyectos de código abierto, tendrás la oportunidad de \*\*aprender y practicar nuevas tecnologías y metodologías, lo que te ayudará a mejorar tus habilidades y a mantenerte actualizado en el mundo en constante cambio de la tecnología.
Esperamos que estés listo para **unirte a nosotros en esta emocionante aventura**

View File

@@ -1,7 +1,6 @@
import { component$, Slot, useContext } from '@builder.io/qwik'
import type { DocumentHead } from '@builder.io/qwik-city'
import ExtraBar from '~/components/widgets/ExtraBar'
import Footer from '~/components/widgets/Footer'
import Header from '~/components/widgets/Header'
import NavBar from '~/components/widgets/NavBar'
import SponsorBar from '~/components/widgets/SponsorBar'
@@ -44,7 +43,6 @@ export default component$(() => {
</div>
</div>
</main>
<Footer />
</>
)
})

View File

@@ -1,3 +1,5 @@
import Navigation from '../../../components/widgets/Navigation'
# Migración
#### Versión (legacy)
@@ -199,9 +201,11 @@ const flowPrincipal = addKeyword(['hola', 'ole', 'alo'])
)
```
> 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)
<Navigation
pages={[
{ name: 'Base de datos', link: '/docs/database' },
{ name: 'Extender', link: '/docs/custom' },
]}
/>

View File

@@ -1,4 +1,5 @@
import Alert from '../../../components/widgets/Alert'
import Navigation from '../../../components/widgets/Navigation'
# Provider (Proveedor)
@@ -29,3 +30,12 @@ Los proveedores disponibles hasta el momento son los siguientes:
[Meta Official](https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages) `require('@bot-whatsapp/provider/meta')`
[Twilio Official](https://www.twilio.com/es-mx/messaging/whatsapp) `require('@bot-whatsapp/provider/twilio')`
---
<Navigation
pages={[
{ name: 'Conversaciones', link: '/docs/flows' },
{ name: 'Base de datos', link: '/docs/database' },
]}
/>

View File

@@ -0,0 +1,34 @@
import Navigation from '../../../components/widgets/Navigation'
# Requerimientos
A continuación se describen los puntos técnicos que debes de tener en cuenta antes de trabajar con esta herramienta
- Node v16 o superior **[descargar node](https://nodejs.org/es/download/)**
---
## ¿Como instalar Node?
- **Windows**: [Ver video](https://youtu.be/xRXHQlqA3Ak?t=376). Necesita ayuda para instalar Node en Windows. A continuación te comparto un video en el minuto exacto donde explico como instalar.
- **Ubuntu**: Te comparto un recurso de **[Digital Ocean](https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-20-04-es)** donde explica como instalar node en Ubuntu.
---
## ¿Como saber que tengo el Node?
Solo debes ejecutar el siguiente comando y esperar que la versión que te arroja sea superior a v16
```shell
$ node -v
v18.12.1
```
---
<Navigation
pages={[
{ name: 'Vista rápida', link: '/docs' },
{ name: 'Instalación', link: '/docs/install' },
]}
/>

View File

@@ -1,20 +1,35 @@
import { component$ } from '@builder.io/qwik'
import type { DocumentHead } from '@builder.io/qwik-city'
import { component$, Resource } from '@builder.io/qwik'
import { DocumentHead, useEndpoint } from '@builder.io/qwik-city'
import Hero from '~/components/widgets/Hero'
import Features from '~/components/widgets/Features'
import FAQs from '~/components/widgets/FAQs'
// import Stats from '~/components/widgets/Stats'
import CallToAction from '~/components/widgets/CallToAction'
import Collaborators from '~/components/widgets/Collaborators'
import { fetchGithub } from '~/services/github'
import { RequestHandlerNetlify } from '@builder.io/qwik-city/middleware/netlify-edge'
import { GITHUB_TOKEN } from './docs/constant'
export const onGet: RequestHandlerNetlify = async ({ platform }) => {
const CHECK_GITHUB_TOKEN =
(platform as any)?.['GITHUB_TOKEN'] ?? GITHUB_TOKEN
console.log(`[🚩 platform]: `, GITHUB_TOKEN)
const data = await fetchGithub(CHECK_GITHUB_TOKEN)
return data
}
export default component$(() => {
const resource = useEndpoint()
return (
<>
<Hero />
<Features />
<CallToAction />
<Resource
value={resource}
onResolved={(data: any) => <Collaborators users={data} />}
></Resource>
<FAQs />
{/* <Stats /> */}
</>
)
})

View File

@@ -0,0 +1,19 @@
/**
* GET API from Github
* @returns
*/
export const fetchGithub = async (token: string) => {
const data = await fetch(
`https://api.github.com/repos/codigoencasa/bot-whatsapp/contributors`,
{
method: 'GET',
headers: {
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
Authorization: `Bearer ${token}`,
},
}
)
const listUsers = data.json()
return listUsers
}

View File

@@ -13,11 +13,6 @@ export default defineConfig(() => {
qwikCity({
basePathname: SITE.basePathname,
trailingSlash: SITE.trailingSlash,
mdxPlugins: {
rehypeSyntaxHighlight: true,
rehypeAutolinkHeadings: false,
remarkGfm: true,
},
}),
qwikVite(),
tsconfigPaths(),

View File

@@ -1,6 +1,6 @@
{
"name": "@bot-whatsapp/provider",
"version": "0.0.31-alpha.0",
"version": "0.0.46-alpha.0",
"description": "Esto es el conector a Twilio, Meta, etc...",
"main": "./lib/mock/index.cjs",
"keywords": [],
@@ -12,7 +12,8 @@
"dependencies": {
"@bot-whatsapp/bot": "*",
"combine-image": "^1.0.3",
"qr-image": "^3.2.0"
"qr-image": "^3.2.0",
"rimraf": "^3.0.2"
},
"exports": {
"./mock": "./lib/mock/index.cjs",

View File

@@ -1,25 +1,32 @@
const { ProviderClass } = require('@bot-whatsapp/bot')
const { Sticker } = require('wa-sticker-formatter')
const pino = require('pino')
const rimraf = require('rimraf')
const mime = require('mime-types')
const { join } = require('path')
const { existsSync, createWriteStream } = require('fs')
const { Console } = require('console')
const {
default: makeWASocket,
useMultiFileAuthState,
Browsers,
DisconnectReason,
} = require('@adiwajshing/baileys')
const {
baileyGenerateImage,
baileyCleanNumber,
baileyIsValidNumber,
baileyDownloadMedia,
} = require('./utils')
const logger = new Console({
stdout: createWriteStream(`${process.cwd()}/baileys.log`),
})
const NAME_DIR_SESSION = `sessions`
const PATH_BASE = join(process.cwd(), NAME_DIR_SESSION)
/**
* ⚙️ BaileysProvider: Es una clase tipo adaptor
* que extiende clases de ProviderClass (la cual es como interfaz para sber que funciones rqueridas)
@@ -30,21 +37,69 @@ class BaileysProvider extends ProviderClass {
saveCredsGlobal = null
constructor() {
super()
this.initBailey().then(() => this.initBusEvents())
this.initBailey().then()
}
/**
* Iniciar todo Bailey
*/
initBailey = async () => {
const { state, saveCreds } = await useMultiFileAuthState('sessions')
const { state, saveCreds } = await useMultiFileAuthState(
NAME_DIR_SESSION
)
this.saveCredsGlobal = saveCreds
try {
this.vendor = makeWASocket({
const sock = makeWASocket({
printQRInTerminal: false,
auth: state,
browser: Browsers.macOS('Desktop'),
syncFullHistory: false,
logger: pino({ level: 'error' }),
})
sock.ev.on('connection.update', async (update) => {
const { connection, lastDisconnect, qr } = update
const statusCode = lastDisconnect?.error?.output?.statusCode
/** Conexion cerrada por diferentes motivos */
if (connection === 'close') {
if (statusCode !== DisconnectReason.loggedOut) {
this.initBailey()
}
if (statusCode === DisconnectReason.loggedOut) {
rimraf(PATH_BASE, (err) => {
if (err) return
})
this.initBailey()
}
}
/** Conexion abierta correctamente */
if (connection === 'open') {
this.emit('ready', true)
this.initBusEvents(sock)
}
/** QR Code */
if (qr) {
this.emit('require_action', {
instructions: [
`Debes escanear el QR Code para iniciar session reivsa qr.png`,
`Recuerda que el QR se actualiza cada minuto `,
`Necesitas ayuda: https://link.codigoencasa.com/DISCORD`,
],
})
await baileyGenerateImage(qr)
}
})
sock.ev.on('creds.update', async () => {
await saveCreds()
})
} catch (e) {
logger.log(e)
this.emit('auth_failure', [
@@ -63,28 +118,6 @@ class BaileysProvider extends ProviderClass {
* @returns
*/
busEvents = () => [
{
event: 'connection.update',
func: async ({ qr, connection, lastDisconnect }) => {
const statusCode = lastDisconnect?.error?.output?.statusCode
if (statusCode && statusCode !== DisconnectReason.loggedOut)
this.initBailey()
if (qr) {
this.emit('require_action', {
instructions: [
`Debes escanear el QR Code para iniciar session reivsa qr.png`,
`Recuerda que el QR se actualiza cada minuto `,
`Necesitas ayuda: https://link.codigoencasa.com/DISCORD`,
],
})
await baileyGenerateImage(qr)
}
if (connection === 'open') this.emit('ready', true)
},
},
{
event: 'messages.upsert',
func: ({ messages, type }) => {
@@ -95,20 +128,28 @@ class BaileysProvider extends ProviderClass {
body: messageCtx?.message?.conversation,
from: messageCtx?.key?.remoteJid,
}
if (payload.from === 'status@broadcast') {
return
}
if (payload.from === 'status@broadcast') return
if (payload?.key?.fromMe) return
if (!baileyIsValidNumber(payload.from)) {
return
}
const btnCtx =
payload?.message?.templateButtonReplyMessage
?.selectedDisplayText
if (btnCtx) payload.body = btnCtx
payload.from = baileyCleanNumber(payload.from, true)
this.emit('message', payload)
},
},
]
initBusEvents = () => {
initBusEvents = (_sock) => {
this.vendor = _sock
const listEvents = this.busEvents()
for (const { event, func } of listEvents) {
@@ -124,8 +165,9 @@ class BaileysProvider extends ProviderClass {
*/
sendMedia = async (number, imageUrl, text) => {
await this.vendor.sendMessage(number, {
image: { url: imageUrl },
const fileDownloaded = await baileyDownloadMedia(imageUrl)
return this.vendor.sendMessage(number, {
image: { url: fileDownloaded },
text,
})
}
@@ -186,17 +228,21 @@ class BaileysProvider extends ProviderClass {
* @example await sendMessage("+XXXXXXXXXXX", "Your Text", "Your Footer", [{"buttonId": "id", "buttonText": {"displayText": "Button"}, "type": 1}])
*/
sendButtons = async (number, text, footer, buttons) => {
sendButtons = async (number, text, buttons) => {
const numberClean = number.replace('+', '')
const templateButtons = buttons.map((btn, i) => ({
index: `${i}`,
quickReplyButton: {
displayText: btn.body,
id: `id-btn-${i}`,
},
}))
const buttonMessage = {
text: text,
footer: footer,
buttons: buttons,
headerType: 1,
}
await this.vendor.sendMessage(`${numberClean}@c.us`, buttonMessage)
return this.vendor.sendMessage(`${numberClean}@c.us`, {
text,
footer: '',
templateButtons: templateButtons,
})
}
/**
@@ -209,8 +255,8 @@ class BaileysProvider extends ProviderClass {
sendMessage = async (numberIn, message, { options }) => {
const number = baileyCleanNumber(numberIn)
// if (options?.buttons?.length)
// return this.sendButtons(number, message, options.buttons)
if (options?.buttons?.length)
return this.sendButtons(number, message, options.buttons)
if (options?.media)
return this.sendMedia(number, options.media, message)
return this.sendText(number, message)

View File

@@ -0,0 +1,7 @@
{
"dependencies": {
"@adiwajshing/baileys": "4.4.0",
"mime-types": "2.1.35",
"wa-sticker-formatter": "4.3.2"
}
}

View File

@@ -1,6 +1,9 @@
const { createWriteStream } = require('fs')
const combineImage = require('combine-image')
const qr = require('qr-image')
const { tmpdir } = require('os')
const http = require('http')
const https = require('https')
const baileyCleanNumber = (number, full = false) => {
number = number.replace('@s.whatsapp.net', '')
@@ -38,4 +41,38 @@ const baileyIsValidNumber = (rawNumber) => {
return !exist
}
module.exports = { baileyCleanNumber, baileyGenerateImage, baileyIsValidNumber }
/**
* Incompleta
* Descargar archivo multimedia para enviar
* @param {*} url
* @returns
*/
const baileyDownloadMedia = (url) => {
return new Promise((resolve, reject) => {
const ext = url.split('.').pop()
const checkProtocol = url.includes('https:')
const handleHttp = checkProtocol ? https : http
const name = `tmp-${Date.now()}.${ext}`
const fullPath = `${tmpdir()}/${name}`
const file = createWriteStream(fullPath)
handleHttp.get(url, function (response) {
response.pipe(file)
file.on('finish', function () {
file.close()
resolve(fullPath)
})
file.on('error', function () {
console.log('errro')
file.close()
reject(null)
})
})
})
}
module.exports = {
baileyCleanNumber,
baileyGenerateImage,
baileyIsValidNumber,
baileyDownloadMedia,
}

View File

@@ -12,16 +12,17 @@ const URL = `https://graph.facebook.com/v15.0`
* Necesitas las siguientes tokens y valores
* { jwtToken, numberId, vendorNumber, verifyToken }
*/
const PORT = process.env.PORT || 3000
class MetaProvider extends ProviderClass {
metHook
jwtToken
numberId
constructor({ jwtToken, numberId, verifyToken }, _port = 3000) {
constructor({ jwtToken, numberId, verifyToken, port = PORT }) {
super()
this.jwtToken = jwtToken
this.numberId = numberId
this.metHook = new MetaWebHookServer(verifyToken, _port)
this.metHook = new MetaWebHookServer(verifyToken, port)
this.metHook.start()
const listEvents = this.busEvents()

View File

@@ -0,0 +1,3 @@
{
"dependencies": {}
}

View File

@@ -1,6 +1,6 @@
const { EventEmitter } = require('node:events')
const polka = require('polka')
const { urlencoded } = require('body-parser')
const { urlencoded, json } = require('body-parser')
class MetaWebHookServer extends EventEmitter {
metaServer
@@ -8,9 +8,11 @@ class MetaWebHookServer extends EventEmitter {
token
constructor(_token, _metaPort) {
super()
this.metaServer = this.buildHTTPServer()
this.metaServer = polka()
this.metaPort = _metaPort
this.token = _token
this.buildHTTPServer()
}
/**
@@ -21,12 +23,18 @@ class MetaWebHookServer extends EventEmitter {
*/
incomingMsg = (req, res) => {
const { body } = req
const message = body.entry[0].changes[0].value.messages[0]
const messages = body.entry[0].changes[0].value?.messages
if (!messages) return
const [message] = messages
const to = body.entry[0].changes[0].value.metadata.display_phone_number
this.emit('message', {
from: message.from,
to,
body: message.text.body,
body: message.text?.body,
})
const json = JSON.stringify({ body })
res.end(json)
@@ -55,16 +63,16 @@ class MetaWebHookServer extends EventEmitter {
const challenge = query['hub.challenge']
if (!mode || !token) {
return res.sendStatus(403)
return (res.statusCode = 403), res.end('No token!')
}
if (this.tokenIsValid(mode, token)) {
console.log('Webhook verified--->😎😎😎😎')
res.status(200).send(challenge)
return (res.statusCode = 200), res.end(challenge)
}
if (!this.tokenIsValid(mode, token)) {
res.sendStatus(403)
return (res.statusCode = 403), res.end('No token!')
}
}
@@ -73,12 +81,13 @@ class MetaWebHookServer extends EventEmitter {
* @returns
*/
buildHTTPServer = () => {
polka()
this.metaServer
.use(urlencoded({ extended: true }))
.get('/webhook', this.verifyToken)
return polka()
this.metaServer
.use(urlencoded({ extended: true }))
.use(json())
.post('/webhook', this.incomingMsg)
}
@@ -91,7 +100,7 @@ class MetaWebHookServer extends EventEmitter {
console.log(``)
console.log(`[meta]: Agregar esta url "WHEN A MESSAGE COMES IN"`)
console.log(
`[meta]: POST http://localhost:${this.metaPort}/meta-hook`
`[meta]: POST http://localhost:${this.metaPort}/webhook`
)
console.log(`[meta]: Más información en la documentacion`)
console.log(``)

View File

@@ -13,14 +13,17 @@ const { parseNumber } = require('./utils')
* Necesitas las siguientes tokens y valores
* { accountSid, authToken, vendorNumber }
*/
const PORT = process.env.PORT || 3000
class TwilioProvider extends ProviderClass {
twilioHook
vendor
vendorNumber
constructor({ accountSid, authToken, vendorNumber }, _port = 3000) {
constructor({ accountSid, authToken, vendorNumber, port = PORT }) {
super()
this.vendor = new twilio(accountSid, authToken)
this.twilioHook = new TwilioWebHookServer(_port)
this.twilioHook = new TwilioWebHookServer(port)
this.vendorNumber = parseNumber(vendorNumber)
this.twilioHook.start()

View File

@@ -0,0 +1,5 @@
{
"dependencies": {
"twilio": "3.84.0"
}
}

View File

@@ -105,6 +105,29 @@ class VenomProvider extends ProviderClass {
}
}
/**
* Enviar botones
* @private
* @param {*} number
* @param {*} message
* @param {*} buttons []
* @returns
*/
sendButtons = async (number, message, buttons = []) => {
const NOTE_VENOM_BUTTON = [
`Actualmente VENOM tiene problemas con la API`,
`para el envio de Botones`,
].join('\n')
console.log(`[NOTA]: ${NOTE_VENOM_BUTTON}`)
const buttonToStr = [message]
.concat(buttons.map((btn) => `${btn.body}`))
.join(`\n`)
return this.vendor.sendText(number, buttonToStr)
// return this.vendor.sendButtons(number, "Title", buttons1, "Description");
}
/**
* Enviar imagen o multimedia
* @param {*} number

View File

@@ -0,0 +1,6 @@
{
"dependencies": {
"venom-bot": "4.3.7",
"mime-types": "2.1.35"
}
}

View File

@@ -0,0 +1,5 @@
{
"dependencies": {
"whatsapp-web.js": "1.18.4"
}
}

169
scripts/checker.js Normal file
View File

@@ -0,0 +1,169 @@
const { execFile } = require('node:child_process')
const { readFileSync, writeFileSync, readdirSync } = require('node:fs')
const { join } = require('path')
const process = require('node:process')
const util = require('node:util')
const semver = require('semver')
const cmd = util.promisify(execFile)
const OS_ENVIROMENT_WIN = process.platform.includes('win32')
const PATH_PACKAGES = join(__dirname, '..', `packages`)
const PATH_STARTERS = join(__dirname, '..', `starters`, `apps`)
const NPM_COMMAND = OS_ENVIROMENT_WIN ? 'npm.cmd' : 'npm'
const [PKG_NAME, PKG_STABLE] = process.argv.slice(2) || [null, null]
/**
* Revisar ultima version de una paquetes
* @param {*} pkgName
*/
const checkPkg = async (pkgName = '') => {
const { stdout } = await cmd(
NPM_COMMAND,
['show', `${pkgName}`, 'version'],
{
stdio: 'inherit',
}
)
return stdout.trim().replace('\n', '')
}
/**
* Revisar ultima version de una paquetes
* @param {*} pkgName
*/
const checkPkgStable = async (pkgName = '', version = '') => {
const { stdout } = await cmd(
NPM_COMMAND,
[
'show',
`${pkgName}@${version.split('.').shift()}.*`,
'version',
'--json',
],
{
stdio: 'inherit',
}
)
try {
const listVersions = JSON.parse(stdout).reverse()
console.log(`[${pkgName}]: `, listVersions)
return listVersions.at(0)
} catch (e) {
const listVersions = [stdout.trim().replace('\n').replaceAll('"', '')]
console.log(`[${pkgName}]: `, listVersions)
return listVersions.at(0)
}
}
/**
* Revisar todas las dependencias del provider
* @param {*} provider
* @param {*} stable
* @returns
*/
const checkEveryProvider = async (provider = '', stable = true) => {
const pkgDependencies = readFileSync(
join(PATH_PACKAGES, 'provider', 'src', provider, 'package.json')
)
try {
const { dependencies } = JSON.parse(pkgDependencies)
const devParse = Object.entries(dependencies)
const newDevParse = {}
for (const [pkgName, pkgVersion] of devParse) {
if (!stable) newDevParse[pkgName] = await checkPkg(pkgName)
if (stable)
newDevParse[pkgName] = await checkPkgStable(pkgName, pkgVersion)
console.log(newDevParse)
}
return newDevParse
} catch (e) {
console.log(e)
return {}
}
}
/**
* Actualizar depedencias con nuevas versiones
* @param {*} provider
* @param {*} list
* @returns
*/
const updateDependencies = async (provider = '', list = {}) => {
const pathProvider = join(
PATH_PACKAGES,
'provider',
'src',
provider,
'package.json'
)
try {
const pkgDependencies = readFileSync(pathProvider)
const { dependencies } = JSON.parse(pkgDependencies)
writeFileSync(
pathProvider,
JSON.stringify(
{ dependencies: { ...dependencies, ...list } },
null,
2
)
)
} catch (e) {
console.log(e)
return {}
}
}
/**
* Actualizar starters
* @param {*} provider
* @returns
*/
const updateStarters = async (provider = '', updateDev = {}) => {
provider = provider === 'web-whatsapp' ? 'wweb' : provider
const allStarters = readdirSync(PATH_STARTERS).filter((n) =>
n.includes(provider)
)
try {
for (const base of allStarters) {
const pkgDependenciesBase = readFileSync(
join(PATH_STARTERS, base, 'package.json')
)
const pkgBase = JSON.parse(pkgDependenciesBase)
writeFileSync(
join(PATH_STARTERS, base, 'package.json'),
JSON.stringify(
{
...pkgBase,
dependencies: { ...pkgBase.dependencies, ...updateDev },
},
null,
2
)
)
}
} catch (e) {
console.log(e)
return
}
}
const main = async () => {
if (PKG_NAME) {
const providerName = PKG_NAME ? PKG_NAME.split('=').at(1) : null
const providerStable = PKG_STABLE ? PKG_STABLE.split('=').at(1) : null
const list = await checkEveryProvider(
providerName,
providerStable === 'true'
)
await updateDependencies(providerName, list)
await updateStarters(providerName, list)
}
}
main()

View File

@@ -1,34 +0,0 @@
### CHATBOT Whatsapp
Este bot es una aplicación que puedes vincular con tu whatsapp y crear flujos para automatizar tareas en tu negocio o procesos repetitivos.
Este bot contiene un flujo básico en el cual una persona (cliente) escribe **"hola"** y el bot responde:
- Bienvenido a mi tienda
- ¿Como puedo ayudarte?
- Tengo: Zapatos, Bolsos etc..
__Iniciar__
Los flujos se declaran de atrás 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 se declaran los submenus 1.1 y 2.1, luego el 1 y 2 y al final el principal.
```
npm install
npm start
```
__¿Tienes problemas?:__ [Abrir Issue](https://github.com/codigoencasa/bot-whatsapp/issues/new/choose)
------
> ¿Quieres se 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)

View File

@@ -1,42 +0,0 @@
### CHATBOT Whatsapp
Este bot es una aplicación que puedes vincular con tu whatsapp y crear flujos para automatizar tareas en tu negocio o procesos repetitivos.
Este bot contiene un flujo básico en el cual una persona (cliente) escribe **"hola"** y el bot responde:
- Bienvenido a mi tienda
- ¿Como puedo ayudarte?
- Tengo: Zapatos, Bolsos etc..
__Iniciar__
Recuerda configurar los parametros de conexión de la base de datos:
```js
// app.js
const MONGO_DB_URI = 'mongodb://0.0.0.0:27017'
const MONGO_DB_NAME = 'db_bot'
```
Los flujos se declaran de atrás 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 se declaran los submenus 1.1 y 2.1, luego el 1 y 2 y al final el principal.
```
npm install
npm start
```
__¿Tienes problemas?:__ [Abrir Issue](https://github.com/codigoencasa/bot-whatsapp/issues/new/choose)
------
> ¿Quieres se 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)

View File

@@ -1,44 +0,0 @@
### CHATBOT Whatsapp
Este bot es una aplicación que puedes vincular con tu whatsapp y crear flujos para automatizar tareas en tu negocio o procesos repetitivos.
Este bot contiene un flujo básico en el cual una persona (cliente) escribe **"hola"** y el bot responde:
- Bienvenido a mi tienda
- ¿Como puedo ayudarte?
- Tengo: Zapatos, Bolsos etc..
__Iniciar__
Recuerda configurar los parametros de conexión de la base de datos
```js
// app.js
const MYSQL_DB_HOST = 'localhost'
const MYSQL_DB_USER = 'user'
const MYSQL_DB_PASSWORD = 'pass'
const MYSQL_DB_NAME = 'bot'
```
Los flujos se declaran de atrás 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 se declaran los submenus 1.1 y 2.1, luego el 1 y 2 y al final el principal.
```
npm install
npm start
```
__¿Tienes problemas?:__ [Abrir Issue](https://github.com/codigoencasa/bot-whatsapp/issues/new/choose)
------
> ¿Quieres se 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)

View File

@@ -0,0 +1,40 @@
### CHATBOT Whatsapp (Baileys Provider)
<p align="center">
<img width="300" src="https://i.imgur.com/Oauef6t.png">
</p>
**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/)**
```js
const main = async () => {
const adapterDB = new MockAdapter()
const adapterFlow = createFlow([flowPrincipal])
const adapterProvider = createProvider(BaileysProvider, {
accountSid: process.env.ACC_SID,
authToken: process.env.ACC_TOKEN,
vendorNumber: process.env.ACC_VENDOR,
})
createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
}
```
```
npm install
npm start
```
---
## 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)

View File

@@ -0,0 +1,88 @@
const {
createBot,
createProvider,
createFlow,
addKeyword,
} = require('@bot-whatsapp/bot')
const BaileysProvider = require('@bot-whatsapp/provider/baileys')
const JsonFileAdapter = require('@bot-whatsapp/database/json')
/**
* 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)
},
[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)
},
[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)
},
[flowBolsos, flowZapatos]
)
const main = async () => {
const adapterDB = new JsonFileAdapter()
const adapterFlow = createFlow([flowPrincipal])
const adapterProvider = createProvider(BaileysProvider)
createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
}
main()

View File

@@ -0,0 +1,22 @@
{
"name": "bot-whatsapp-base-bailey-json",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"pre-copy": "cd .. && yarn run copy.lib base-baileys-json",
"start": "node app.js"
},
"keywords": [],
"dependencies": {
"@bot-whatsapp/bot": "latest",
"@bot-whatsapp/cli": "latest",
"@bot-whatsapp/database": "latest",
"@bot-whatsapp/provider": "latest",
"@adiwajshing/baileys": "4.4.0",
"mime-types": "2.1.35",
"wa-sticker-formatter": "4.3.2"
},
"author": "",
"license": "ISC"
}

View File

@@ -0,0 +1,40 @@
### CHATBOT Whatsapp (Baileys Provider)
<p align="center">
<img width="300" src="https://i.imgur.com/Oauef6t.png">
</p>
**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/)**
```js
const main = async () => {
const adapterDB = new MockAdapter()
const adapterFlow = createFlow([flowPrincipal])
const adapterProvider = createProvider(BaileysProvider, {
accountSid: process.env.ACC_SID,
authToken: process.env.ACC_TOKEN,
vendorNumber: process.env.ACC_VENDOR,
})
createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
}
```
```
npm install
npm start
```
---
## 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)

View File

@@ -3,7 +3,6 @@ const {
createProvider,
createFlow,
addKeyword,
addChild,
} = require('@bot-whatsapp/bot')
const BaileysProvider = require('@bot-whatsapp/provider/baileys')
@@ -40,7 +39,7 @@ const flowZapatos = addKeyword(['1', 'zapatos', 'ZAPATOS'])
console.log('Puedes enviar un mail, hook, etc..')
console.log(ctx)
},
[...addChild(flowZapatos2)]
[flowZapatos2]
)
const flowBolsos = addKeyword(['2', 'bolsos', 'BOLSOS'])
@@ -54,7 +53,7 @@ const flowBolsos = addKeyword(['2', 'bolsos', 'BOLSOS'])
console.log('Puedes enviar un mail, hook, etc..')
console.log(ctx)
},
[...addChild(flowBolsos2)]
[flowBolsos2]
)
/**
@@ -72,7 +71,7 @@ const flowPrincipal = addKeyword(['hola', 'ole', 'alo'])
console.log('Puedes enviar un mail, hook, etc..')
console.log(ctx)
},
[...addChild(flowBolsos), ...addChild(flowZapatos)]
[flowBolsos, flowZapatos]
)
const main = async () => {

View File

@@ -4,7 +4,7 @@
"description": "",
"main": "app.js",
"scripts": {
"pre-copy": "cd .. && yarn run copy.lib base-bailey-memory",
"pre-copy": "cd .. && yarn run copy.lib base-baileys-memory",
"start": "node app.js"
},
"keywords": [],
@@ -13,9 +13,9 @@
"@bot-whatsapp/cli": "latest",
"@bot-whatsapp/database": "latest",
"@bot-whatsapp/provider": "latest",
"@adiwajshing/baileys": "^4.4.0",
"mime-types": "^2.1.35",
"wa-sticker-formatter": "^4.3.2"
"@adiwajshing/baileys": "4.4.0",
"mime-types": "2.1.35",
"wa-sticker-formatter": "4.3.2"
},
"author": "",
"license": "ISC"

Some files were not shown because too many files have changed in this diff Show More