mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-20 20:49:15 +00:00
Compare commits
5 Commits
contributo
...
feature/br
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c451ad5e68 | ||
| 4b1a43187e | |||
| d564c170a7 | |||
| c7117b9884 | |||
|
|
147100dfc2 |
@@ -1,2 +1 @@
|
|||||||
packages/docs/*
|
packages/docs/*
|
||||||
packages/portal/*
|
|
||||||
10
.github/workflows/check-provider-major.yml
vendored
10
.github/workflows/check-provider-major.yml
vendored
@@ -39,14 +39,8 @@ jobs:
|
|||||||
- name: Check Twilio
|
- name: Check Twilio
|
||||||
run: yarn node ./scripts/checker.js --name=twilio --stable=true
|
run: yarn node ./scripts/checker.js --name=twilio --stable=true
|
||||||
|
|
||||||
- name: Add and commit changes to gh-pages branch
|
|
||||||
run: |
|
|
||||||
git config --local user.email 'action@github.com'
|
|
||||||
git config --local user.name 'GitHub Action'
|
|
||||||
git add .
|
|
||||||
|
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
with:
|
with:
|
||||||
commit_message: 'ci(providers): check provider versions'
|
commit_message: 'ci(providers): 🚩 Check BREAKING CHANGE'
|
||||||
create_branch: true
|
create_branch: true
|
||||||
branch: feature/providers-major
|
branch: feature/breaking-change
|
||||||
|
|||||||
45
.github/workflows/check-providers.yml
vendored
Normal file
45
.github/workflows/check-providers.yml
vendored
Normal 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'
|
||||||
54
.github/workflows/ci.yml
vendored
54
.github/workflows/ci.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
run: yarn install --immutable --network-timeout 300000
|
run: yarn install --immutable --network-timeout 300000
|
||||||
|
|
||||||
- name: Build Package
|
- name: Build Package
|
||||||
run: yarn build:full
|
run: yarn build
|
||||||
|
|
||||||
- name: Build Eslint rules
|
- name: Build Eslint rules
|
||||||
run: yarn lint:fix
|
run: yarn lint:fix
|
||||||
@@ -56,55 +56,3 @@ jobs:
|
|||||||
|
|
||||||
- name: Unit Tests
|
- name: Unit Tests
|
||||||
run: yarn test
|
run: yarn test
|
||||||
|
|
||||||
############ UNIT TEST ############
|
|
||||||
check-providers:
|
|
||||||
name: Check Providers Versions
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
commit: ${{ steps.vars.outputs.commit }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
ref: ${{github.event.after}}
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Setup Node
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 16.x
|
|
||||||
cache: 'yarn'
|
|
||||||
registry-url: https://registry.npmjs.org/
|
|
||||||
|
|
||||||
- run: corepack enable
|
|
||||||
|
|
||||||
- name: Install NPM Dependencies
|
|
||||||
run: yarn install --immutable --network-timeout 300000
|
|
||||||
|
|
||||||
- name: Check Baileys
|
|
||||||
run: yarn node ./scripts/checker.js --name=baileys --stable=true
|
|
||||||
|
|
||||||
- name: Check Venom
|
|
||||||
run: yarn node ./scripts/checker.js --name=venom --stable=true
|
|
||||||
|
|
||||||
- name: Check web-whatsapp
|
|
||||||
run: yarn node ./scripts/checker.js --name=web-whatsapp --stable=true
|
|
||||||
|
|
||||||
- name: Check Meta
|
|
||||||
run: yarn node ./scripts/checker.js --name=meta --stable=true
|
|
||||||
|
|
||||||
- name: Check Twilio
|
|
||||||
run: yarn node ./scripts/checker.js --name=twilio --stable=true
|
|
||||||
|
|
||||||
- name: Set output
|
|
||||||
id: vars
|
|
||||||
run: echo "commit=$(git log --format=%B -n 1 ${{github.event.after}})" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Commit & Push changes
|
|
||||||
uses: actions-js/push@master
|
|
||||||
with:
|
|
||||||
branch: feature/providers-major
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
force: true
|
|
||||||
|
|||||||
3
.github/workflows/codeql.yml
vendored
3
.github/workflows/codeql.yml
vendored
@@ -13,7 +13,7 @@ name: 'CodeQL'
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [release/next]
|
branches: ['main', dev, next-release]
|
||||||
pull_request:
|
pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
# The branches below must be a subset of the branches above
|
||||||
branches: ['main']
|
branches: ['main']
|
||||||
@@ -22,7 +22,6 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
if: ${{ !github.event.act }}
|
|
||||||
name: Analyze
|
name: Analyze
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
|
|||||||
10
.github/workflows/contributors.yml
vendored
10
.github/workflows/contributors.yml
vendored
@@ -1,8 +1,12 @@
|
|||||||
name: Revisando Colaboradores
|
name: Revisando Colaboradores
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
push:
|
||||||
- cron: '0 9 * * *'
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
types: [closed]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
contrib-readme-job:
|
contrib-readme-job:
|
||||||
|
|||||||
1
.github/workflows/netlify-dev.yml
vendored
1
.github/workflows/netlify-dev.yml
vendored
@@ -13,7 +13,6 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
############ DOCUMENTATION BUILD ############
|
############ DOCUMENTATION BUILD ############
|
||||||
build-documentation:
|
build-documentation:
|
||||||
if: ${{ !github.event.act }}
|
|
||||||
name: Build Package
|
name: Build Package
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
|||||||
5
.github/workflows/netlify.yml
vendored
5
.github/workflows/netlify.yml
vendored
@@ -3,11 +3,12 @@ name: 📄 (PROD) Desplegando documentacion
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- release/next
|
- main
|
||||||
|
- next-release
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
############ DOCUMENTATION BUILD ############
|
############ DOCUMENTATION BUILD ############
|
||||||
build-documentation-prod:
|
build-documentation:
|
||||||
name: Build Package
|
name: Build Package
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
|||||||
25
.github/workflows/releases-dev.yml
vendored
25
.github/workflows/releases-dev.yml
vendored
@@ -3,22 +3,16 @@ name: 🚀 (DEV) Liberando versiones
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- release/next
|
- next-release
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
############ RELEASE ############
|
############ RELEASE ############
|
||||||
release:
|
release:
|
||||||
name: Release
|
name: Release
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
|
||||||
commit: ${{ steps.vars.outputs.commit }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
ref: ${{github.event.after}}
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
@@ -33,7 +27,7 @@ jobs:
|
|||||||
run: yarn install --immutable --network-timeout 300000
|
run: yarn install --immutable --network-timeout 300000
|
||||||
|
|
||||||
- name: Build Package
|
- name: Build Package
|
||||||
run: yarn build:full
|
run: yarn build
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/bot
|
- name: Release @bot-whatsapp/bot
|
||||||
run: yarn node ./scripts/release.js --name=bot --version= --token="${{ secrets.NPM_TOKEN }}"
|
run: yarn node ./scripts/release.js --name=bot --version= --token="${{ secrets.NPM_TOKEN }}"
|
||||||
@@ -50,15 +44,8 @@ jobs:
|
|||||||
- name: Release @bot-whatsapp/provider
|
- name: Release @bot-whatsapp/provider
|
||||||
run: yarn node ./scripts/release.js --name=provider --version= --token="${{ secrets.NPM_TOKEN }}"
|
run: yarn node ./scripts/release.js --name=provider --version= --token="${{ secrets.NPM_TOKEN }}"
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/contexts
|
- name: Commit Versioning & Push changes
|
||||||
run: yarn node ./scripts/release.js --name=contexts --version= --token="${{ secrets.NPM_TOKEN }}"
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/portal
|
|
||||||
run: yarn node ./scripts/release.js --name=portal --version= --token="${{ secrets.NPM_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Commit & Push changes
|
|
||||||
uses: actions-js/push@master
|
|
||||||
with:
|
with:
|
||||||
branch: release/next
|
commit_message: 'ci(version): :zap: automatic - "${date}" updated versions every packages'
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
branch: dev
|
||||||
force: true
|
|
||||||
|
|||||||
69
.github/workflows/releases.yml
vendored
69
.github/workflows/releases.yml
vendored
@@ -2,12 +2,12 @@ name: 🚀⚡ Liberando versiones
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
tags:
|
||||||
- release/production
|
- 'v*.*.*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
############ RELEASE ############
|
############ RELEASE ############
|
||||||
release-prod:
|
release:
|
||||||
if: ${{ !github.event.act }}
|
|
||||||
name: Release
|
name: Release
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -27,49 +27,32 @@ jobs:
|
|||||||
|
|
||||||
- run: corepack enable
|
- run: corepack enable
|
||||||
|
|
||||||
- name: Set User
|
|
||||||
run: git config --global user.email "leifer.contacto@gmail.com" && git config --global user.name "Leifer Mendez"
|
|
||||||
|
|
||||||
- name: Install NPM Dependencies
|
- name: Install NPM Dependencies
|
||||||
run: yarn install --immutable --network-timeout 300000
|
run: yarn install --immutable --network-timeout 300000
|
||||||
|
|
||||||
|
- name: Build Package
|
||||||
|
run: yarn build
|
||||||
|
|
||||||
|
- name: Release @bot-whatsapp/bot
|
||||||
|
run: yarn node ./scripts/release.js --name=bot --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Release @bot-whatsapp/cli
|
||||||
|
run: yarn node ./scripts/release.js --name=cli --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Release @bot-whatsapp/create-bot-whatsapp
|
||||||
|
run: yarn node ./scripts/release.js --name=create-bot-whatsapp --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Release @bot-whatsapp/database
|
||||||
|
run: yarn node ./scripts/release.js --name=database --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Release @bot-whatsapp/provider
|
||||||
|
run: yarn node ./scripts/release.js --name=provider --version="${{ steps.vars.outputs.tag }}" --token="${{ secrets.NPM_TOKEN }}"
|
||||||
|
|
||||||
- name: Set CHANGELOG
|
- name: Set CHANGELOG
|
||||||
run: yarn release
|
run: yarn release
|
||||||
|
|
||||||
- name: get-npm-version
|
- name: Commit Versioning & Push changes
|
||||||
id: package-version
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
uses: martinbeentjes/npm-get-version-action@main
|
|
||||||
|
|
||||||
- name: Build Package
|
|
||||||
run: yarn build:full
|
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/bot
|
|
||||||
run: yarn node ./scripts/release.js --name=bot --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/cli
|
|
||||||
run: yarn node ./scripts/release.js --name=cli --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/create-bot-whatsapp
|
|
||||||
run: yarn node ./scripts/release.js --name=create-bot-whatsapp --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/database
|
|
||||||
run: yarn node ./scripts/release.js --name=database --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/provider
|
|
||||||
run: yarn node ./scripts/release.js --name=provider --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/contexts
|
|
||||||
run: yarn node ./scripts/release.js --name=contexts --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Release @bot-whatsapp/portal
|
|
||||||
run: yarn node ./scripts/release.js --name=portal --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.NPM_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Release Github
|
|
||||||
run: yarn node ./scripts/github.js --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.OCTO_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Commit & Push changes
|
|
||||||
uses: actions-js/push@master
|
|
||||||
with:
|
with:
|
||||||
branch: release/production
|
commit_message: 'release(version): 🚀 - "${{ steps.vars.outputs.tag }}" release'
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
branch: dev
|
||||||
force: true
|
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,5 +1,4 @@
|
|||||||
/node_modules
|
/node_modules
|
||||||
/packages/repl
|
|
||||||
/packages/*/starters
|
/packages/*/starters
|
||||||
/packages/*/node_modules
|
/packages/*/node_modules
|
||||||
/packages/*/dist
|
/packages/*/dist
|
||||||
@@ -15,10 +14,6 @@ mediaSend/*
|
|||||||
!mediaSend/nota-de-voz.mp3
|
!mediaSend/nota-de-voz.mp3
|
||||||
.env
|
.env
|
||||||
.wwebjs_auth
|
.wwebjs_auth
|
||||||
/session
|
|
||||||
/session/*
|
|
||||||
/tokens
|
|
||||||
/tokens/*
|
|
||||||
packages/cli/config.json
|
packages/cli/config.json
|
||||||
config.json
|
config.json
|
||||||
.yarnrc.yml
|
.yarnrc.yml
|
||||||
@@ -43,4 +38,3 @@ yarn-error.log
|
|||||||
.npmrc
|
.npmrc
|
||||||
# Local Netlify folder
|
# Local Netlify folder
|
||||||
.netlify
|
.netlify
|
||||||
.secrets
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
. "$(dirname -- "$0")/_/husky.sh"
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
npm run lint:fix && npx --no -- commitlint --edit
|
npx --no -- commitlint --edit
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
packages/**/lib
|
packages/**/lib
|
||||||
packages/docs/
|
packages/docs/*.json
|
||||||
**/.git
|
**/.git
|
||||||
**/.svn
|
**/.svn
|
||||||
**/.hg
|
**/.hg
|
||||||
|
|||||||
@@ -2,6 +2,5 @@
|
|||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
"tabWidth": 4,
|
"tabWidth": 4,
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": true,
|
"singleQuote": true
|
||||||
"printWidth": 120
|
|
||||||
}
|
}
|
||||||
|
|||||||
2
.vscode/extensions.json
vendored
2
.vscode/extensions.json
vendored
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"recommendations": ["xyc.vscode-mdx-preview", "vivaxy.vscode-conventional-commits", "mhutchie.git-graph"]
|
"recommendations": ["xyc.vscode-mdx-preview"]
|
||||||
}
|
}
|
||||||
|
|||||||
193
CHANGELOG.md
193
CHANGELOG.md
@@ -2,199 +2,6 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||||
|
|
||||||
### [0.1.20](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.19...v0.1.20) (2023-02-05)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **cli:** :fire: add regex expression in addKeyworkd ([e34560c](https://github.com/leifermendez/bot-whatsapp/commit/e34560c77d4852d2e90930f0858e51aa67d4eeab))
|
|
||||||
* **provider:** :zap: possible get class provider ([76ba717](https://github.com/leifermendez/bot-whatsapp/commit/76ba717927a75b3d6299206aa0b8aee2bc25b726))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **cli:** :zap: working flowDynamic test ([c0113ca](https://github.com/leifermendez/bot-whatsapp/commit/c0113ca49295aff220d8defcb53f2ba7f2872d75))
|
|
||||||
* **cli:** :zap: working flowDynamic test ([aef52d2](https://github.com/leifermendez/bot-whatsapp/commit/aef52d2694fa6616d614338643db198b4f7f1fe8))
|
|
||||||
* **cli:** :zap: working flowDynamic test ([f769320](https://github.com/leifermendez/bot-whatsapp/commit/f76932021ce968d93241b55cfcdb8ae0e0e6c934))
|
|
||||||
* **cli:** :zap: working flowDynamic test ([23e09ef](https://github.com/leifermendez/bot-whatsapp/commit/23e09efaeccaf51018c55da492edff45b625f0a9))
|
|
||||||
* **database:** add support emoji in mysql ([9311aa0](https://github.com/leifermendez/bot-whatsapp/commit/9311aa0a65623a1bf40e96207a281625154dae90))
|
|
||||||
* **database:** fix naming ([cd082f2](https://github.com/leifermendez/bot-whatsapp/commit/cd082f235012cd5f5844c6437f51711beee0c865))
|
|
||||||
* **database:** fix naming ([1afc3ba](https://github.com/leifermendez/bot-whatsapp/commit/1afc3ba182070713b5bec40eaab0fa1f680830cd))
|
|
||||||
* **database:** fix naming ([c9831d2](https://github.com/leifermendez/bot-whatsapp/commit/c9831d202ab2c85f15a0247cd2a2426bc435270c))
|
|
||||||
* **provider:** :zap: baily wa.link ([96c2bff](https://github.com/leifermendez/bot-whatsapp/commit/96c2bffd093269be8e39474a84c156938504a6cb))
|
|
||||||
|
|
||||||
### [0.1.19](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.18...v0.1.19) (2023-01-29)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* :fire: bailey add media ([eab39e4](https://github.com/leifermendez/bot-whatsapp/commit/eab39e4ac06fd46f1a4671f8c15d1456b4400b97))
|
|
||||||
* :zap: more feature ([e19c3a2](https://github.com/leifermendez/bot-whatsapp/commit/e19c3a25a40259c74b4add9635af4844907eed26))
|
|
||||||
* **provider:** :rocket: fix issues in providers venom and wwebjs ([cbe438b](https://github.com/leifermendez/bot-whatsapp/commit/cbe438b77854e8df48b9dafaf7a837d21124ac5f))
|
|
||||||
* **provider:** :rocket: fix provider ([0ad4c58](https://github.com/leifermendez/bot-whatsapp/commit/0ad4c58457b548dc41c0f9e8470d59c48de7b95a))
|
|
||||||
* **provider:** :rocket: fix provider ([f8c7184](https://github.com/leifermendez/bot-whatsapp/commit/f8c7184487065443ab10f77aaf585e8bd63ca441))
|
|
||||||
* **provider:** :rocket: fix provider ([b2afa45](https://github.com/leifermendez/bot-whatsapp/commit/b2afa45352a7ab1f5d9775f3c1fde475bd8ca204))
|
|
||||||
* **provider:** :rocket: fix provider venom and wwebjs ([dcb0566](https://github.com/leifermendez/bot-whatsapp/commit/dcb0566d2bc3da40cd0c71554bb5ea0ec115d9ca))
|
|
||||||
* **provider:** :rocket: implements all send media to venom provider ([9dd7c02](https://github.com/leifermendez/bot-whatsapp/commit/9dd7c02b6a5474aff063f7d6be0ca8519504b93c))
|
|
||||||
* **provider:** :rocket: send file wwebjs ([6ff1a3a](https://github.com/leifermendez/bot-whatsapp/commit/6ff1a3a980196c01c66ed04ee07d0e7e57256504))
|
|
||||||
* **provider:** :zap: bailey add send file video audio ([14d1a61](https://github.com/leifermendez/bot-whatsapp/commit/14d1a61fa259c09135c37c55bd79e97c9c8367e4))
|
|
||||||
* **provider:** :zap: venom wweb ([fd2847a](https://github.com/leifermendez/bot-whatsapp/commit/fd2847aea0db17a0bdf33b5bca67a4cb8db2da16))
|
|
||||||
* **provider:** :zap: venom wweb ([f95331d](https://github.com/leifermendez/bot-whatsapp/commit/f95331d3dc70e76a3dfbe4c8d24059f0e7a164ef))
|
|
||||||
* **provider:** 🚀 implements all send media to venom provider ([bd7d150](https://github.com/leifermendez/bot-whatsapp/commit/bd7d150c047af41fdbb47f0a50a21e82cd79ee85))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **bot:** :fire: endFlow with ctx ([f6114af](https://github.com/leifermendez/bot-whatsapp/commit/f6114affadfbc324536a86167d1fdfe8da3c8de6))
|
|
||||||
* **bot:** :fire: endFlow with ctx ([b655ae4](https://github.com/leifermendez/bot-whatsapp/commit/b655ae449e7958ea940d8cc3c678fd66f60b6385))
|
|
||||||
* **bot:** :zap: endFlow butons ([87a4203](https://github.com/leifermendez/bot-whatsapp/commit/87a4203cd5b88f566387a76d586248e4265d6e4e))
|
|
||||||
* **bot:** :zap: fix fallback refactor ([e22780d](https://github.com/leifermendez/bot-whatsapp/commit/e22780d3faba94f71a70f1f201a20690608fa5bf))
|
|
||||||
* **cli:** :zap: endflow ([1c66f17](https://github.com/leifermendez/bot-whatsapp/commit/1c66f178a56d284bb8cb9df5ca17685c7e5d1ddd))
|
|
||||||
* **cli:** :zap: refactor fallback in child flow ([b33e346](https://github.com/leifermendez/bot-whatsapp/commit/b33e34692d3abcb6874308a9be79f74be4a2c3a8))
|
|
||||||
* **cli:** :zap: refactor fallback in child flow ([8da4b20](https://github.com/leifermendez/bot-whatsapp/commit/8da4b204b41125b5d0fa0aee4fa87c1f5faf5568))
|
|
||||||
|
|
||||||
### [0.1.18](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.17...v0.1.18) (2023-01-24)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **bot:** :zap: add blacklist ([7078dc4](https://github.com/leifermendez/bot-whatsapp/commit/7078dc4c93d01bf90ef08ecb34e89a1abbe16fd2))
|
|
||||||
* **bot:** :zap: flowDynamic buttons, media ([3c4b1c0](https://github.com/leifermendez/bot-whatsapp/commit/3c4b1c0fc4b6d98d67c67806d918d3604bb2209b))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **bot:** :bug: body undefined ([bb6ed4a](https://github.com/leifermendez/bot-whatsapp/commit/bb6ed4a084ae98070dfdf0c4ba1eca574c4092cc))
|
|
||||||
* **bot:** :bug: body undefined ([9234cf1](https://github.com/leifermendez/bot-whatsapp/commit/9234cf1c5d00abdd35e62a826b3c450ab056987a))
|
|
||||||
* **bot:** :bug: body undefined ([a118bbb](https://github.com/leifermendez/bot-whatsapp/commit/a118bbbf7f0a7023cb7f33c23f37db72adad151f))
|
|
||||||
* **bot:** :bug: body undefined ([f54dea5](https://github.com/leifermendez/bot-whatsapp/commit/f54dea52b01063acd6122eeba1fbbe324aa7805d))
|
|
||||||
* **bot:** :bug: body undefined ([72e0a91](https://github.com/leifermendez/bot-whatsapp/commit/72e0a910503e9643db7dfbc6e09c41c96934e1f7))
|
|
||||||
* **bot:** :bug: body undefined ([70dd4d7](https://github.com/leifermendez/bot-whatsapp/commit/70dd4d73e814fc5636d19a887f3621c483b837c1))
|
|
||||||
* **bot:** :bug: body undefined ([ecf0eef](https://github.com/leifermendez/bot-whatsapp/commit/ecf0eef928917d76c59bd23886cb7a4108b421f1))
|
|
||||||
* **bot:** :bug: flowDynamic stranger behaviour ([877252b](https://github.com/leifermendez/bot-whatsapp/commit/877252bd4a8a7bbbbf083c3ceaeaeb952b0a1828))
|
|
||||||
* **bot:** :bug: flowDynamic stranger behaviour ([f5a7de3](https://github.com/leifermendez/bot-whatsapp/commit/f5a7de3a003c012e2164e51fff26892cfc3144be))
|
|
||||||
* **bot:** :memo: more docs ([98793d0](https://github.com/leifermendez/bot-whatsapp/commit/98793d0cfc1674830beaa3707f933c5a791eec14))
|
|
||||||
* **cli:** :zap: refactor ([a29b9d4](https://github.com/leifermendez/bot-whatsapp/commit/a29b9d4e1f85fc163cf1d633c0857f0c8b7f03e1))
|
|
||||||
* **cli:** :zap: refactor ([18ef4e9](https://github.com/leifermendez/bot-whatsapp/commit/18ef4e9d726575ca390ca24354825860328d3347))
|
|
||||||
* **cli:** :zap: refactor ([3648757](https://github.com/leifermendez/bot-whatsapp/commit/3648757fa083bdb88a16bf6c2e90c828c233bdb1))
|
|
||||||
* **cli:** :zap: refactor ([32f6a70](https://github.com/leifermendez/bot-whatsapp/commit/32f6a70f8f6fb26d8ea2a0f1a4aec4827b9d6a93))
|
|
||||||
* **cli:** :zap: refactor ([8c825e7](https://github.com/leifermendez/bot-whatsapp/commit/8c825e7f6b7133f7cc7f3041ce331b80a9fe60e0))
|
|
||||||
* **cli:** :zap: refactor ([0c0f437](https://github.com/leifermendez/bot-whatsapp/commit/0c0f4375b84549bee809340a85f9ce038ee2739e))
|
|
||||||
* **cli:** :zap: refactor ([039ce5d](https://github.com/leifermendez/bot-whatsapp/commit/039ce5dd7cac8115b335ad5de05f7bd871e24140))
|
|
||||||
* **cli:** :zap: refactor ([5e87918](https://github.com/leifermendez/bot-whatsapp/commit/5e879188b8bf9d486399b308a9a9c2612607d465))
|
|
||||||
* **cli:** :zap: refactor ([21a7270](https://github.com/leifermendez/bot-whatsapp/commit/21a72702817bc6b344223b34ca4513a7ff45fc93))
|
|
||||||
* **cli:** :zap: refactor ([82a99b2](https://github.com/leifermendez/bot-whatsapp/commit/82a99b2c80e6738566042ea738bbab8208a17758))
|
|
||||||
* **cli:** :zap: refactor ([cc19974](https://github.com/leifermendez/bot-whatsapp/commit/cc19974579379777b05cb69c38cec0fce6740471))
|
|
||||||
* **cli:** :zap: refactor ([56fcb8f](https://github.com/leifermendez/bot-whatsapp/commit/56fcb8fb72169bc21fce7c4fcdceccf2acd39c73))
|
|
||||||
* **cli:** :zap: refactor ([f36cff1](https://github.com/leifermendez/bot-whatsapp/commit/f36cff1eefdd96be4ab531e1cb2d3b630b1a81c3))
|
|
||||||
* **cli:** :zap: refactor ([b393c11](https://github.com/leifermendez/bot-whatsapp/commit/b393c11af6c0ebccb0a690be8b90b9df8877dad1))
|
|
||||||
* **cli:** :zap: refactor ([6683715](https://github.com/leifermendez/bot-whatsapp/commit/6683715ad617ea1075654a475a1c62ea607c733f))
|
|
||||||
* **contexts:** :bug: fixed [#524](https://github.com/leifermendez/bot-whatsapp/issues/524) issue ([79cc31a](https://github.com/leifermendez/bot-whatsapp/commit/79cc31a96f6a9836447cc4e6bb1e1521c54183fe))
|
|
||||||
* **contexts:** :bug: fixed [#524](https://github.com/leifermendez/bot-whatsapp/issues/524) issue ([7067b4a](https://github.com/leifermendez/bot-whatsapp/commit/7067b4a80b7938ccfaf1ed141a37d645a1a3a062))
|
|
||||||
* **provider:** wwebjs upgrade ([345f256](https://github.com/leifermendez/bot-whatsapp/commit/345f256a1b4a238519dafc15c9a31bc5e6bad4fe))
|
|
||||||
* se agrego @bot-whatsapp/portal a package.json ([46a9fa6](https://github.com/leifermendez/bot-whatsapp/commit/46a9fa6793e06600335de998d2bd9d0691b02ca4))
|
|
||||||
|
|
||||||
### [0.1.17](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.16...v0.1.17) (2023-01-13)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* mod de starters para habiltar portal ([eceb170](https://github.com/leifermendez/bot-whatsapp/commit/eceb170df03721dca4183b658c863b94fa04bc84))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **ci:** pre-release ([aaec075](https://github.com/leifermendez/bot-whatsapp/commit/aaec0751408ab49483d428810d94aaf7d46acb94))
|
|
||||||
* correccion en starters app.js para portal QR ([f430380](https://github.com/leifermendez/bot-whatsapp/commit/f430380b4f23d41702395c96c628bf13bf443278))
|
|
||||||
* **starters:** :zap: added dockerfile ([230981e](https://github.com/leifermendez/bot-whatsapp/commit/230981e2676361149cb2a99def7f705e75009260))
|
|
||||||
|
|
||||||
### [0.1.16](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.15...v0.1.16) (2023-01-11)
|
|
||||||
|
|
||||||
### [0.1.15](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.14...v0.1.15) (2023-01-11)
|
|
||||||
|
|
||||||
### [0.1.14](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.13...v0.1.14) (2023-01-11)
|
|
||||||
|
|
||||||
### [0.1.13](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.12...v0.1.13) (2023-01-11)
|
|
||||||
|
|
||||||
### [0.1.12](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.10...v0.1.12) (2023-01-11)
|
|
||||||
|
|
||||||
### [0.1.9-pre](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.9...v0.1.9-pre) (2023-01-10)
|
|
||||||
|
|
||||||
### [0.1.7-pre-1](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-alpha...v0.1.7-pre-1) (2023-01-10)
|
|
||||||
|
|
||||||
### [0.1.7-alpha](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-pre...v0.1.7-alpha) (2023-01-10)
|
|
||||||
|
|
||||||
### [0.1.11](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.10...v0.1.11) (2023-01-11)
|
|
||||||
|
|
||||||
### [0.1.9-pre](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.9...v0.1.9-pre) (2023-01-10)
|
|
||||||
|
|
||||||
### [0.1.7-pre-1](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-alpha...v0.1.7-pre-1) (2023-01-10)
|
|
||||||
|
|
||||||
### [0.1.7-alpha](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-pre...v0.1.7-alpha) (2023-01-10)
|
|
||||||
|
|
||||||
### [0.1.10](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.8...v0.1.10) (2023-01-11)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* :fire: update qr package ([ecde23f](https://github.com/leifermendez/bot-whatsapp/commit/ecde23fdea65def209aa874af35a3f293e6b1a91))
|
|
||||||
|
|
||||||
### [0.1.8](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-pre...v0.1.8) (2023-01-10)
|
|
||||||
|
|
||||||
### [0.1.7](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.7-pre...v0.1.7) (2023-01-10)
|
|
||||||
|
|
||||||
### [0.1.6](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.5...v0.1.6) (2023-01-10)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* :zap: new portal web for qr scan ([cb2e869](https://github.com/leifermendez/bot-whatsapp/commit/cb2e8692a3f94c8b24993cd11dd564f094b0e4ef))
|
|
||||||
* :zap: new portal web for qr scan ([9e93795](https://github.com/leifermendez/bot-whatsapp/commit/9e93795e6fce38890045389da95184fef1fbe0da))
|
|
||||||
* :zap: new portal web for qr scan ([3c178ea](https://github.com/leifermendez/bot-whatsapp/commit/3c178ea113b140535a51f5dcd521dbb66251670e))
|
|
||||||
* :zap: new portal web for qr scan ([1f1f564](https://github.com/leifermendez/bot-whatsapp/commit/1f1f564f4e2e3aa13b84de500fe215e0c45c2770))
|
|
||||||
* :zap: new portal web for qr scan ([3de5f4b](https://github.com/leifermendez/bot-whatsapp/commit/3de5f4b77a10e30632ff7555f5af5d8e93cb2019))
|
|
||||||
* :zap: qr code filename ([d794f60](https://github.com/leifermendez/bot-whatsapp/commit/d794f604ac8a835e523709dbf18c9b1609bbd00e))
|
|
||||||
* :zap: qr portal ([246ecdc](https://github.com/leifermendez/bot-whatsapp/commit/246ecdc11a8c4e652867c842b612dc4ce73f9828))
|
|
||||||
* :zap: qr portal ([af8b401](https://github.com/leifermendez/bot-whatsapp/commit/af8b401d075e1c35065589ede61476461ce86b4d))
|
|
||||||
* agregamos dockerfile y webserver a starters ([f9e3bbc](https://github.com/leifermendez/bot-whatsapp/commit/f9e3bbc6655060408e4fdbe1d7e920c2ed4fca53))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* :zap: add Dockerfile, starter ([4e0d33c](https://github.com/leifermendez/bot-whatsapp/commit/4e0d33c6bb46ad259774f6d0c38c6c0b5f8ca4a9))
|
|
||||||
* :zap: fix inject port args ([20f752e](https://github.com/leifermendez/bot-whatsapp/commit/20f752e6c1b1f7d11948fc4f2f8950f7834df7d9))
|
|
||||||
* :zap: fix inject port args ([7a23eb0](https://github.com/leifermendez/bot-whatsapp/commit/7a23eb0cc6f93ec21c5ab34e46981ae7a93f42ff))
|
|
||||||
* **provider:** :zap: fix send image baileys ([2ddea54](https://github.com/leifermendez/bot-whatsapp/commit/2ddea5468d235035478d4e91e63c821da19da179))
|
|
||||||
* **provider:** :zap: fix send image baileys ([391e11c](https://github.com/leifermendez/bot-whatsapp/commit/391e11ce738cd64792b5237d69f3739b0263c198))
|
|
||||||
* **provider:** :zap: fix send image baileys ([5d10cb9](https://github.com/leifermendez/bot-whatsapp/commit/5d10cb9026da60043e9a2f86117ebb04d0631a3f))
|
|
||||||
* **provider:** fix error docker as root user ([5a033da](https://github.com/leifermendez/bot-whatsapp/commit/5a033da83aee1f614120bccf27c9f330500cc7b0))
|
|
||||||
|
|
||||||
### [0.1.4](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.5...v0.1.4) (2023-01-10)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* :zap: new portal web for qr scan ([cb2e869](https://github.com/leifermendez/bot-whatsapp/commit/cb2e8692a3f94c8b24993cd11dd564f094b0e4ef))
|
|
||||||
* :zap: new portal web for qr scan ([9e93795](https://github.com/leifermendez/bot-whatsapp/commit/9e93795e6fce38890045389da95184fef1fbe0da))
|
|
||||||
* :zap: new portal web for qr scan ([3c178ea](https://github.com/leifermendez/bot-whatsapp/commit/3c178ea113b140535a51f5dcd521dbb66251670e))
|
|
||||||
* :zap: new portal web for qr scan ([1f1f564](https://github.com/leifermendez/bot-whatsapp/commit/1f1f564f4e2e3aa13b84de500fe215e0c45c2770))
|
|
||||||
* :zap: new portal web for qr scan ([3de5f4b](https://github.com/leifermendez/bot-whatsapp/commit/3de5f4b77a10e30632ff7555f5af5d8e93cb2019))
|
|
||||||
* :zap: qr code filename ([d794f60](https://github.com/leifermendez/bot-whatsapp/commit/d794f604ac8a835e523709dbf18c9b1609bbd00e))
|
|
||||||
* :zap: qr portal ([246ecdc](https://github.com/leifermendez/bot-whatsapp/commit/246ecdc11a8c4e652867c842b612dc4ce73f9828))
|
|
||||||
* :zap: qr portal ([af8b401](https://github.com/leifermendez/bot-whatsapp/commit/af8b401d075e1c35065589ede61476461ce86b4d))
|
|
||||||
* agregamos dockerfile y webserver a starters ([f9e3bbc](https://github.com/leifermendez/bot-whatsapp/commit/f9e3bbc6655060408e4fdbe1d7e920c2ed4fca53))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* :zap: add Dockerfile, starter ([4e0d33c](https://github.com/leifermendez/bot-whatsapp/commit/4e0d33c6bb46ad259774f6d0c38c6c0b5f8ca4a9))
|
|
||||||
* :zap: fix inject port args ([20f752e](https://github.com/leifermendez/bot-whatsapp/commit/20f752e6c1b1f7d11948fc4f2f8950f7834df7d9))
|
|
||||||
* :zap: fix inject port args ([7a23eb0](https://github.com/leifermendez/bot-whatsapp/commit/7a23eb0cc6f93ec21c5ab34e46981ae7a93f42ff))
|
|
||||||
* **provider:** :zap: fix send image baileys ([2ddea54](https://github.com/leifermendez/bot-whatsapp/commit/2ddea5468d235035478d4e91e63c821da19da179))
|
|
||||||
* **provider:** :zap: fix send image baileys ([391e11c](https://github.com/leifermendez/bot-whatsapp/commit/391e11ce738cd64792b5237d69f3739b0263c198))
|
|
||||||
* **provider:** :zap: fix send image baileys ([5d10cb9](https://github.com/leifermendez/bot-whatsapp/commit/5d10cb9026da60043e9a2f86117ebb04d0631a3f))
|
|
||||||
* **provider:** fix error docker as root user ([5a033da](https://github.com/leifermendez/bot-whatsapp/commit/5a033da83aee1f614120bccf27c9f330500cc7b0))
|
|
||||||
|
|
||||||
### [0.1.3](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.2...v0.1.3) (2023-01-04)
|
### [0.1.3](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.2...v0.1.3) (2023-01-04)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
52
README.md
52
README.md
@@ -1,7 +1,8 @@
|
|||||||
# Chatbot Library
|
# Chatbot Library
|
||||||

|

|
||||||
[](http://commitizen.github.io/cz-cli/)
|
[](http://commitizen.github.io/cz-cli/)
|
||||||
[](https://link.codigoencasa.com/DISCORD)
|
[](https://github.com/codigoencasa/bot-whatsapp/actions/workflows/releases.yml)
|
||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img width="300" src="https://i.imgur.com/Oauef6t.png">
|
<img width="300" src="https://i.imgur.com/Oauef6t.png">
|
||||||
@@ -68,21 +69,14 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
|
|||||||
<sub><b>Juan Daniel Castaño</b></sub>
|
<sub><b>Juan Daniel Castaño</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
|
||||||
<a href="https://github.com/aurik3">
|
|
||||||
<img src="https://avatars.githubusercontent.com/u/37228512?v=4" width="50;" alt="aurik3"/>
|
|
||||||
<br />
|
|
||||||
<sub><b>Null</b></sub>
|
|
||||||
</a>
|
|
||||||
</td></tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/marianarolfo">
|
<a href="https://github.com/marianarolfo">
|
||||||
<img src="https://avatars.githubusercontent.com/u/68322254?v=4" width="50;" alt="marianarolfo"/>
|
<img src="https://avatars.githubusercontent.com/u/68322254?v=4" width="50;" alt="marianarolfo"/>
|
||||||
<br />
|
<br />
|
||||||
<sub><b>Null</b></sub>
|
<sub><b>Null</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td></tr>
|
||||||
|
<tr>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/HKong31">
|
<a href="https://github.com/HKong31">
|
||||||
<img src="https://avatars.githubusercontent.com/u/113340082?v=4" width="50;" alt="HKong31"/>
|
<img src="https://avatars.githubusercontent.com/u/113340082?v=4" width="50;" alt="HKong31"/>
|
||||||
@@ -112,16 +106,8 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
|
|||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/devrlbusiness">
|
<a href="https://github.com/aurik3">
|
||||||
<img src="https://avatars.githubusercontent.com/u/66280283?v=4" width="50;" alt="devrlbusiness"/>
|
<img src="https://avatars.githubusercontent.com/u/37228512?v=4" width="50;" alt="aurik3"/>
|
||||||
<br />
|
|
||||||
<sub><b>Developer RL Business</b></sub>
|
|
||||||
</a>
|
|
||||||
</td></tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center">
|
|
||||||
<a href="https://github.com/Gregoriotecnico">
|
|
||||||
<img src="https://avatars.githubusercontent.com/u/118696506?v=4" width="50;" alt="Gregoriotecnico"/>
|
|
||||||
<br />
|
<br />
|
||||||
<sub><b>Null</b></sub>
|
<sub><b>Null</b></sub>
|
||||||
</a>
|
</a>
|
||||||
@@ -132,14 +118,8 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
|
|||||||
<br />
|
<br />
|
||||||
<sub><b>Jose Luis Ferrete Olarte</b></sub>
|
<sub><b>Jose Luis Ferrete Olarte</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td></tr>
|
||||||
<td align="center">
|
<tr>
|
||||||
<a href="https://github.com/lisandroprada">
|
|
||||||
<img src="https://avatars.githubusercontent.com/u/7232326?v=4" width="50;" alt="lisandroprada"/>
|
|
||||||
<br />
|
|
||||||
<sub><b>Null</b></sub>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/6rak0">
|
<a href="https://github.com/6rak0">
|
||||||
<img src="https://avatars.githubusercontent.com/u/12260031?v=4" width="50;" alt="6rak0"/>
|
<img src="https://avatars.githubusercontent.com/u/12260031?v=4" width="50;" alt="6rak0"/>
|
||||||
@@ -147,26 +127,18 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
|
|||||||
<sub><b>Null</b></sub>
|
<sub><b>Null</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
|
||||||
<a href="https://github.com/Jhonarias13">
|
|
||||||
<img src="https://avatars.githubusercontent.com/u/19483021?v=4" width="50;" alt="Jhonarias13"/>
|
|
||||||
<br />
|
|
||||||
<sub><b>Jhon Freiman Arias</b></sub>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/tonyvazgar">
|
<a href="https://github.com/tonyvazgar">
|
||||||
<img src="https://avatars.githubusercontent.com/u/21047090?v=4" width="50;" alt="tonyvazgar"/>
|
<img src="https://avatars.githubusercontent.com/u/21047090?v=4" width="50;" alt="tonyvazgar"/>
|
||||||
<br />
|
<br />
|
||||||
<sub><b>Luis Antonio Vázquez García</b></sub>
|
<sub><b>Luis Antonio Vázquez García</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td></tr>
|
</td>
|
||||||
<tr>
|
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/Zamphiropolos">
|
<a href="https://github.com/ulisesvina">
|
||||||
<img src="https://avatars.githubusercontent.com/u/40876040?v=4" width="50;" alt="Zamphiropolos"/>
|
<img src="https://avatars.githubusercontent.com/u/20508563?v=4" width="50;" alt="ulisesvina"/>
|
||||||
<br />
|
<br />
|
||||||
<sub><b>Zamphi</b></sub>
|
<sub><b>Ulises Viña</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const MOCK_DB = require('../packages/database/src/mock')
|
|
||||||
const PROVIDER_DB = require('../packages/provider/src/mock')
|
|
||||||
const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
|
|
||||||
|
|
||||||
test(`[Caso - 01] Flow Basico`, async () => {
|
|
||||||
const [VALUE_A, VALUE_B] = ['hola', 'buenas']
|
|
||||||
|
|
||||||
const flow = addKeyword(VALUE_A).addAnswer(VALUE_B)
|
|
||||||
const provider = createProvider(PROVIDER_DB)
|
|
||||||
const database = new MOCK_DB()
|
|
||||||
|
|
||||||
createBot({
|
|
||||||
database,
|
|
||||||
flow: createFlow([flow]),
|
|
||||||
provider,
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(100, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: VALUE_A,
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(100)
|
|
||||||
|
|
||||||
const prevMsg = database.getPrevByNumber('000')
|
|
||||||
|
|
||||||
assert.is(prevMsg.answer, VALUE_B)
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise((res) => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const MOCK_DB = require('../packages/database/src/mock')
|
|
||||||
const PROVIDER_DB = require('../packages/provider/src/mock')
|
|
||||||
const {
|
|
||||||
addKeyword,
|
|
||||||
createBot,
|
|
||||||
createFlow,
|
|
||||||
createProvider,
|
|
||||||
} = require('../packages/bot/index')
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Falsear peticion async
|
|
||||||
* @param {*} fakeData
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
const fakeHTTP = async (fakeData = []) => {
|
|
||||||
console.log('⚡ Server request!')
|
|
||||||
await delay(50)
|
|
||||||
console.log('⚡ Server return!')
|
|
||||||
const data = fakeData.map((u, i) => ({ body: `${i + 1} ${u}` }))
|
|
||||||
console.log(data)
|
|
||||||
return Promise.resolve(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
test(`[Caso - 02] Flow (flowDynamic)`, async () => {
|
|
||||||
const MOCK_VALUES = [
|
|
||||||
'Bienvenido te envio muchas marcas (5510)',
|
|
||||||
'Seleccione marca del auto a cotizar, con el *número* correspondiente',
|
|
||||||
'Seleccione la sub marca del auto a cotizar, con el *número* correspondiente:',
|
|
||||||
'Los precios rondan:',
|
|
||||||
]
|
|
||||||
const provider = createProvider(PROVIDER_DB)
|
|
||||||
const database = new MOCK_DB()
|
|
||||||
|
|
||||||
const flujoPrincipal = addKeyword(['hola'])
|
|
||||||
.addAnswer(MOCK_VALUES[0], null, async (ctx, { flowDynamic }) => {
|
|
||||||
console.log('execute...')
|
|
||||||
const data = await fakeHTTP(['Ford', 'GM', 'BMW'])
|
|
||||||
return flowDynamic(data)
|
|
||||||
})
|
|
||||||
.addAnswer(MOCK_VALUES[1], null, async (ctx, { flowDynamic }) => {
|
|
||||||
const data = await fakeHTTP(['Ranger', 'Explorer'])
|
|
||||||
return flowDynamic(data)
|
|
||||||
})
|
|
||||||
.addAnswer(MOCK_VALUES[2], null, async (ctx, { flowDynamic }) => {
|
|
||||||
const data = await fakeHTTP(['Usado', 'Nuevos'])
|
|
||||||
return flowDynamic(data)
|
|
||||||
})
|
|
||||||
.addAnswer(MOCK_VALUES[3], null, async (ctx, { flowDynamic }) => {
|
|
||||||
const data = await fakeHTTP(['1000', '2000', '3000'])
|
|
||||||
return flowDynamic(data)
|
|
||||||
})
|
|
||||||
|
|
||||||
createBot({
|
|
||||||
database,
|
|
||||||
flow: createFlow([flujoPrincipal]),
|
|
||||||
provider,
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(0, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'hola',
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(1200)
|
|
||||||
const getHistory = database.listHistory.map((i) => i.answer)
|
|
||||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
|
||||||
|
|
||||||
//FlowDynamic
|
|
||||||
assert.is('1 Ford', getHistory[1])
|
|
||||||
assert.is('2 GM', getHistory[2])
|
|
||||||
assert.is('3 BMW', getHistory[3])
|
|
||||||
|
|
||||||
assert.is(MOCK_VALUES[1], getHistory[4])
|
|
||||||
|
|
||||||
//FlowDynamic
|
|
||||||
assert.is('1 Ranger', getHistory[5])
|
|
||||||
assert.is('2 Explorer', getHistory[6])
|
|
||||||
|
|
||||||
assert.is(MOCK_VALUES[2], getHistory[7])
|
|
||||||
|
|
||||||
//FlowDynamic
|
|
||||||
assert.is('1 Usado', getHistory[8])
|
|
||||||
assert.is('2 Nuevos', getHistory[9])
|
|
||||||
|
|
||||||
assert.is(MOCK_VALUES[3], getHistory[10])
|
|
||||||
|
|
||||||
//FlowDynamic
|
|
||||||
assert.is('1 1000', getHistory[11])
|
|
||||||
assert.is('2 2000', getHistory[12])
|
|
||||||
assert.is('3 3000', getHistory[13])
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise((res) => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const MOCK_DB = require('../packages/database/src/mock')
|
|
||||||
const PROVIDER_DB = require('../packages/provider/src/mock')
|
|
||||||
const {
|
|
||||||
addKeyword,
|
|
||||||
createBot,
|
|
||||||
createFlow,
|
|
||||||
createProvider,
|
|
||||||
} = require('../packages/bot/index')
|
|
||||||
|
|
||||||
test(`[Caso - 03] Flow puro`, async () => {
|
|
||||||
const MOCK_VALUES = ['Bienvenido a mi tienda', 'Como estas?']
|
|
||||||
|
|
||||||
const provider = createProvider(PROVIDER_DB)
|
|
||||||
const database = new MOCK_DB()
|
|
||||||
|
|
||||||
const flujoPrincipal = addKeyword(['hola'])
|
|
||||||
.addAnswer(MOCK_VALUES[0])
|
|
||||||
.addAnswer(MOCK_VALUES[1])
|
|
||||||
|
|
||||||
createBot({
|
|
||||||
database,
|
|
||||||
flow: createFlow([flujoPrincipal]),
|
|
||||||
provider,
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(0, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'hola',
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(10)
|
|
||||||
const getHistory = database.listHistory.map((i) => i.answer)
|
|
||||||
|
|
||||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
|
||||||
assert.is(MOCK_VALUES[1], getHistory[1])
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise((res) => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const MOCK_DB = require('../packages/database/src/mock')
|
|
||||||
const PROVIDER_DB = require('../packages/provider/src/mock')
|
|
||||||
const {
|
|
||||||
addKeyword,
|
|
||||||
createBot,
|
|
||||||
createFlow,
|
|
||||||
createProvider,
|
|
||||||
} = require('../packages/bot/index')
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Falsear peticion async
|
|
||||||
* @param {*} fakeData
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
const fakeHTTP = async (fakeData = []) => {
|
|
||||||
console.log('⚡ Server request!')
|
|
||||||
await delay(50)
|
|
||||||
console.log('⚡ Server return!')
|
|
||||||
const data = fakeData.map((u, i) => ({ body: `${i + 1} ${u}` }))
|
|
||||||
console.log(data)
|
|
||||||
return Promise.resolve(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
test(`[Caso - 04] Romper flujo (endFlow)`, async () => {
|
|
||||||
const MOCK_VALUES = [
|
|
||||||
'Bienvenido te envio muchas marcas (5510)',
|
|
||||||
'Seleccione marca del auto a cotizar, con el *número* correspondiente',
|
|
||||||
'Seleccione la sub marca del auto a cotizar, con el *número* correspondiente:',
|
|
||||||
'Los precios rondan:',
|
|
||||||
]
|
|
||||||
const provider = createProvider(PROVIDER_DB)
|
|
||||||
const database = new MOCK_DB()
|
|
||||||
|
|
||||||
const flujoPrincipal = addKeyword(['hola'])
|
|
||||||
.addAnswer(MOCK_VALUES[0], null, async (ctx, { flowDynamic }) => {
|
|
||||||
console.log('execute...')
|
|
||||||
const data = await fakeHTTP(['Ford', 'GM', 'BMW'])
|
|
||||||
return flowDynamic(data)
|
|
||||||
})
|
|
||||||
.addAnswer(MOCK_VALUES[1], null, async (ctx, { endFlow }) => {
|
|
||||||
return endFlow()
|
|
||||||
})
|
|
||||||
.addAnswer(MOCK_VALUES[2], null, async (ctx, { flowDynamic }) => {
|
|
||||||
const data = await fakeHTTP(['Usado', 'Nuevos'])
|
|
||||||
return flowDynamic(data)
|
|
||||||
})
|
|
||||||
.addAnswer(MOCK_VALUES[3], null, async (ctx, { flowDynamic }) => {
|
|
||||||
const data = await fakeHTTP(['1000', '2000', '3000'])
|
|
||||||
return flowDynamic(data)
|
|
||||||
})
|
|
||||||
|
|
||||||
createBot({
|
|
||||||
database,
|
|
||||||
flow: createFlow([flujoPrincipal]),
|
|
||||||
provider,
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(0, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'hola',
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(1200)
|
|
||||||
const getHistory = database.listHistory.map((i) => i.answer)
|
|
||||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
|
||||||
|
|
||||||
//FlowDynamic
|
|
||||||
assert.is('1 Ford', getHistory[1])
|
|
||||||
assert.is('2 GM', getHistory[2])
|
|
||||||
assert.is('3 BMW', getHistory[3])
|
|
||||||
|
|
||||||
assert.is(MOCK_VALUES[1], getHistory[4])
|
|
||||||
assert.is(undefined, getHistory[5])
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise((res) => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const MOCK_DB = require('../packages/database/src/mock')
|
|
||||||
const PROVIDER_DB = require('../packages/provider/src/mock')
|
|
||||||
const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Falsear peticion async
|
|
||||||
* @param {*} fakeData
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
const fakeHTTP = async (fakeData = []) => {
|
|
||||||
await delay(5)
|
|
||||||
const data = fakeData.map((u, i) => ({ body: `${i + 1} ${u}` }))
|
|
||||||
return Promise.resolve(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
test(`[Caso - 05] Continuar Flujo (continueFlow)`, async () => {
|
|
||||||
const MOCK_VALUES = ['¿CUal es tu email?', 'Continuamos....', '¿Cual es tu edad?']
|
|
||||||
const provider = createProvider(PROVIDER_DB)
|
|
||||||
const database = new MOCK_DB()
|
|
||||||
|
|
||||||
const flujoPrincipal = addKeyword(['hola'])
|
|
||||||
.addAnswer(
|
|
||||||
MOCK_VALUES[0],
|
|
||||||
{
|
|
||||||
capture: true,
|
|
||||||
},
|
|
||||||
async (ctx, { flowDynamic, fallBack }) => {
|
|
||||||
const validation = ctx.body.includes('@')
|
|
||||||
|
|
||||||
if (validation) {
|
|
||||||
const getDataFromApi = await fakeHTTP(['Gracias por tu email se ha validado de manera correcta'])
|
|
||||||
return flowDynamic(getDataFromApi)
|
|
||||||
}
|
|
||||||
return fallBack(validation)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.addAnswer(MOCK_VALUES[1])
|
|
||||||
.addAnswer(MOCK_VALUES[2], { capture: true }, async (ctx, { flowDynamic, fallBack }) => {
|
|
||||||
if (ctx.body !== '18') {
|
|
||||||
await delay(50)
|
|
||||||
return fallBack(false, 'Ups creo que no eres mayor de edad')
|
|
||||||
}
|
|
||||||
return flowDynamic('Bien tu edad es correcta!')
|
|
||||||
})
|
|
||||||
.addAnswer('Puedes pasar')
|
|
||||||
|
|
||||||
createBot({
|
|
||||||
database,
|
|
||||||
flow: createFlow([flujoPrincipal]),
|
|
||||||
provider,
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(0, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'hola',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(10, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'this is not email value',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(20, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'test@test.com',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(90, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: '20',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(200, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: '18',
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(1200)
|
|
||||||
const getHistory = database.listHistory.map((i) => i.answer)
|
|
||||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
|
||||||
assert.is('this is not email value', getHistory[1])
|
|
||||||
assert.is(MOCK_VALUES[0], getHistory[2])
|
|
||||||
assert.is('test@test.com', getHistory[3])
|
|
||||||
assert.is('1 Gracias por tu email se ha validado de manera correcta', getHistory[4])
|
|
||||||
assert.is(MOCK_VALUES[1], getHistory[5])
|
|
||||||
assert.is(MOCK_VALUES[2], getHistory[6])
|
|
||||||
assert.is('20', getHistory[7])
|
|
||||||
assert.is('Ups creo que no eres mayor de edad', getHistory[8])
|
|
||||||
assert.is('18', getHistory[9])
|
|
||||||
assert.is('Bien tu edad es correcta!', getHistory[10])
|
|
||||||
assert.is('Puedes pasar', getHistory[11])
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise((res) => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const MOCK_DB = require('../packages/database/src/mock')
|
|
||||||
const PROVIDER_DB = require('../packages/provider/src/mock')
|
|
||||||
const {
|
|
||||||
addKeyword,
|
|
||||||
createBot,
|
|
||||||
createFlow,
|
|
||||||
createProvider,
|
|
||||||
} = require('../packages/bot/index')
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Falsear peticion async
|
|
||||||
* @param {*} fakeData
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
const fakeHTTP = async (fakeData = []) => {
|
|
||||||
await delay(5)
|
|
||||||
const data = fakeData.map((u, i) => ({ body: `${i + 1} ${u}` }))
|
|
||||||
return Promise.resolve(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
test(`[Caso - 06] Finalizar Flujo (endFlow)`, async () => {
|
|
||||||
const MOCK_VALUES = [
|
|
||||||
'¿CUal es tu email?',
|
|
||||||
'Continuamos....',
|
|
||||||
'¿Cual es tu edad?',
|
|
||||||
]
|
|
||||||
const provider = createProvider(PROVIDER_DB)
|
|
||||||
const database = new MOCK_DB()
|
|
||||||
|
|
||||||
const flujoPrincipal = addKeyword(['hola'])
|
|
||||||
.addAnswer(
|
|
||||||
MOCK_VALUES[0],
|
|
||||||
{
|
|
||||||
capture: true,
|
|
||||||
},
|
|
||||||
async (ctx, { flowDynamic, fallBack }) => {
|
|
||||||
const validation = ctx.body.includes('@')
|
|
||||||
|
|
||||||
if (validation) {
|
|
||||||
const getDataFromApi = await fakeHTTP([
|
|
||||||
'Gracias por tu email se ha validado de manera correcta',
|
|
||||||
])
|
|
||||||
return flowDynamic(getDataFromApi)
|
|
||||||
}
|
|
||||||
return fallBack(validation)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.addAnswer(MOCK_VALUES[1], null, async (_, { endFlow }) => {
|
|
||||||
return endFlow()
|
|
||||||
})
|
|
||||||
.addAnswer(
|
|
||||||
MOCK_VALUES[2],
|
|
||||||
{ capture: true },
|
|
||||||
async (ctx, { flowDynamic, fallBack }) => {
|
|
||||||
if (ctx.body !== '18') {
|
|
||||||
await delay(50)
|
|
||||||
return fallBack(false, 'Ups creo que no eres mayor de edad')
|
|
||||||
}
|
|
||||||
return flowDynamic('Bien tu edad es correcta!')
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.addAnswer('Puedes pasar')
|
|
||||||
|
|
||||||
createBot({
|
|
||||||
database,
|
|
||||||
flow: createFlow([flujoPrincipal]),
|
|
||||||
provider,
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(0, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'hola',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(10, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'this is not email value',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(20, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'test@test.com',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(90, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: '20',
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(1200)
|
|
||||||
const getHistory = database.listHistory.map((i) => i.answer)
|
|
||||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
|
||||||
assert.is('this is not email value', getHistory[1])
|
|
||||||
assert.is(MOCK_VALUES[0], getHistory[2])
|
|
||||||
assert.is('test@test.com', getHistory[3])
|
|
||||||
assert.is(
|
|
||||||
'1 Gracias por tu email se ha validado de manera correcta',
|
|
||||||
getHistory[4]
|
|
||||||
)
|
|
||||||
assert.is(MOCK_VALUES[1], getHistory[5])
|
|
||||||
assert.is('20', getHistory[6])
|
|
||||||
assert.is(undefined, getHistory[7])
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise((res) => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const MOCK_DB = require('../packages/database/src/mock')
|
|
||||||
const PROVIDER_DB = require('../packages/provider/src/mock')
|
|
||||||
const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Falsear peticion async
|
|
||||||
* @param {*} fakeData
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
const fakeHTTP = async (fakeData = []) => {
|
|
||||||
await delay(5)
|
|
||||||
const data = fakeData.map((u, i) => ({ body: `${i + 1} ${u}` }))
|
|
||||||
return Promise.resolve(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
let STATE_APP = {}
|
|
||||||
|
|
||||||
test(`[Caso - 07] Retornar estado`, async () => {
|
|
||||||
const MOCK_VALUES = ['¿Cual es tu nombre?', '¿Cual es tu edad?', 'Tu datos son:']
|
|
||||||
const provider = createProvider(PROVIDER_DB)
|
|
||||||
const database = new MOCK_DB()
|
|
||||||
|
|
||||||
const flujoPrincipal = addKeyword(['hola'])
|
|
||||||
.addAnswer(
|
|
||||||
MOCK_VALUES[0],
|
|
||||||
{
|
|
||||||
capture: true,
|
|
||||||
},
|
|
||||||
async (ctx, { flowDynamic, fallBack }) => {
|
|
||||||
STATE_APP[ctx.from] = { ...STATE_APP[ctx.from], name: ctx.body }
|
|
||||||
|
|
||||||
flowDynamic('Gracias por tu nombre!')
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.addAnswer(
|
|
||||||
MOCK_VALUES[1],
|
|
||||||
{
|
|
||||||
capture: true,
|
|
||||||
},
|
|
||||||
async (ctx, { flowDynamic, endFlow }) => {
|
|
||||||
STATE_APP[ctx.from] = { ...STATE_APP[ctx.from], age: ctx.body }
|
|
||||||
|
|
||||||
await flowDynamic('Gracias por tu edad!')
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.addAnswer(MOCK_VALUES[2], null, async (ctx, { flowDynamic }) => {
|
|
||||||
flowDynamic(`Nombre: ${STATE_APP[ctx.from].name} Edad: ${STATE_APP[ctx.from].age}`)
|
|
||||||
})
|
|
||||||
.addAnswer('🤖🤖 Gracias por tu participacion')
|
|
||||||
|
|
||||||
createBot({
|
|
||||||
database,
|
|
||||||
flow: createFlow([flujoPrincipal]),
|
|
||||||
provider,
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(0, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'hola',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(20, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'Leifer',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(40, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: '90',
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(1200)
|
|
||||||
const getHistory = database.listHistory.map((i) => i.answer)
|
|
||||||
assert.is(MOCK_VALUES[0], getHistory[0])
|
|
||||||
assert.is('Leifer', getHistory[1])
|
|
||||||
assert.is('Gracias por tu nombre!', getHistory[2])
|
|
||||||
assert.is('¿Cual es tu edad?', getHistory[3])
|
|
||||||
assert.is('90', getHistory[4])
|
|
||||||
assert.is('Gracias por tu edad!', getHistory[5])
|
|
||||||
assert.is('Tu datos son:', getHistory[6])
|
|
||||||
assert.is('Nombre: Leifer Edad: 90', getHistory[7])
|
|
||||||
assert.is('🤖🤖 Gracias por tu participacion', getHistory[8])
|
|
||||||
assert.is(undefined, getHistory[9])
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise((res) => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const MOCK_DB = require('../packages/database/src/mock')
|
|
||||||
const PROVIDER_DB = require('../packages/provider/src/mock')
|
|
||||||
const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
|
|
||||||
|
|
||||||
test(`[Caso - 08] Regular expression on keyword`, async () => {
|
|
||||||
const provider = createProvider(PROVIDER_DB)
|
|
||||||
const database = new MOCK_DB()
|
|
||||||
|
|
||||||
const REGEX_CREDIT_NUMBER = `/(^4[0-9]{12}(?:[0-9]{3})?$)|(^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$)|(3[47][0-9]{13})|(^3(?:0[0-5]|[68][0-9])[0-9]{11}$)|(^6(?:011|5[0-9]{2})[0-9]{12}$)|(^(?:2131|1800|35\d{3})\d{11}$)/gm`
|
|
||||||
const flujoPrincipal = addKeyword(REGEX_CREDIT_NUMBER, { regex: true })
|
|
||||||
.addAnswer(`Gracias por proporcionar un numero de tarjeta valido`)
|
|
||||||
.addAnswer('Fin!')
|
|
||||||
|
|
||||||
createBot({
|
|
||||||
database,
|
|
||||||
flow: createFlow([flujoPrincipal]),
|
|
||||||
provider,
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(0, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: 'hola',
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(20, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: '374245455400126',
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(40)
|
|
||||||
const getHistory = database.listHistory.map((i) => i.answer)
|
|
||||||
assert.is('Gracias por proporcionar un numero de tarjeta valido', getHistory[0])
|
|
||||||
assert.is('Fin!', getHistory[1])
|
|
||||||
assert.is(undefined, getHistory[2])
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise((res) => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const MOCK_DB = require('../packages/database/src/mock')
|
|
||||||
const PROVIDER_MOCK = require('../packages/provider/src/mock')
|
|
||||||
const { addKeyword, createBot, createFlow, createProvider } = require('../packages/bot/index')
|
|
||||||
|
|
||||||
let PROVIDER = undefined
|
|
||||||
|
|
||||||
test(`[Caso - 09] Check provider WS`, async () => {
|
|
||||||
const [VALUE_A, VALUE_B] = ['hola', 'buenas']
|
|
||||||
|
|
||||||
const flow = addKeyword(VALUE_A).addAnswer(VALUE_B, null, async (_, { provider }) => {
|
|
||||||
PROVIDER = provider
|
|
||||||
})
|
|
||||||
const provider = createProvider(PROVIDER_MOCK)
|
|
||||||
const database = new MOCK_DB()
|
|
||||||
|
|
||||||
createBot({
|
|
||||||
database,
|
|
||||||
flow: createFlow([flow]),
|
|
||||||
provider,
|
|
||||||
})
|
|
||||||
|
|
||||||
provider.delaySendMessage(100, 'message', {
|
|
||||||
from: '000',
|
|
||||||
body: VALUE_A,
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(100)
|
|
||||||
|
|
||||||
const prevMsg = database.getPrevByNumber('000')
|
|
||||||
|
|
||||||
assert.is(prevMsg.answer, VALUE_B)
|
|
||||||
assert.is(typeof PROVIDER.sendMessage, 'function')
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise((res) => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
13
package.json
13
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@bot-whatsapp/root",
|
"name": "@bot-whatsapp/root",
|
||||||
"version": "0.1.20",
|
"version": "0.1.3",
|
||||||
"description": "Bot de wahtsapp open source para MVP o pequeños negocios",
|
"description": "Bot de wahtsapp open source para MVP o pequeños negocios",
|
||||||
"main": "app.js",
|
"main": "app.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
@@ -13,19 +13,15 @@
|
|||||||
"contexts:rollup": "rollup --config ./packages/contexts/rollup-contexts.config.js",
|
"contexts:rollup": "rollup --config ./packages/contexts/rollup-contexts.config.js",
|
||||||
"database:rollup": "rollup --config ./packages/database/rollup-database.config.js",
|
"database:rollup": "rollup --config ./packages/database/rollup-database.config.js",
|
||||||
"create-bot-whatsapp:rollup": "rollup --config ./packages/create-bot-whatsapp/rollup-create.config.js",
|
"create-bot-whatsapp:rollup": "rollup --config ./packages/create-bot-whatsapp/rollup-create.config.js",
|
||||||
"portal:rollup": "rollup --config ./packages/portal/rollup-portal.config.js",
|
|
||||||
"format:check": "prettier --check ./packages",
|
"format:check": "prettier --check ./packages",
|
||||||
"format:write": "prettier --write ./packages",
|
"format:write": "prettier --write ./packages",
|
||||||
"fmt.staged": "pretty-quick --staged",
|
"fmt.staged": "pretty-quick --staged",
|
||||||
"lint:check": "eslint ./packages",
|
"lint:check": "eslint ./packages",
|
||||||
"lint:fix": "eslint --fix ./packages",
|
"lint:fix": "eslint --fix ./packages",
|
||||||
"build:portal-web": "cd ./packages/portal/ && yarn run build.types && yarn run build.client && yarn run build.server && yarn run lint --fix",
|
"build": "yarn run cli:rollup && yarn run bot:rollup && yarn run provider:rollup && yarn run database:rollup && yarn run contexts:rollup && yarn run create-bot-whatsapp:rollup",
|
||||||
"build:full": "yarn run build:portal-web && yarn run cli:rollup && yarn run bot:rollup && yarn run provider:rollup && yarn run database:rollup && yarn run contexts:rollup && yarn run create-bot-whatsapp:rollup && yarn run portal:rollup",
|
|
||||||
"build": "yarn run cli:rollup && yarn run bot:rollup && yarn run provider:rollup && yarn run database:rollup && yarn run contexts:rollup && yarn run create-bot-whatsapp:rollup && yarn run portal:rollup",
|
|
||||||
"copy.lib": "node ./scripts/move.js",
|
"copy.lib": "node ./scripts/move.js",
|
||||||
"test.unit": "node ./node_modules/uvu/bin.js packages test",
|
"test.unit": "node ./node_modules/uvu/bin.js packages test",
|
||||||
"test.e2e": "node ./node_modules/uvu/bin.js __test__",
|
"test.coverage": "node ./node_modules/c8/bin/c8.js npm run test.unit",
|
||||||
"test.coverage": "node ./node_modules/c8/bin/c8.js npm run test.unit && npm run test.e2e",
|
|
||||||
"test": "npm run test.coverage",
|
"test": "npm run test.coverage",
|
||||||
"cli": "node ./packages/cli/bin/cli.js",
|
"cli": "node ./packages/cli/bin/cli.js",
|
||||||
"create": "node ./packages/create-bot-whatsapp/bin/create.js",
|
"create": "node ./packages/create-bot-whatsapp/bin/create.js",
|
||||||
@@ -43,7 +39,6 @@
|
|||||||
"packages/database",
|
"packages/database",
|
||||||
"packages/provider",
|
"packages/provider",
|
||||||
"packages/contexts",
|
"packages/contexts",
|
||||||
"packages/portal",
|
|
||||||
"packages/docs"
|
"packages/docs"
|
||||||
],
|
],
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -68,7 +63,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.3.0",
|
"@commitlint/cli": "^17.3.0",
|
||||||
"@commitlint/config-conventional": "^17.3.0",
|
"@commitlint/config-conventional": "^17.3.0",
|
||||||
"@octokit/core": "^4.1.0",
|
|
||||||
"@rollup/plugin-commonjs": "^23.0.2",
|
"@rollup/plugin-commonjs": "^23.0.2",
|
||||||
"@rollup/plugin-json": "^5.0.1",
|
"@rollup/plugin-json": "^5.0.1",
|
||||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||||
@@ -81,7 +75,6 @@
|
|||||||
"fs-extra": "^11.1.0",
|
"fs-extra": "^11.1.0",
|
||||||
"git-cz": "^4.9.0",
|
"git-cz": "^4.9.0",
|
||||||
"husky": "^8.0.2",
|
"husky": "^8.0.2",
|
||||||
"mime-types": "^2.1.35",
|
|
||||||
"only-allow": "^1.1.1",
|
"only-allow": "^1.1.1",
|
||||||
"prettier": "^2.8.0",
|
"prettier": "^2.8.0",
|
||||||
"pretty-quick": "^3.1.3",
|
"pretty-quick": "^3.1.3",
|
||||||
|
|||||||
@@ -8,9 +8,6 @@ const { createWriteStream } = require('fs')
|
|||||||
const logger = new Console({
|
const logger = new Console({
|
||||||
stdout: createWriteStream(`${process.cwd()}/core.class.log`),
|
stdout: createWriteStream(`${process.cwd()}/core.class.log`),
|
||||||
})
|
})
|
||||||
|
|
||||||
const QueuePrincipal = new Queue()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [ ] Escuchar eventos del provider asegurarte que los provider emitan eventos
|
* [ ] Escuchar eventos del provider asegurarte que los provider emitan eventos
|
||||||
* [ ] Guardar historial en db
|
* [ ] Guardar historial en db
|
||||||
@@ -21,12 +18,10 @@ class CoreClass {
|
|||||||
flowClass
|
flowClass
|
||||||
databaseClass
|
databaseClass
|
||||||
providerClass
|
providerClass
|
||||||
generalArgs = { blackList: [] }
|
constructor(_flow, _database, _provider) {
|
||||||
constructor(_flow, _database, _provider, _args) {
|
|
||||||
this.flowClass = _flow
|
this.flowClass = _flow
|
||||||
this.databaseClass = _database
|
this.databaseClass = _database
|
||||||
this.providerClass = _provider
|
this.providerClass = _provider
|
||||||
this.generalArgs = { ...this.generalArgs, ..._args }
|
|
||||||
|
|
||||||
for (const { event, func } of this.listenerBusEvents()) {
|
for (const { event, func } of this.listenerBusEvents()) {
|
||||||
this.providerClass.on(event, func)
|
this.providerClass.on(event, func)
|
||||||
@@ -43,7 +38,8 @@ class CoreClass {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
event: 'require_action',
|
event: 'require_action',
|
||||||
func: ({ instructions, title = '⚡⚡ ACCIÓN REQUERIDA ⚡⚡' }) => printer(instructions, title),
|
func: ({ instructions, title = '⚡⚡ ACCIÓN REQUERIDA ⚡⚡' }) =>
|
||||||
|
printer(instructions, title),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
event: 'ready',
|
event: 'ready',
|
||||||
@@ -51,7 +47,8 @@ class CoreClass {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
event: 'auth_failure',
|
event: 'auth_failure',
|
||||||
func: ({ instructions }) => printer(instructions, '⚡⚡ ERROR AUTH ⚡⚡'),
|
func: ({ instructions }) =>
|
||||||
|
printer(instructions, '⚡⚡ ERROR AUTH ⚡⚡'),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -69,14 +66,14 @@ class CoreClass {
|
|||||||
logger.log(`[handleMsg]: `, messageCtxInComming)
|
logger.log(`[handleMsg]: `, messageCtxInComming)
|
||||||
const { body, from } = messageCtxInComming
|
const { body, from } = messageCtxInComming
|
||||||
let msgToSend = []
|
let msgToSend = []
|
||||||
let endFlowFlag = false
|
|
||||||
let fallBackFlag = false
|
let fallBackFlag = false
|
||||||
if (this.generalArgs.blackList.includes(from)) return
|
|
||||||
if (!body) return
|
|
||||||
if (!body.length) return
|
if (!body.length) return
|
||||||
|
|
||||||
let prevMsg = await this.databaseClass.getPrevByNumber(from)
|
const prevMsg = await this.databaseClass.getPrevByNumber(from)
|
||||||
const refToContinue = this.flowClass.findBySerialize(prevMsg?.refSerialize)
|
const refToContinue = this.flowClass.findBySerialize(
|
||||||
|
prevMsg?.refSerialize
|
||||||
|
)
|
||||||
|
|
||||||
if (prevMsg?.ref) {
|
if (prevMsg?.ref) {
|
||||||
const ctxByNumber = toCtx({
|
const ctxByNumber = toCtx({
|
||||||
@@ -87,128 +84,53 @@ class CoreClass {
|
|||||||
this.databaseClass.save(ctxByNumber)
|
this.databaseClass.save(ctxByNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 📄 Crar CTX de mensaje (uso private)
|
|
||||||
const createCtxMessage = (payload = {}, index = 0) => {
|
|
||||||
const body = typeof payload === 'string' ? payload : payload?.body ?? payload?.answer
|
|
||||||
const media = payload?.media ?? null
|
|
||||||
const buttons = payload?.buttons ?? []
|
|
||||||
const capture = payload?.capture ?? false
|
|
||||||
|
|
||||||
return toCtx({
|
|
||||||
body,
|
|
||||||
from,
|
|
||||||
keyword: null,
|
|
||||||
index,
|
|
||||||
options: { media, buttons, capture },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 📄 Limpiar cola de procesos
|
|
||||||
const clearQueue = () => {
|
|
||||||
QueuePrincipal.pendingPromise = false
|
|
||||||
QueuePrincipal.queue = []
|
|
||||||
}
|
|
||||||
|
|
||||||
// 📄 Finalizar flujo
|
|
||||||
const endFlow = async (message = null) => {
|
|
||||||
endFlowFlag = true
|
|
||||||
if (message) this.sendProviderAndSave(from, createCtxMessage(message))
|
|
||||||
clearQueue()
|
|
||||||
sendFlow([])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 📄 Esta funcion se encarga de enviar un array de mensajes dentro de este ctx
|
|
||||||
const sendFlow = async (messageToSend, numberOrId, options = { prev: prevMsg }) => {
|
|
||||||
if (options.prev?.options?.capture) await cbEveryCtx(options.prev?.ref)
|
|
||||||
|
|
||||||
const queue = []
|
|
||||||
for (const ctxMessage of messageToSend) {
|
|
||||||
if (endFlowFlag) return
|
|
||||||
const delayMs = ctxMessage?.options?.delay || 0
|
|
||||||
if (delayMs) await delay(delayMs)
|
|
||||||
QueuePrincipal.enqueue(() =>
|
|
||||||
Promise.all([
|
|
||||||
this.sendProviderAndSave(numberOrId, ctxMessage).then(() => resolveCbEveryCtx(ctxMessage)),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return Promise.all(queue)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 📄 [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje
|
// 📄 [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje
|
||||||
const fallBack = async (validation = false, message = null) => {
|
const fallBack = () => {
|
||||||
QueuePrincipal.queue = []
|
fallBackFlag = true
|
||||||
|
msgToSend = this.flowClass.find(refToContinue?.keyword, true) || []
|
||||||
if (validation) {
|
this.sendFlow(msgToSend, from)
|
||||||
const currentPrev = await this.databaseClass.getPrevByNumber(from)
|
return refToContinue
|
||||||
const nextFlow = await this.flowClass.find(refToContinue?.ref, true)
|
|
||||||
const filterNextFlow = nextFlow.filter((msg) => msg.refSerialize !== currentPrev?.refSerialize)
|
|
||||||
|
|
||||||
return sendFlow(filterNextFlow, from, { prev: undefined })
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.sendProviderAndSave(from, {
|
|
||||||
...prevMsg,
|
|
||||||
answer: typeof message === 'string' ? message : message?.body ?? prevMsg.answer,
|
|
||||||
options: {
|
|
||||||
...prevMsg.options,
|
|
||||||
buttons: prevMsg.options?.buttons,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 📄 [options: flowDynamic]: esta funcion se encarga de responder un array de respuesta esta limitado a 5 mensajes
|
// 📄 [options: flowDynamic]: esta funcion se encarga de responder un array de respuesta esta limitado a 5 mensajes
|
||||||
// para evitar bloque de whatsapp
|
// para evitar bloque de whatsapp
|
||||||
|
const flowDynamic = (listMsg = [], optListMsg = { limit: 3 }) => {
|
||||||
|
if (!Array.isArray(listMsg))
|
||||||
|
throw new Error('Esto debe ser un ARRAY')
|
||||||
|
|
||||||
const flowDynamic = async (listMsg = []) => {
|
const parseListMsg = listMsg
|
||||||
if (!Array.isArray(listMsg)) listMsg = [listMsg]
|
.map(({ body }, index) =>
|
||||||
|
toCtx({
|
||||||
const parseListMsg = listMsg.map((opt, index) => createCtxMessage(opt, index))
|
body,
|
||||||
const currentPrev = await this.databaseClass.getPrevByNumber(from)
|
from,
|
||||||
|
keyword: null,
|
||||||
const skipContinueFlow = async () => {
|
index,
|
||||||
const nextFlow = await this.flowClass.find(refToContinue?.ref, true)
|
})
|
||||||
const filterNextFlow = nextFlow.filter((msg) => msg.refSerialize !== currentPrev?.refSerialize)
|
)
|
||||||
const isContinueFlow = filterNextFlow.map((i) => i.keyword).includes(currentPrev?.ref)
|
.slice(0, optListMsg.limit)
|
||||||
return {
|
msgToSend = parseListMsg
|
||||||
continue: !isContinueFlow,
|
this.sendFlow(msgToSend, from)
|
||||||
contexts: filterNextFlow,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endFlowFlag) return
|
|
||||||
for (const msg of parseListMsg) {
|
|
||||||
await this.sendProviderAndSave(from, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
const continueFlowData = await skipContinueFlow()
|
|
||||||
|
|
||||||
if (continueFlowData.continue) return sendFlow(continueFlowData.contexts, from, { prev: undefined })
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback o fallback
|
|
||||||
const resolveCbEveryCtx = async (ctxMessage) => {
|
|
||||||
if (!ctxMessage?.options?.capture) return await cbEveryCtx(ctxMessage?.ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback y ejecutarlo
|
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback y ejecutarlo
|
||||||
const cbEveryCtx = async (inRef) => {
|
const cbEveryCtx = (inRef) => {
|
||||||
const provider = this.providerClass
|
this.flowClass.allCallbacks[inRef](messageCtxInComming, {
|
||||||
|
|
||||||
if (!this.flowClass.allCallbacks[inRef]) return Promise.resolve()
|
|
||||||
return this.flowClass.allCallbacks[inRef](messageCtxInComming, {
|
|
||||||
provider,
|
|
||||||
fallBack,
|
fallBack,
|
||||||
flowDynamic,
|
flowDynamic,
|
||||||
endFlow,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 📄 [options: callback]: Si se tiene un callback se ejecuta
|
||||||
|
if (!fallBackFlag) {
|
||||||
|
if (refToContinue?.options?.capture) cbEveryCtx(refToContinue?.ref)
|
||||||
|
for (const ite of this.flowClass.find(body)) {
|
||||||
|
if (!ite?.options?.capture) cbEveryCtx(ite?.ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 📄🤘(tiene return) [options: nested(array)]: Si se tiene flujos hijos los implementa
|
// 📄🤘(tiene return) [options: nested(array)]: Si se tiene flujos hijos los implementa
|
||||||
if (!endFlowFlag && prevMsg?.options?.nested?.length) {
|
if (!fallBackFlag && prevMsg?.options?.nested?.length) {
|
||||||
const nestedRef = prevMsg.options.nested
|
const nestedRef = prevMsg.options.nested
|
||||||
const flowStandalone = nestedRef.map((f) => ({
|
const flowStandalone = nestedRef.map((f) => ({
|
||||||
...nestedRef.find((r) => r.refSerialize === f.refSerialize),
|
...nestedRef.find((r) => r.refSerialize === f.refSerialize),
|
||||||
@@ -216,23 +138,28 @@ class CoreClass {
|
|||||||
|
|
||||||
msgToSend = this.flowClass.find(body, false, flowStandalone) || []
|
msgToSend = this.flowClass.find(body, false, flowStandalone) || []
|
||||||
|
|
||||||
sendFlow(msgToSend, from)
|
for (const ite of msgToSend) {
|
||||||
|
cbEveryCtx(ite?.ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sendFlow(msgToSend, from)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 📄🤘(tiene return) Si el mensaje previo implementa capture
|
// 📄🤘(tiene return) [options: capture (boolean)]: Si se tiene option boolean
|
||||||
if (!endFlowFlag && !prevMsg?.options?.nested?.length) {
|
if (!fallBackFlag && !prevMsg?.options?.nested?.length) {
|
||||||
const typeCapture = typeof prevMsg?.options?.capture
|
const typeCapture = typeof prevMsg?.options?.capture
|
||||||
|
const valueCapture = prevMsg?.options?.capture
|
||||||
|
|
||||||
if (typeCapture === 'boolean' && fallBackFlag) {
|
if (['string', 'boolean'].includes(typeCapture) && valueCapture) {
|
||||||
msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
|
msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
|
||||||
sendFlow(msgToSend, from)
|
this.sendFlow(msgToSend, from)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msgToSend = this.flowClass.find(body) || []
|
msgToSend = this.flowClass.find(body) || []
|
||||||
sendFlow(msgToSend, from)
|
this.sendFlow(msgToSend, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -243,13 +170,25 @@ class CoreClass {
|
|||||||
*/
|
*/
|
||||||
sendProviderAndSave = (numberOrId, ctxMessage) => {
|
sendProviderAndSave = (numberOrId, ctxMessage) => {
|
||||||
const { answer } = ctxMessage
|
const { answer } = ctxMessage
|
||||||
return this.providerClass
|
return Promise.all([
|
||||||
.sendMessage(numberOrId, answer, ctxMessage)
|
this.providerClass.sendMessage(numberOrId, answer, ctxMessage),
|
||||||
.then(() => this.databaseClass.save({ ...ctxMessage, from: numberOrId }))
|
this.databaseClass.save({ ...ctxMessage, from: numberOrId }),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
sendFlow = async (messageToSend, numberOrId) => {
|
||||||
|
const queue = []
|
||||||
|
for (const ctxMessage of messageToSend) {
|
||||||
|
const delayMs = ctxMessage?.options?.delay || 0
|
||||||
|
if (delayMs) await delay(delayMs)
|
||||||
|
Queue.enqueue(() =>
|
||||||
|
this.sendProviderAndSave(numberOrId, ctxMessage)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return Promise.all(queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
|
||||||
* @private
|
* @private
|
||||||
* @param {*} message
|
* @param {*} message
|
||||||
* @param {*} ref
|
* @param {*} ref
|
||||||
@@ -262,22 +201,5 @@ class CoreClass {
|
|||||||
this.continue(null, responde.ref)
|
this.continue(null, responde.ref)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Funcion dedicada a enviar el mensaje sin pasar por el flow
|
|
||||||
* (dialogflow)
|
|
||||||
* @param {*} messageToSend
|
|
||||||
* @param {*} numberOrId
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
sendFlowSimple = async (messageToSend, numberOrId) => {
|
|
||||||
const queue = []
|
|
||||||
for (const ctxMessage of messageToSend) {
|
|
||||||
const delayMs = ctxMessage?.options?.delay || 0
|
|
||||||
if (delayMs) await delay(delayMs)
|
|
||||||
QueuePrincipal.enqueue(() => this.sendProviderAndSave(numberOrId, ctxMessage))
|
|
||||||
}
|
|
||||||
return Promise.all(queue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
module.exports = CoreClass
|
module.exports = CoreClass
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ const { addKeyword, addAnswer, addChild, toSerialize } = require('./io/methods')
|
|||||||
* @param {*} args
|
* @param {*} args
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const createBot = async ({ flow, database, provider }, args = {}) => new CoreClass(flow, database, provider, args)
|
const createBot = async ({ flow, database, provider }) =>
|
||||||
|
new CoreClass(flow, database, provider)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crear instancia de clase Io (Flow)
|
* Crear instancia de clase Io (Flow)
|
||||||
@@ -28,7 +29,8 @@ const createFlow = (args) => {
|
|||||||
*/
|
*/
|
||||||
const createProvider = (providerClass = class {}, args = null) => {
|
const createProvider = (providerClass = class {}, args = null) => {
|
||||||
const providerInstance = new providerClass(args)
|
const providerInstance = new providerClass(args)
|
||||||
if (!providerClass.prototype instanceof ProviderClass) throw new Error('El provider no implementa ProviderClass')
|
if (!providerClass.prototype instanceof ProviderClass)
|
||||||
|
throw new Error('El provider no implementa ProviderClass')
|
||||||
return providerInstance
|
return providerInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,17 +25,9 @@ class FlowClass {
|
|||||||
let refSymbol = null
|
let refSymbol = null
|
||||||
overFlow = overFlow ?? this.flowSerialize
|
overFlow = overFlow ?? this.flowSerialize
|
||||||
|
|
||||||
const customRegex = (str = null) => {
|
|
||||||
if (typeof str !== 'string') return
|
|
||||||
const instanceRegex = new RegExp(str)
|
|
||||||
return instanceRegex.test(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retornar expresion regular para buscar coincidencia */
|
/** Retornar expresion regular para buscar coincidencia */
|
||||||
const mapSensitive = (str, mapOptions = { sensitive: false, regex: false }) => {
|
const mapSensitive = (str, flag = false) => {
|
||||||
if (mapOptions.regex) return customRegex(str)
|
const regexSensitive = flag ? 'g' : 'i'
|
||||||
|
|
||||||
const regexSensitive = mapOptions.sensitive ? 'g' : 'i'
|
|
||||||
if (Array.isArray(str)) {
|
if (Array.isArray(str)) {
|
||||||
return new RegExp(str.join('|'), regexSensitive)
|
return new RegExp(str.join('|'), regexSensitive)
|
||||||
}
|
}
|
||||||
@@ -44,7 +36,6 @@ class FlowClass {
|
|||||||
|
|
||||||
const findIn = (keyOrWord, symbol = false, flow = overFlow) => {
|
const findIn = (keyOrWord, symbol = false, flow = overFlow) => {
|
||||||
const sensitive = refSymbol?.options?.sensitive || false
|
const sensitive = refSymbol?.options?.sensitive || false
|
||||||
const regex = refSymbol?.options?.regex || false
|
|
||||||
capture = refSymbol?.options?.capture || false
|
capture = refSymbol?.options?.capture || false
|
||||||
|
|
||||||
if (capture) return messages
|
if (capture) return messages
|
||||||
@@ -55,7 +46,7 @@ class FlowClass {
|
|||||||
if (refSymbol?.ref) findIn(refSymbol.ref, true)
|
if (refSymbol?.ref) findIn(refSymbol.ref, true)
|
||||||
} else {
|
} else {
|
||||||
refSymbol = flow.find((c) => {
|
refSymbol = flow.find((c) => {
|
||||||
return mapSensitive(c.keyword, { sensitive, regex }).test(keyOrWord)
|
return mapSensitive(c.keyword, sensitive).test(keyOrWord)
|
||||||
})
|
})
|
||||||
if (refSymbol?.ref) findIn(refSymbol.ref, true)
|
if (refSymbol?.ref) findIn(refSymbol.ref, true)
|
||||||
return messages
|
return messages
|
||||||
@@ -65,7 +56,8 @@ class FlowClass {
|
|||||||
return messages
|
return messages
|
||||||
}
|
}
|
||||||
|
|
||||||
findBySerialize = (refSerialize) => this.flowSerialize.find((r) => r.refSerialize === refSerialize)
|
findBySerialize = (refSerialize) =>
|
||||||
|
this.flowSerialize.find((r) => r.refSerialize === refSerialize)
|
||||||
|
|
||||||
findIndexByRef = (ref) => this.flowSerialize.findIndex((r) => r.ref === ref)
|
findIndexByRef = (ref) => this.flowSerialize.findIndex((r) => r.ref === ref)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,15 @@ const addAnswer =
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const getAnswerOptions = () => ({
|
const getAnswerOptions = () => ({
|
||||||
media: typeof options?.media === 'string' ? `${options?.media}` : null,
|
media:
|
||||||
|
typeof options?.media === 'string' ? `${options?.media}` : null,
|
||||||
buttons: Array.isArray(options?.buttons) ? options.buttons : [],
|
buttons: Array.isArray(options?.buttons) ? options.buttons : [],
|
||||||
capture: typeof options?.capture === 'boolean' ? options?.capture : false,
|
capture:
|
||||||
child: typeof options?.child === 'string' ? `${options?.child}` : null,
|
typeof options?.capture === 'boolean'
|
||||||
|
? options?.capture
|
||||||
|
: false,
|
||||||
|
child:
|
||||||
|
typeof options?.child === 'string' ? `${options?.child}` : null,
|
||||||
delay: typeof options?.delay === 'number' ? options?.delay : 0,
|
delay: typeof options?.delay === 'number' ? options?.delay : 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -44,7 +49,8 @@ const addAnswer =
|
|||||||
* Esta funcion aplana y busca los callback anidados de los hijos
|
* Esta funcion aplana y busca los callback anidados de los hijos
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const getCbFromNested = () => flatObject(Array.isArray(nested) ? nested : [nested])
|
const getCbFromNested = () =>
|
||||||
|
flatObject(Array.isArray(nested) ? nested : [nested])
|
||||||
|
|
||||||
const callback = typeof cb === 'function' ? cb : () => null
|
const callback = typeof cb === 'function' ? cb : () => null
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,12 @@ const { toJson } = require('./toJson')
|
|||||||
* @param {*} options {sensitive:boolean} default false
|
* @param {*} options {sensitive:boolean} default false
|
||||||
*/
|
*/
|
||||||
const addKeyword = (keyword, options) => {
|
const addKeyword = (keyword, options) => {
|
||||||
if (typeof keyword !== 'string' && !Array.isArray(keyword)) {
|
|
||||||
throw new Error('DEBE_SER_STRING_ARRAY_REGEX')
|
|
||||||
}
|
|
||||||
|
|
||||||
const parseOptions = () => {
|
const parseOptions = () => {
|
||||||
const defaultProperties = {
|
const defaultProperties = {
|
||||||
sensitive: typeof options?.sensitive === 'boolean' ? options?.sensitive : false,
|
sensitive:
|
||||||
regex: typeof options?.regex === 'boolean' ? options?.regex : false,
|
typeof options?.sensitive === 'boolean'
|
||||||
|
? options?.sensitive
|
||||||
|
: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultProperties
|
return defaultProperties
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ const { generateRef, generateRefSerialize } = require('../../utils/hash')
|
|||||||
* @param options {media:string, buttons:[], capture:true default false}
|
* @param options {media:string, buttons:[], capture:true default false}
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const toCtx = ({ body, from, prevRef, options = {}, index }) => {
|
const toCtx = ({ body, from, prevRef, index }) => {
|
||||||
return {
|
return {
|
||||||
ref: generateRef(),
|
ref: generateRef(),
|
||||||
keyword: prevRef,
|
keyword: prevRef,
|
||||||
answer: body,
|
answer: body,
|
||||||
options: options ?? {},
|
options: {},
|
||||||
from,
|
from,
|
||||||
refSerialize: generateRefSerialize({ index, answer: body }),
|
refSerialize: generateRefSerialize({ index, answer: body }),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@bot-whatsapp/bot",
|
"name": "@bot-whatsapp/bot",
|
||||||
"version": "0.0.96-alpha.0",
|
"version": "0.0.41-alpha.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "./lib/bundle.bot.cjs",
|
"main": "./lib/bundle.bot.cjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -28,9 +28,5 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^16.0.3"
|
"dotenv": "^16.0.3"
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/bot"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ class ProviderClass extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
sendMessage = async (userId, message) => {
|
sendMessage = async (userId, message) => {
|
||||||
if (NODE_ENV !== 'production') console.log('[sendMessage]', { userId, message })
|
if (NODE_ENV !== 'production')
|
||||||
|
console.log('[sendMessage]', { userId, message })
|
||||||
return message
|
return message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ module.exports = [
|
|||||||
banner: banner['banner.output'].join(''),
|
banner: banner['banner.output'].join(''),
|
||||||
file: join(__dirname, 'lib', 'bundle.bot.cjs'),
|
file: join(__dirname, 'lib', 'bundle.bot.cjs'),
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
sourcemap: true,
|
|
||||||
},
|
},
|
||||||
plugins: [commonjs(), nodeResolve()],
|
plugins: [commonjs(), nodeResolve()],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ const { test } = require('uvu')
|
|||||||
const assert = require('uvu/assert')
|
const assert = require('uvu/assert')
|
||||||
const FlowClass = require('../io/flow.class')
|
const FlowClass = require('../io/flow.class')
|
||||||
const MockProvider = require('../../../__mocks__/mock.provider')
|
const MockProvider = require('../../../__mocks__/mock.provider')
|
||||||
const { createBot, CoreClass, createFlow, createProvider, ProviderClass } = require('../index')
|
const {
|
||||||
|
createBot,
|
||||||
|
CoreClass,
|
||||||
|
createFlow,
|
||||||
|
createProvider,
|
||||||
|
ProviderClass,
|
||||||
|
} = require('../index')
|
||||||
|
|
||||||
class MockFlow {
|
class MockFlow {
|
||||||
allCallbacks = { ref: () => 1 }
|
allCallbacks = { ref: () => 1 }
|
||||||
@@ -94,13 +100,20 @@ test(`[Bot] Eventos 'require_action,ready,auth_failure,message '`, async () => {
|
|||||||
await createBot(setting)
|
await createBot(setting)
|
||||||
|
|
||||||
/// Escuchamos eventos
|
/// Escuchamos eventos
|
||||||
mockProvider.on('require_action', (r) => (responseEvents['require_action'] = r))
|
mockProvider.on(
|
||||||
|
'require_action',
|
||||||
|
(r) => (responseEvents['require_action'] = r)
|
||||||
|
)
|
||||||
mockProvider.on('ready', (r) => (responseEvents['ready'] = r))
|
mockProvider.on('ready', (r) => (responseEvents['ready'] = r))
|
||||||
mockProvider.on('auth_failure', (r) => (responseEvents['auth_failure'] = r))
|
mockProvider.on('auth_failure', (r) => (responseEvents['auth_failure'] = r))
|
||||||
mockProvider.on('message', (r) => (responseEvents['message'] = r))
|
mockProvider.on('message', (r) => (responseEvents['message'] = r))
|
||||||
|
|
||||||
/// Emitimos eventos
|
/// Emitimos eventos
|
||||||
mockProvider.delaySendMessage(0, 'require_action', MOCK_EVENTS.require_action)
|
mockProvider.delaySendMessage(
|
||||||
|
0,
|
||||||
|
'require_action',
|
||||||
|
MOCK_EVENTS.require_action
|
||||||
|
)
|
||||||
mockProvider.delaySendMessage(0, 'ready', MOCK_EVENTS.ready)
|
mockProvider.delaySendMessage(0, 'ready', MOCK_EVENTS.ready)
|
||||||
mockProvider.delaySendMessage(0, 'auth_failure', MOCK_EVENTS.auth_failure)
|
mockProvider.delaySendMessage(0, 'auth_failure', MOCK_EVENTS.auth_failure)
|
||||||
mockProvider.delaySendMessage(0, 'message', MOCK_EVENTS.message)
|
mockProvider.delaySendMessage(0, 'message', MOCK_EVENTS.message)
|
||||||
@@ -108,12 +121,21 @@ test(`[Bot] Eventos 'require_action,ready,auth_failure,message '`, async () => {
|
|||||||
await delay(0)
|
await delay(0)
|
||||||
|
|
||||||
/// Testeamos eventos
|
/// Testeamos eventos
|
||||||
assert.is(JSON.stringify(responseEvents.require_action), JSON.stringify(MOCK_EVENTS.require_action))
|
assert.is(
|
||||||
|
JSON.stringify(responseEvents.require_action),
|
||||||
|
JSON.stringify(MOCK_EVENTS.require_action)
|
||||||
|
)
|
||||||
assert.is(responseEvents.ready, MOCK_EVENTS.ready)
|
assert.is(responseEvents.ready, MOCK_EVENTS.ready)
|
||||||
|
|
||||||
assert.is(JSON.stringify(responseEvents.auth_failure), JSON.stringify(MOCK_EVENTS.auth_failure))
|
assert.is(
|
||||||
|
JSON.stringify(responseEvents.auth_failure),
|
||||||
|
JSON.stringify(MOCK_EVENTS.auth_failure)
|
||||||
|
)
|
||||||
|
|
||||||
assert.is(JSON.stringify(responseEvents.message), JSON.stringify(MOCK_EVENTS.message))
|
assert.is(
|
||||||
|
JSON.stringify(responseEvents.message),
|
||||||
|
JSON.stringify(MOCK_EVENTS.message)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test(`[Bot] Probando Flujos Internos`, async () => {
|
test(`[Bot] Probando Flujos Internos`, async () => {
|
||||||
@@ -144,13 +166,20 @@ test(`[Bot] Probando Flujos Internos`, async () => {
|
|||||||
await createBot(setting)
|
await createBot(setting)
|
||||||
|
|
||||||
/// Escuchamos eventos
|
/// Escuchamos eventos
|
||||||
mockProvider.on('require_action', (r) => (responseEvents['require_action'] = r))
|
mockProvider.on(
|
||||||
|
'require_action',
|
||||||
|
(r) => (responseEvents['require_action'] = r)
|
||||||
|
)
|
||||||
mockProvider.on('ready', (r) => (responseEvents['ready'] = r))
|
mockProvider.on('ready', (r) => (responseEvents['ready'] = r))
|
||||||
mockProvider.on('auth_failure', (r) => (responseEvents['auth_failure'] = r))
|
mockProvider.on('auth_failure', (r) => (responseEvents['auth_failure'] = r))
|
||||||
mockProvider.on('message', (r) => (responseEvents['message'] = r))
|
mockProvider.on('message', (r) => (responseEvents['message'] = r))
|
||||||
|
|
||||||
/// Emitimos eventos
|
/// Emitimos eventos
|
||||||
mockProvider.delaySendMessage(0, 'require_action', MOCK_EVENTS.require_action)
|
mockProvider.delaySendMessage(
|
||||||
|
0,
|
||||||
|
'require_action',
|
||||||
|
MOCK_EVENTS.require_action
|
||||||
|
)
|
||||||
mockProvider.delaySendMessage(0, 'ready', MOCK_EVENTS.ready)
|
mockProvider.delaySendMessage(0, 'ready', MOCK_EVENTS.ready)
|
||||||
mockProvider.delaySendMessage(0, 'auth_failure', MOCK_EVENTS.auth_failure)
|
mockProvider.delaySendMessage(0, 'auth_failure', MOCK_EVENTS.auth_failure)
|
||||||
mockProvider.delaySendMessage(0, 'message', MOCK_EVENTS.message)
|
mockProvider.delaySendMessage(0, 'message', MOCK_EVENTS.message)
|
||||||
@@ -158,12 +187,21 @@ test(`[Bot] Probando Flujos Internos`, async () => {
|
|||||||
await delay(0)
|
await delay(0)
|
||||||
|
|
||||||
/// Testeamos eventos
|
/// Testeamos eventos
|
||||||
assert.is(JSON.stringify(responseEvents.require_action), JSON.stringify(MOCK_EVENTS.require_action))
|
assert.is(
|
||||||
|
JSON.stringify(responseEvents.require_action),
|
||||||
|
JSON.stringify(MOCK_EVENTS.require_action)
|
||||||
|
)
|
||||||
assert.is(responseEvents.ready, MOCK_EVENTS.ready)
|
assert.is(responseEvents.ready, MOCK_EVENTS.ready)
|
||||||
|
|
||||||
assert.is(JSON.stringify(responseEvents.auth_failure), JSON.stringify(MOCK_EVENTS.auth_failure))
|
assert.is(
|
||||||
|
JSON.stringify(responseEvents.auth_failure),
|
||||||
|
JSON.stringify(MOCK_EVENTS.auth_failure)
|
||||||
|
)
|
||||||
|
|
||||||
assert.is(JSON.stringify(responseEvents.message), JSON.stringify(MOCK_EVENTS.message))
|
assert.is(
|
||||||
|
JSON.stringify(responseEvents.message),
|
||||||
|
JSON.stringify(MOCK_EVENTS.message)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test(`[Bot] Probando Flujos Nested`, async () => {
|
test(`[Bot] Probando Flujos Nested`, async () => {
|
||||||
@@ -196,13 +234,20 @@ test(`[Bot] Probando Flujos Nested`, async () => {
|
|||||||
botInstance.sendProviderAndSave('xxxxx', 'xxxxx')
|
botInstance.sendProviderAndSave('xxxxx', 'xxxxx')
|
||||||
botInstance.continue('xxxxx', 'xxxxx')
|
botInstance.continue('xxxxx', 'xxxxx')
|
||||||
/// Escuchamos eventos
|
/// Escuchamos eventos
|
||||||
mockProvider.on('require_action', (r) => (responseEvents['require_action'] = r))
|
mockProvider.on(
|
||||||
|
'require_action',
|
||||||
|
(r) => (responseEvents['require_action'] = r)
|
||||||
|
)
|
||||||
mockProvider.on('ready', (r) => (responseEvents['ready'] = r))
|
mockProvider.on('ready', (r) => (responseEvents['ready'] = r))
|
||||||
mockProvider.on('auth_failure', (r) => (responseEvents['auth_failure'] = r))
|
mockProvider.on('auth_failure', (r) => (responseEvents['auth_failure'] = r))
|
||||||
mockProvider.on('message', (r) => (responseEvents['message'] = r))
|
mockProvider.on('message', (r) => (responseEvents['message'] = r))
|
||||||
|
|
||||||
/// Emitimos eventos
|
/// Emitimos eventos
|
||||||
mockProvider.delaySendMessage(0, 'require_action', MOCK_EVENTS.require_action)
|
mockProvider.delaySendMessage(
|
||||||
|
0,
|
||||||
|
'require_action',
|
||||||
|
MOCK_EVENTS.require_action
|
||||||
|
)
|
||||||
mockProvider.delaySendMessage(0, 'ready', MOCK_EVENTS.ready)
|
mockProvider.delaySendMessage(0, 'ready', MOCK_EVENTS.ready)
|
||||||
mockProvider.delaySendMessage(0, 'auth_failure', MOCK_EVENTS.auth_failure)
|
mockProvider.delaySendMessage(0, 'auth_failure', MOCK_EVENTS.auth_failure)
|
||||||
mockProvider.delaySendMessage(0, 'message', MOCK_EVENTS.message)
|
mockProvider.delaySendMessage(0, 'message', MOCK_EVENTS.message)
|
||||||
@@ -210,12 +255,21 @@ test(`[Bot] Probando Flujos Nested`, async () => {
|
|||||||
await delay(0)
|
await delay(0)
|
||||||
|
|
||||||
/// Testeamos eventos
|
/// Testeamos eventos
|
||||||
assert.is(JSON.stringify(responseEvents.require_action), JSON.stringify(MOCK_EVENTS.require_action))
|
assert.is(
|
||||||
|
JSON.stringify(responseEvents.require_action),
|
||||||
|
JSON.stringify(MOCK_EVENTS.require_action)
|
||||||
|
)
|
||||||
assert.is(responseEvents.ready, MOCK_EVENTS.ready)
|
assert.is(responseEvents.ready, MOCK_EVENTS.ready)
|
||||||
|
|
||||||
assert.is(JSON.stringify(responseEvents.auth_failure), JSON.stringify(MOCK_EVENTS.auth_failure))
|
assert.is(
|
||||||
|
JSON.stringify(responseEvents.auth_failure),
|
||||||
|
JSON.stringify(MOCK_EVENTS.auth_failure)
|
||||||
|
)
|
||||||
|
|
||||||
assert.is(JSON.stringify(responseEvents.message), JSON.stringify(MOCK_EVENTS.message))
|
assert.is(
|
||||||
|
JSON.stringify(responseEvents.message),
|
||||||
|
JSON.stringify(MOCK_EVENTS.message)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test.run()
|
test.run()
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
const { test } = require('uvu')
|
|
||||||
const assert = require('uvu/assert')
|
|
||||||
const FlowClass = require('../io/flow.class')
|
|
||||||
const { addKeyword } = require('../index')
|
|
||||||
|
|
||||||
test(`[FlowClass] Probando instanciamiento de clase`, async () => {
|
|
||||||
const MOCK_FLOW = addKeyword('hola').addAnswer('Buenas!')
|
|
||||||
const flowClass = new FlowClass([MOCK_FLOW])
|
|
||||||
assert.is(flowClass instanceof FlowClass, true)
|
|
||||||
})
|
|
||||||
|
|
||||||
test(`[FlowClass] Probando find`, async () => {
|
|
||||||
const MOCK_FLOW = addKeyword('hola').addAnswer('Buenas!')
|
|
||||||
const flowClass = new FlowClass([MOCK_FLOW])
|
|
||||||
|
|
||||||
flowClass.find('hola')
|
|
||||||
assert.is(flowClass instanceof FlowClass, true)
|
|
||||||
})
|
|
||||||
|
|
||||||
test(`[FlowClass] Probando findBySerialize`, async () => {
|
|
||||||
const MOCK_FLOW = addKeyword('hola').addAnswer('Buenas!')
|
|
||||||
const flowClass = new FlowClass([MOCK_FLOW])
|
|
||||||
|
|
||||||
flowClass.findBySerialize('')
|
|
||||||
assert.is(flowClass instanceof FlowClass, true)
|
|
||||||
})
|
|
||||||
|
|
||||||
test.run()
|
|
||||||
@@ -35,7 +35,10 @@ test('Debere probar toSerialize', () => {
|
|||||||
const ARRANGE = {
|
const ARRANGE = {
|
||||||
keyword: ['hola!', 'ole'],
|
keyword: ['hola!', 'ole'],
|
||||||
}
|
}
|
||||||
const MAIN_CTX = addKeyword(ARRANGE.keyword).addAnswer('Segundo!').addAnswer('Segundo!').toJson()
|
const MAIN_CTX = addKeyword(ARRANGE.keyword)
|
||||||
|
.addAnswer('Segundo!')
|
||||||
|
.addAnswer('Segundo!')
|
||||||
|
.toJson()
|
||||||
|
|
||||||
const [ANSWER_A] = MAIN_CTX
|
const [ANSWER_A] = MAIN_CTX
|
||||||
|
|
||||||
@@ -68,7 +71,9 @@ test('Debere probar la anidación', () => {
|
|||||||
answer_A: 'Bienvenido',
|
answer_A: 'Bienvenido',
|
||||||
answer_B: 'Continuar',
|
answer_B: 'Continuar',
|
||||||
}
|
}
|
||||||
const MAIN_CTX = addKeyword(ARRANGE.keyword).addAnswer(ARRANGE.answer_A).addAnswer(ARRANGE.answer_B)
|
const MAIN_CTX = addKeyword(ARRANGE.keyword)
|
||||||
|
.addAnswer(ARRANGE.answer_A)
|
||||||
|
.addAnswer(ARRANGE.answer_B)
|
||||||
|
|
||||||
assert.is(MAIN_CTX.ctx.answer, ARRANGE.answer_B)
|
assert.is(MAIN_CTX.ctx.answer, ARRANGE.answer_B)
|
||||||
})
|
})
|
||||||
@@ -102,7 +107,10 @@ test('Debere probar error las addAnswer', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('Obtener toJson', () => {
|
test('Obtener toJson', () => {
|
||||||
const [ctxA, ctxB, ctxC] = addKeyword('hola').addAnswer('pera!').addAnswer('chao').toJson()
|
const [ctxA, ctxB, ctxC] = addKeyword('hola')
|
||||||
|
.addAnswer('pera!')
|
||||||
|
.addAnswer('chao')
|
||||||
|
.toJson()
|
||||||
|
|
||||||
assert.is(ctxA.keyword, 'hola')
|
assert.is(ctxA.keyword, 'hola')
|
||||||
assert.match(ctxA.ref, /^key_/)
|
assert.match(ctxA.ref, /^key_/)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
const delay = (miliseconds) => new Promise((res) => setTimeout(res, miliseconds))
|
const delay = (miliseconds) =>
|
||||||
|
new Promise((res) => setTimeout(res, miliseconds))
|
||||||
|
|
||||||
module.exports = { delay }
|
module.exports = { delay }
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ const flatObject = (listArray = []) => {
|
|||||||
|
|
||||||
if (!listArray.length) return {}
|
if (!listArray.length) return {}
|
||||||
|
|
||||||
const cbNestedObj = cbNestedList.map(({ ctx }) => ctx?.callbacks).filter((i) => !!i)
|
const cbNestedObj = cbNestedList
|
||||||
|
.map(({ ctx }) => ctx?.callbacks)
|
||||||
|
.filter((i) => !!i)
|
||||||
const queueCb = cbNestedObj.reduce((acc, current) => {
|
const queueCb = cbNestedObj.reduce((acc, current) => {
|
||||||
const getKeys = Object.keys(current)
|
const getKeys = Object.keys(current)
|
||||||
const parse = getKeys.map((icb, i) => ({
|
const parse = getKeys.map((icb, i) => ({
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ const generateRef = (prefix = false) => {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const generateRefSerialize = ({ index, answer, keyword }) =>
|
const generateRefSerialize = ({ index, answer, keyword }) =>
|
||||||
crypto.createHash('md5').update(JSON.stringify({ index, answer, keyword })).digest('hex')
|
crypto
|
||||||
|
.createHash('md5')
|
||||||
|
.update(JSON.stringify({ index, answer, keyword }))
|
||||||
|
.digest('hex')
|
||||||
|
|
||||||
module.exports = { generateRef, generateRefSerialize }
|
module.exports = { generateRef, generateRefSerialize }
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ const printer = (message, title) => {
|
|||||||
if (NODE_ENV !== 'test') {
|
if (NODE_ENV !== 'test') {
|
||||||
// console.clear()
|
// console.clear()
|
||||||
if (title) console.log(bgRed(`${title}`))
|
if (title) console.log(bgRed(`${title}`))
|
||||||
console.log(yellow(Array.isArray(message) ? message.join('\n') : message))
|
console.log(
|
||||||
|
yellow(Array.isArray(message) ? message.join('\n') : message)
|
||||||
|
)
|
||||||
console.log(``)
|
console.log(``)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
class Queue {
|
class Queue {
|
||||||
queue = []
|
static queue = []
|
||||||
pendingPromise = false
|
static pendingPromise = false
|
||||||
|
|
||||||
enqueue(promise) {
|
static enqueue(promise) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.queue.push({
|
this.queue.push({
|
||||||
promise,
|
promise,
|
||||||
@@ -13,7 +13,7 @@ class Queue {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
dequeue() {
|
static dequeue() {
|
||||||
if (this.workingOnPromise) {
|
if (this.workingOnPromise) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,59 +1,38 @@
|
|||||||
const { red, yellow, green, bgCyan } = require('kleur')
|
const { red, yellow, green, bgCyan } = require('kleur')
|
||||||
const { exec } = require('node:child_process')
|
|
||||||
|
|
||||||
const checkNodeVersion = () => {
|
const checkNodeVersion = () => {
|
||||||
return new Promise((resolve, reject) => {
|
console.log(bgCyan('🚀 Revisando tu Node.js'))
|
||||||
console.log(bgCyan('🚀 Revisando tu Node.js'))
|
const version = process.version
|
||||||
const version = process.version
|
const majorVersion = parseInt(version.replace('v', '').split('.').shift())
|
||||||
const majorVersion = parseInt(version.replace('v', '').split('.').shift())
|
if (majorVersion < 16) {
|
||||||
if (majorVersion < 16) {
|
console.error(
|
||||||
console.error(red(`🔴 Se require Node.js 16 o superior. Actualmente esta ejecutando Node.js ${version}`))
|
red(
|
||||||
console.log(``)
|
`🔴 Se require Node.js 16 o superior. Actualmente esta ejecutando Node.js ${version}`
|
||||||
reject('ERROR_NODE')
|
)
|
||||||
}
|
)
|
||||||
console.log(green(`Node.js: ${version} compatible ✅`))
|
process.exit(1)
|
||||||
console.log(``)
|
}
|
||||||
resolve()
|
console.log(green(`Node.js compatible ${version}`))
|
||||||
})
|
console.log(``)
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkOs = () => {
|
const checkOs = () => {
|
||||||
return new Promise((resolve) => {
|
console.log(bgCyan('🙂 Revisando tu sistema operativo'))
|
||||||
console.log(bgCyan('🙂 Revisando tu sistema operativo'))
|
const os = process.platform
|
||||||
const os = process.platform
|
if (!os.includes('win32')) {
|
||||||
if (!os.includes('win32')) {
|
const messages = [
|
||||||
const messages = [
|
`El sistema operativo actual (${os}) posiblemente requiera`,
|
||||||
`El sistema operativo actual (${os}) posiblemente requiera`,
|
`una configuración adicional referente al puppeteer`,
|
||||||
`una configuración adicional referente al puppeteer`,
|
``,
|
||||||
``,
|
`Recuerda pasar por el WIKI`,
|
||||||
`Recuerda pasar por el WIKI`,
|
`🔗 https://github.com/leifermendez/bot-whatsapp/wiki/Instalación`,
|
||||||
`🔗 https://github.com/leifermendez/bot-whatsapp/wiki/Instalación`,
|
``,
|
||||||
``,
|
]
|
||||||
]
|
|
||||||
|
|
||||||
console.log(yellow(messages.join(' \n')))
|
console.log(yellow(messages.join(' \n')))
|
||||||
}
|
}
|
||||||
console.log(green(`OS: compatible ✅`))
|
|
||||||
console.log(``)
|
console.log(``)
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkGit = () => {
|
module.exports = { checkNodeVersion, checkOs }
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
console.log(bgCyan('🤓 Revisando GIT'))
|
|
||||||
exec('git --version', (error) => {
|
|
||||||
if (error) {
|
|
||||||
console.error(red(`🔴 Se require instalar GIT`))
|
|
||||||
console.log(``)
|
|
||||||
reject('ERROR_GIT')
|
|
||||||
} else {
|
|
||||||
console.log(green(`Git: Compatible ✅`))
|
|
||||||
console.log(``)
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { checkNodeVersion, checkOs, checkGit }
|
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ const rimraf = require('rimraf')
|
|||||||
const { yellow } = require('kleur')
|
const { yellow } = require('kleur')
|
||||||
const { join } = require('path')
|
const { join } = require('path')
|
||||||
|
|
||||||
const PATH_WW = [join(process.cwd(), '.wwebjs_auth'), join(process.cwd(), 'session.json')]
|
const PATH_WW = [
|
||||||
|
join(process.cwd(), '.wwebjs_auth'),
|
||||||
|
join(process.cwd(), 'session.json'),
|
||||||
|
]
|
||||||
|
|
||||||
const cleanSession = () => {
|
const cleanSession = () => {
|
||||||
const queue = []
|
const queue = []
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ const JSON_TEMPLATE = {
|
|||||||
const PATH_CONFIG = join(process.cwd(), 'config.json')
|
const PATH_CONFIG = join(process.cwd(), 'config.json')
|
||||||
|
|
||||||
const jsonConfig = () => {
|
const jsonConfig = () => {
|
||||||
return writeFile(PATH_CONFIG, JSON.stringify(JSON_TEMPLATE, null, 2), 'utf-8')
|
return writeFile(
|
||||||
|
PATH_CONFIG,
|
||||||
|
JSON.stringify(JSON_TEMPLATE, null, 2),
|
||||||
|
'utf-8'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { jsonConfig }
|
module.exports = { jsonConfig }
|
||||||
|
|||||||
@@ -20,9 +20,13 @@ const installDeps = (pkgManager, packageList) => {
|
|||||||
const installSingle = (pkgInstall) => () => {
|
const installSingle = (pkgInstall) => () => {
|
||||||
new Promise((resolve) => {
|
new Promise((resolve) => {
|
||||||
try {
|
try {
|
||||||
childProcess = spawn(pkgManager, [PKG_OPTION[pkgManager], pkgInstall], {
|
childProcess = spawn(
|
||||||
stdio: 'inherit',
|
pkgManager,
|
||||||
})
|
[PKG_OPTION[pkgManager], pkgInstall],
|
||||||
|
{
|
||||||
|
stdio: 'inherit',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
childProcess.on('error', (e) => {
|
childProcess.on('error', (e) => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
const prompts = require('prompts')
|
const prompts = require('prompts')
|
||||||
const { join } = require('path')
|
const { join } = require('path')
|
||||||
const { yellow, red, cyan, bgMagenta, bgRed } = require('kleur')
|
const { yellow, red, cyan, bgMagenta } = require('kleur')
|
||||||
const { existsSync } = require('fs')
|
const { existsSync } = require('fs')
|
||||||
const { copyBaseApp } = require('../create-app')
|
const { copyBaseApp } = require('../create-app')
|
||||||
const { checkNodeVersion, checkOs, checkGit } = require('../check')
|
const { checkNodeVersion, checkOs } = require('../check')
|
||||||
|
|
||||||
const bannerDone = () => {
|
const bannerDone = () => {
|
||||||
console.log(``)
|
console.log(``)
|
||||||
@@ -21,20 +21,6 @@ const bannerDone = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const startInteractive = async () => {
|
const startInteractive = async () => {
|
||||||
try {
|
|
||||||
console.clear()
|
|
||||||
await checkNodeVersion()
|
|
||||||
checkOs()
|
|
||||||
await checkGit()
|
|
||||||
console.clear()
|
|
||||||
await nextSteps()
|
|
||||||
} catch (e) {
|
|
||||||
console.error(bgRed(`Ups! 🙄 algo no va bien.`))
|
|
||||||
console.error(bgRed(`Revisa los requerimientos minimos en la documentacion`))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextSteps = async () => {
|
|
||||||
const questions = [
|
const questions = [
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
@@ -46,11 +32,11 @@ const nextSteps = async () => {
|
|||||||
name: 'providerWs',
|
name: 'providerWs',
|
||||||
message: '¿Cuál proveedor de whatsapp quieres utilizar?',
|
message: '¿Cuál proveedor de whatsapp quieres utilizar?',
|
||||||
choices: [
|
choices: [
|
||||||
{ title: 'Baileys (gratis)', value: 'baileys' },
|
|
||||||
{ title: 'Venom (gratis)', value: 'venom' },
|
|
||||||
{ title: 'whatsapp-web.js (gratis)', value: 'wweb' },
|
{ title: 'whatsapp-web.js (gratis)', value: 'wweb' },
|
||||||
|
{ title: 'Venom (gratis)', value: 'venom' },
|
||||||
|
{ title: 'Baileys (gratis)', value: 'baileys' },
|
||||||
{ title: 'Twilio', value: 'twilio' },
|
{ title: 'Twilio', value: 'twilio' },
|
||||||
{ title: 'Meta', value: 'meta' },
|
{ title: 'API Oficial (Meta)', value: 'meta' },
|
||||||
],
|
],
|
||||||
max: 1,
|
max: 1,
|
||||||
hint: 'Espacio para seleccionar',
|
hint: 'Espacio para seleccionar',
|
||||||
@@ -72,6 +58,9 @@ const nextSteps = async () => {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
console.clear()
|
||||||
|
checkNodeVersion()
|
||||||
|
checkOs()
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
console.log('¡Proceso cancelado!')
|
console.log('¡Proceso cancelado!')
|
||||||
return true
|
return true
|
||||||
@@ -80,7 +69,8 @@ const nextSteps = async () => {
|
|||||||
const { outDir = '', providerDb = [], providerWs = [] } = response
|
const { outDir = '', providerDb = [], providerWs = [] } = response
|
||||||
|
|
||||||
const createApp = async (templateName = null) => {
|
const createApp = async (templateName = null) => {
|
||||||
if (!templateName) throw new Error('TEMPLATE_NAME_INVALID: ', templateName)
|
if (!templateName)
|
||||||
|
throw new Error('TEMPLATE_NAME_INVALID: ', templateName)
|
||||||
|
|
||||||
const possiblesPath = [
|
const possiblesPath = [
|
||||||
join(__dirname, '..', '..', 'starters', 'apps', templateName),
|
join(__dirname, '..', '..', 'starters', 'apps', templateName),
|
||||||
@@ -112,7 +102,11 @@ const nextSteps = async () => {
|
|||||||
const vendorProvider = async () => {
|
const vendorProvider = async () => {
|
||||||
const [answer] = providerWs
|
const [answer] = providerWs
|
||||||
if (!providerWs.length) {
|
if (!providerWs.length) {
|
||||||
console.log(red(`Debes seleccionar un proveedor de whatsapp. Tecla [Space] para seleccionar`))
|
console.log(
|
||||||
|
red(
|
||||||
|
`Debes seleccionar un proveedor de whatsapp. Tecla [Space] para seleccionar`
|
||||||
|
)
|
||||||
|
)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
return answer
|
return answer
|
||||||
@@ -125,7 +119,11 @@ const nextSteps = async () => {
|
|||||||
const dbProvider = async () => {
|
const dbProvider = async () => {
|
||||||
const [answer] = providerDb
|
const [answer] = providerDb
|
||||||
if (!providerDb.length) {
|
if (!providerDb.length) {
|
||||||
console.log(red(`Debes seleccionar un proveedor de base de datos. Tecla [Space] para seleccionar`))
|
console.log(
|
||||||
|
red(
|
||||||
|
`Debes seleccionar un proveedor de base de datos. Tecla [Space] para seleccionar`
|
||||||
|
)
|
||||||
|
)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
return answer
|
return answer
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@bot-whatsapp/cli",
|
"name": "@bot-whatsapp/cli",
|
||||||
"version": "0.0.72-alpha.0",
|
"version": "0.0.48-alpha.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -15,9 +15,5 @@
|
|||||||
],
|
],
|
||||||
"bin": {
|
"bin": {
|
||||||
"bot": "./bin/cli.js"
|
"bot": "./bin/cli.js"
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/cli"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@bot-whatsapp/contexts",
|
"name": "@bot-whatsapp/contexts",
|
||||||
"version": "0.0.16-alpha.0",
|
"version": "0.0.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "./lib/bundle.contexts.cjs",
|
"main": "./lib/bundle.contexts.cjs",
|
||||||
"files": [
|
"files": [
|
||||||
@@ -13,9 +13,5 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bot-whatsapp/bot": "*"
|
"@bot-whatsapp/bot": "*"
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/contexts"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ class DialogFlowCXContext extends CoreClass {
|
|||||||
* */
|
* */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.optionsDX.location.length) throw new Error('LOCATION_NO_ENCONTRADO')
|
if (!this.optionsDX.location.length)
|
||||||
if (!this.optionsDX.agentId.length) throw new Error('AGENTID_NO_ENCONTRADO')
|
throw new Error('LOCATION_NO_ENCONTRADO')
|
||||||
|
if (!this.optionsDX.agentId.length)
|
||||||
|
throw new Error('AGENTID_NO_ENCONTRADO')
|
||||||
|
|
||||||
const rawJson = readFileSync(GOOGLE_ACCOUNT_PATH, 'utf-8')
|
const rawJson = readFileSync(GOOGLE_ACCOUNT_PATH, 'utf-8')
|
||||||
const { project_id, private_key, client_email } = JSON.parse(rawJson)
|
const { project_id, private_key, client_email } = JSON.parse(rawJson)
|
||||||
@@ -84,7 +86,9 @@ class DialogFlowCXContext extends CoreClass {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [null]
|
const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [
|
||||||
|
null,
|
||||||
|
]
|
||||||
|
|
||||||
const listMessages = single.queryResult.responseMessages.map((res) => {
|
const listMessages = single.queryResult.responseMessages.map((res) => {
|
||||||
if (res.message == 'text') {
|
if (res.message == 'text') {
|
||||||
@@ -92,11 +96,17 @@ class DialogFlowCXContext extends CoreClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (res.message == 'payload') {
|
if (res.message == 'payload') {
|
||||||
const { media = null, buttons = [], answer = '' } = res.payload.fields
|
const {
|
||||||
const buttonsArray = buttons?.listValue?.values?.map((btnValue) => {
|
media = null,
|
||||||
const { stringValue } = btnValue.structValue.fields.body
|
buttons = [],
|
||||||
return { body: stringValue }
|
answer = '',
|
||||||
})
|
} = res.payload.fields
|
||||||
|
const buttonsArray = buttons?.listValue?.values?.map(
|
||||||
|
(btnValue) => {
|
||||||
|
const { stringValue } = btnValue.structValue.fields.body
|
||||||
|
return { body: stringValue }
|
||||||
|
}
|
||||||
|
)
|
||||||
return {
|
return {
|
||||||
answer: answer?.stringValue,
|
answer: answer?.stringValue,
|
||||||
options: {
|
options: {
|
||||||
@@ -107,7 +117,7 @@ class DialogFlowCXContext extends CoreClass {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.sendFlowSimple(listMessages, from)
|
this.sendFlow(listMessages, from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ const DialogCXFlowClass = require('./dialogflow-cx.class')
|
|||||||
* @param {*} args
|
* @param {*} args
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const createBotDialog = async ({ database, provider }, _options) => new DialogCXFlowClass(database, provider, _options)
|
const createBotDialog = async ({ database, provider }, _options) =>
|
||||||
|
new DialogCXFlowClass(database, provider, _options)
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createBotDialog,
|
createBotDialog,
|
||||||
|
|||||||
@@ -65,7 +65,10 @@ class DialogFlowContext extends CoreClass {
|
|||||||
* para evitar este problema.
|
* para evitar este problema.
|
||||||
* https://github.com/codigoencasa/bot-whatsapp/pull/140
|
* https://github.com/codigoencasa/bot-whatsapp/pull/140
|
||||||
*/
|
*/
|
||||||
const session = this.sessionClient.projectAgentSessionPath(this.projectId, from)
|
const session = this.sessionClient.projectAgentSessionPath(
|
||||||
|
this.projectId,
|
||||||
|
from
|
||||||
|
)
|
||||||
const reqDialog = {
|
const reqDialog = {
|
||||||
session,
|
session,
|
||||||
queryInput: {
|
queryInput: {
|
||||||
@@ -76,11 +79,15 @@ class DialogFlowContext extends CoreClass {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [null]
|
const [single] = (await this.sessionClient.detectIntent(reqDialog)) || [
|
||||||
|
null,
|
||||||
|
]
|
||||||
|
|
||||||
const { queryResult } = single
|
const { queryResult } = single
|
||||||
|
|
||||||
const msgPayload = queryResult?.fulfillmentMessages?.find((a) => a.message === 'payload')
|
const msgPayload = queryResult?.fulfillmentMessages?.find(
|
||||||
|
(a) => a.message === 'payload'
|
||||||
|
)
|
||||||
|
|
||||||
// Revisamos si el dialogFlow tiene multimedia
|
// Revisamos si el dialogFlow tiene multimedia
|
||||||
if (msgPayload && msgPayload?.payload) {
|
if (msgPayload && msgPayload?.payload) {
|
||||||
@@ -90,25 +97,17 @@ class DialogFlowContext extends CoreClass {
|
|||||||
})
|
})
|
||||||
|
|
||||||
customPayload = {
|
customPayload = {
|
||||||
options: {
|
media: fields?.media?.stringValue,
|
||||||
media: fields?.media?.stringValue,
|
buttons: mapButtons,
|
||||||
buttons: mapButtons,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ctxFromDX = {
|
|
||||||
...customPayload,
|
|
||||||
answer: fields?.answer?.stringValue,
|
|
||||||
}
|
|
||||||
this.sendFlowSimple([ctxFromDX], from)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ctxFromDX = {
|
const ctxFromDX = {
|
||||||
|
...customPayload,
|
||||||
answer: queryResult?.fulfillmentText,
|
answer: queryResult?.fulfillmentText,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendFlowSimple([ctxFromDX], from)
|
this.sendFlow([ctxFromDX], from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ const DialogFlowClass = require('./dialogflow.class')
|
|||||||
* @param {*} args
|
* @param {*} args
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const createBotDialog = async ({ database, provider }) => new DialogFlowClass(database, provider)
|
const createBotDialog = async ({ database, provider }) =>
|
||||||
|
new DialogFlowClass(database, provider)
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createBotDialog,
|
createBotDialog,
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ const MockClass = require('./mock.class')
|
|||||||
* @param {*} args
|
* @param {*} args
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const createBotMock = async ({ database, provider }) => new MockClass(database, provider)
|
const createBotMock = async ({ database, provider }) =>
|
||||||
|
new MockClass(database, provider)
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createBotMock,
|
createBotMock,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "create-bot-whatsapp",
|
"name": "create-bot-whatsapp",
|
||||||
"version": "0.0.93-alpha.0",
|
"version": "0.0.59-alpha.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "./lib/bundle.create-bot-whatsapp.cjs",
|
"main": "./lib/bundle.create-bot-whatsapp.cjs",
|
||||||
"files": [
|
"files": [
|
||||||
@@ -11,9 +11,5 @@
|
|||||||
"bin": "./bin/create.js",
|
"bin": "./bin/create.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bot-whatsapp/cli": "*"
|
"@bot-whatsapp/cli": "*"
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/create-bot-whatsapp"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@bot-whatsapp/database",
|
"name": "@bot-whatsapp/database",
|
||||||
"version": "0.0.64-alpha.0",
|
"version": "0.0.40-alpha.0",
|
||||||
"description": "Esto es el conector a mysql, pg, mongo",
|
"description": "Esto es el conector a mysql, pg, mongo",
|
||||||
"main": "./lib/mock/index.cjs",
|
"main": "./lib/mock/index.cjs",
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
@@ -19,9 +19,5 @@
|
|||||||
"./mongo": "./lib/mongo/index.cjs",
|
"./mongo": "./lib/mongo/index.cjs",
|
||||||
"./json": "./lib/json/index.cjs",
|
"./json": "./lib/json/index.cjs",
|
||||||
"./mysql": "./lib/mysql/index.cjs"
|
"./mysql": "./lib/mysql/index.cjs"
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/codigoencasa/bot-whatsapp/tree/main/packages/database"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,7 @@ class MockDatabase {
|
|||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
getPrevByNumber = (from) => {
|
getPrevByNumber = (from) => {
|
||||||
const history = this.listHistory
|
const history = this.listHistory.slice().reverse()
|
||||||
.slice()
|
|
||||||
.reverse()
|
|
||||||
.filter((i) => !!i.keyword)
|
|
||||||
return history.find((a) => a.from === from)
|
return history.find((a) => a.from === from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,12 @@ class MongoAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getPrevByNumber = async (from) => {
|
getPrevByNumber = async (from) => {
|
||||||
const result = await this.db.collection('history').find({ from }).sort({ _id: -1 }).limit(1).toArray()
|
const result = await this.db
|
||||||
|
.collection('history')
|
||||||
|
.find({ from })
|
||||||
|
.sort({ _id: -1 })
|
||||||
|
.limit(1)
|
||||||
|
.toArray()
|
||||||
return result[0]
|
return result[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,18 @@ class MyslAdapter {
|
|||||||
})
|
})
|
||||||
|
|
||||||
save = (ctx) => {
|
save = (ctx) => {
|
||||||
const values = [[ctx.ref, ctx.keyword, ctx.answer, ctx.refSerialize, ctx.from, JSON.stringify(ctx.options)]]
|
const values = [
|
||||||
const sql = 'INSERT INTO history (ref, keyword, answer, refSerialize, phone, options ) values ?'
|
[
|
||||||
|
ctx.ref,
|
||||||
|
ctx.keyword,
|
||||||
|
ctx.answer,
|
||||||
|
ctx.refSerialize,
|
||||||
|
ctx.from,
|
||||||
|
JSON.stringify(ctx.options),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
const sql =
|
||||||
|
'INSERT INTO history (ref, keyword, answer, refSerialize, phone, options ) values ?'
|
||||||
|
|
||||||
this.db.query(sql, [values], (err) => {
|
this.db.query(sql, [values], (err) => {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
@@ -61,14 +71,14 @@ class MyslAdapter {
|
|||||||
const tableName = 'history'
|
const tableName = 'history'
|
||||||
|
|
||||||
const sql = `CREATE TABLE ${tableName}
|
const sql = `CREATE TABLE ${tableName}
|
||||||
(id INT AUTO_INCREMENT PRIMARY KEY,
|
(id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
ref varchar(255) NOT NULL,
|
ref varchar(255) NOT NULL,
|
||||||
keyword varchar(255) NOT NULL,
|
keyword varchar(255) NOT NULL,
|
||||||
answer longtext NOT NULL,
|
answer longtext NOT NULL,
|
||||||
refSerialize varchar(255) NOT NULL,
|
refSerialize varchar(255) NOT NULL,
|
||||||
phone varchar(255) NOT NULL,
|
phone varchar(255) NOT NULL,
|
||||||
options longtext NOT NULL)
|
options longtext NOT NULL
|
||||||
CHARACTER SET utf8mb4 COLLATE utf8mb4_General_ci`
|
)`
|
||||||
|
|
||||||
this.db.query(sql, (err) => {
|
this.db.query(sql, (err) => {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|||||||
@@ -8,5 +8,6 @@
|
|||||||
font-family: IBMPlexMono-Regular;
|
font-family: IBMPlexMono-Regular;
|
||||||
src: url(IBMPlexMono-Regular-subset.woff2) format('woff2'),
|
src: url(IBMPlexMono-Regular-subset.woff2) format('woff2'),
|
||||||
url(IBMPlexMono-Regular-subset.zopfli.woff) format('woff');
|
url(IBMPlexMono-Regular-subset.zopfli.woff) format('woff');
|
||||||
unicode-range: U+20, U+2C, U+2E, U+41-43, U+46, U+49, U+4B-4F, U+53-55, U+58, U+61-65, U+67-69, U+6C-76;
|
unicode-range: U+20, U+2C, U+2E, U+41-43, U+46, U+49, U+4B-4F, U+53-55, U+58,
|
||||||
|
U+61-65, U+67-69, U+6C-76;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
font-family: IBMPlexMono-SemiBold;
|
font-family: IBMPlexMono-SemiBold;
|
||||||
src: url(IBMPlexMono-SemiBold-subset.woff2) format('woff2'),
|
src: url(IBMPlexMono-SemiBold-subset.woff2) format('woff2'),
|
||||||
url(IBMPlexMono-SemiBold-subset.zopfli.woff) format('woff');
|
url(IBMPlexMono-SemiBold-subset.zopfli.woff) format('woff');
|
||||||
unicode-range: U+20, U+24, U+2E, U+30, U+38, U+39, U+41, U+42, U+44, U+47, U+4E, U+4F, U+52-55, U+57, U+59, U+65,
|
unicode-range: U+20, U+24, U+2E, U+30, U+38, U+39, U+41, U+42, U+44, U+47,
|
||||||
U+68, U+6F, U+72, U+74;
|
U+4E, U+4F, U+52-55, U+57, U+59, U+65, U+68, U+6F, U+72, U+74;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: Pally-Variable;
|
font-family: Pally-Variable;
|
||||||
src: url(Pally-Variable-subset.woff2) format('woff2'), url(Pally-Variable-subset.zopfli.woff) format('woff');
|
src: url(Pally-Variable-subset.woff2) format('woff2'),
|
||||||
unicode-range: U+20, U+24, U+2C, U+2E, U+30, U+33, U+39, U+41-43, U+46, U+49-4D, U+53, U+55, U+58, U+61-65, U+67-69,
|
url(Pally-Variable-subset.zopfli.woff) format('woff');
|
||||||
U+6B-77, U+79;
|
unicode-range: U+20, U+24, U+2C, U+2E, U+30, U+33, U+39, U+41-43, U+46,
|
||||||
|
U+49-4D, U+53, U+55, U+58, U+61-65, U+67-69, U+6B-77, U+79;
|
||||||
font-weight: 400 700;
|
font-weight: 400 700;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,6 @@
|
|||||||
font-family: SourceSerifPro-Regular;
|
font-family: SourceSerifPro-Regular;
|
||||||
src: url(SourceSerifPro-Regular-subset.woff2) format('woff2'),
|
src: url(SourceSerifPro-Regular-subset.woff2) format('woff2'),
|
||||||
url(SourceSerifPro-Regular-subset.zopfli.woff) format('woff');
|
url(SourceSerifPro-Regular-subset.zopfli.woff) format('woff');
|
||||||
unicode-range: U+20, U+2C, U+2E, U+41-44, U+49, U+4A, U+4C, U+53, U+55, U+61-65, U+67-69, U+6B-76, U+79;
|
unicode-range: U+20, U+2C, U+2E, U+41-44, U+49, U+4A, U+4C, U+53, U+55,
|
||||||
|
U+61-65, U+67-69, U+6B-76, U+79;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: Synonym-Variable;
|
font-family: Synonym-Variable;
|
||||||
src: url(Synonym-Variable-subset.woff2) format('woff2'), url(Synonym-Variable-subset.zopfli.woff) format('woff');
|
src: url(Synonym-Variable-subset.woff2) format('woff2'),
|
||||||
unicode-range: U+20, U+24, U+2C, U+2E, U+30, U+33, U+35, U+41-44, U+46, U+47, U+49, U+4B-4F, U+53-55, U+57-59, U+61,
|
url(Synonym-Variable-subset.zopfli.woff) format('woff');
|
||||||
U+63-65, U+67-69, U+6C-76;
|
unicode-range: U+20, U+24, U+2C, U+2E, U+30, U+33, U+35, U+41-44, U+46, U+47,
|
||||||
|
U+49, U+4B-4F, U+53-55, U+57-59, U+61, U+63-65, U+67-69, U+6C-76;
|
||||||
font-weight: 400 700;
|
font-weight: 400 700;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: TenorSans-Regular;
|
font-family: TenorSans-Regular;
|
||||||
src: url(TenorSans-Regular-subset.woff2) format('woff2'), url(TenorSans-Regular-subset.zopfli.woff) format('woff');
|
src: url(TenorSans-Regular-subset.woff2) format('woff2'),
|
||||||
unicode-range: U+20, U+24, U+2E, U+30, U+36, U+46, U+49, U+4A, U+53, U+54, U+61, U+63, U+65, U+69, U+6B, U+6E, U+6F,
|
url(TenorSans-Regular-subset.zopfli.woff) format('woff');
|
||||||
U+72-75, U+79;
|
unicode-range: U+20, U+24, U+2E, U+30, U+36, U+46, U+49, U+4A, U+53, U+54,
|
||||||
|
U+61, U+63, U+65, U+69, U+6B, U+6E, U+6F, U+72-75, U+79;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.0 KiB |
@@ -1,189 +0,0 @@
|
|||||||
export const DigitalOcean = () => (
|
|
||||||
<svg
|
|
||||||
version="1.1"
|
|
||||||
id="Layer_1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
viewBox="0 0 604 129"
|
|
||||||
style="enable-background:new 0 0 604 129;"
|
|
||||||
xml:space="preserve"
|
|
||||||
>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="M174.3,3c4.9,0,8.7,2.9,8.7,8.6c0,5.6-3.8,8.5-8.7,8.5h-7.6v11.1h-3.5V3H174.3z M166.7,17.1h7.2
|
|
||||||
c3,0,5.6-1.8,5.6-5.5c0-3.8-2.5-5.5-5.6-5.5h-7.2V17.1z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="M208.8,21.7c0,6.1-4.3,10-9.9,10c-5.6,0-9.9-3.9-9.9-10c0-6.1,4.3-10,9.9-10
|
|
||||||
C204.5,11.7,208.8,15.6,208.8,21.7z M192.3,21.7c0,4.5,2.9,7.2,6.6,7.2c3.7,0,6.6-2.7,6.6-7.2c0-4.5-2.9-7.1-6.6-7.1
|
|
||||||
C195.2,14.5,192.3,17.2,192.3,21.7z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="M234.4,31.3l-5.2-13.8L224,31.3h-2.6L214.1,12h3.6l5.2,14l5.2-14h2.3l5.3,14l5.2-14h3.5L237,31.3H234.4z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="M253,22.9c0.2,3.7,2.6,5.9,6,5.9c2.8,0,4.8-1.3,5.4-3.4l3.2,0.2c-0.8,3.5-4.1,6.1-8.6,6.1
|
|
||||||
c-5.5,0-9.6-3.7-9.6-10c0-6.3,4-10,9.5-10c5.5,0,8.8,3.7,8.8,9.4v1.8H253z M253,20.3h11.6c-0.1-3.4-2-5.7-5.6-5.7
|
|
||||||
C255.6,14.5,253.2,16.5,253,20.3z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="M285.4,14.9c-3.4,0-5.6,2.3-5.6,5.3v11.1h-3.2V12h3.2v2.9c0.7-1.6,2.5-3.1,5.7-3.1V14.9z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="M294.7,22.9c0.2,3.7,2.6,5.9,6,5.9c2.8,0,4.8-1.3,5.4-3.4l3.2,0.2c-0.8,3.5-4.1,6.1-8.6,6.1
|
|
||||||
c-5.5,0-9.6-3.7-9.6-10c0-6.3,4-10,9.5-10c5.5,0,8.8,3.7,8.8,9.4v1.8H294.7z M294.7,20.3h11.6c-0.1-3.4-2-5.7-5.6-5.7
|
|
||||||
C297.4,14.5,294.9,16.5,294.7,20.3z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="M333.1,31.3v-3.1c-1.1,2-3.6,3.5-6.8,3.5c-5.3,0-9.3-3.8-9.3-10c0-6.2,4-10,9.3-10c3.2,0,5.6,1.4,6.6,3.2V2
|
|
||||||
h3.2v29.4H333.1z M320.3,21.7c0,4.6,2.8,7.2,6.5,7.2c3.6,0,6.2-2.2,6.2-6.6v-1.1c0-4.3-2.6-6.6-6.2-6.6
|
|
||||||
C323.1,14.5,320.3,17.1,320.3,21.7z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="M361.8,14.9c1.1-1.9,3.4-3.2,6.7-3.2c5.3,0,9.3,3.8,9.3,10c0,6.2-4,10-9.3,10c-3.3,0-5.7-1.5-6.8-3.5v3.1
|
|
||||||
h-3.1V2h3.2V14.9z M361.9,21.1v1.1c0,4.4,2.6,6.6,6.2,6.6c3.7,0,6.5-2.5,6.5-7.2c0-4.6-2.8-7.1-6.5-7.1
|
|
||||||
C364.5,14.5,361.9,16.8,361.9,21.1z"
|
|
||||||
/>
|
|
||||||
<path class="st0" d="M386.3,40.9l4.6-10.7L383.2,12h3.6l5.8,14.5l5.8-14.5h3.6l-12.2,28.9H386.3z" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g id="XMLID_2369_">
|
|
||||||
<g>
|
|
||||||
<g id="XMLID_281_">
|
|
||||||
<g id="XMLID_282_">
|
|
||||||
<g>
|
|
||||||
<g id="XMLID_283_">
|
|
||||||
<g id="XMLID_287_">
|
|
||||||
<path
|
|
||||||
id="XMLID_288_"
|
|
||||||
class="st0"
|
|
||||||
d="M64.4,127l0-24.2c25.6,0,45.5-25.4,35.7-52.3c-3.6-10-11.6-17.9-21.6-21.6
|
|
||||||
c-27-9.8-52.3,10-52.3,35.7c0,0,0,0,0,0L2,64.7C2,23.8,41.5-8,84.3,5.4c18.7,5.8,33.6,20.7,39.4,39.4
|
|
||||||
C137,87.6,105.2,127,64.4,127z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
<polygon
|
|
||||||
id="XMLID_286_"
|
|
||||||
class="st1"
|
|
||||||
points="64.4,102.9 40.4,102.9 40.4,78.9 40.4,78.9 64.4,78.9 64.4,78.9 "
|
|
||||||
/>
|
|
||||||
<polygon
|
|
||||||
id="XMLID_285_"
|
|
||||||
class="st1"
|
|
||||||
points="40.3,121.5 21.8,121.5 21.8,121.5 21.8,102.9 40.4,102.9 40.4,121.5 "
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
id="XMLID_284_"
|
|
||||||
class="st1"
|
|
||||||
d="M21.9,102.9H6.3c0,0,0,0,0,0V87.4c0,0,0,0,0,0h15.5c0,0,0,0,0,0V102.9z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g id="XMLID_254_">
|
|
||||||
<path
|
|
||||||
id="XMLID_278_"
|
|
||||||
class="st0"
|
|
||||||
d="M200.9,52.4c-5.5-3.8-12.4-5.8-20.5-5.8h-17.5v55.5h17.5c8,0,14.9-2.1,20.5-6.1
|
|
||||||
c3-2.1,5.4-5.1,7.1-8.9c1.7-3.7,2.5-8.2,2.5-13.1c0-4.9-0.8-9.3-2.5-13C206.3,57.4,203.9,54.4,200.9,52.4z M173.1,56h5.5
|
|
||||||
c6.1,0,11.1,1.2,15,3.6c4.2,2.6,6.4,7.4,6.4,14.4c0,7.2-2.2,12.3-6.4,15.1h0c-3.7,2.4-8.7,3.6-14.9,3.6h-5.6V56z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
id="XMLID_277_"
|
|
||||||
class="st0"
|
|
||||||
d="M222.6,45.9c-1.7,0-3.1,0.6-4.3,1.8c-1.2,1.1-1.8,2.6-1.8,4.2c0,1.7,0.6,3.1,1.8,4.3
|
|
||||||
c1.2,1.2,2.6,1.8,4.3,1.8c1.7,0,3.1-0.6,4.3-1.8c1.2-1.2,1.8-2.6,1.8-4.3c0-1.7-0.6-3.1-1.8-4.2
|
|
||||||
C225.7,46.5,224.3,45.9,222.6,45.9z"
|
|
||||||
/>
|
|
||||||
<rect id="XMLID_276_" x="217.6" y="63" class="st0" width="9.8" height="39.1" />
|
|
||||||
<path
|
|
||||||
id="XMLID_273_"
|
|
||||||
class="st0"
|
|
||||||
d="M263.2,66.3c-3-2.6-6.3-4.2-9.9-4.2c-5.4,0-9.9,1.9-13.4,5.6c-3.5,3.7-5.3,8.4-5.3,14.1
|
|
||||||
c0,5.5,1.8,10.2,5.2,14c3.5,3.7,8,5.5,13.5,5.5c3.8,0,7.1-1.1,9.7-3.1V99c0,3.2-0.9,5.8-2.6,7.5c-1.7,1.7-4.1,2.6-7.1,2.6
|
|
||||||
c-4.5,0-7.4-1.8-10.9-6.5l-6.7,6.4l0.2,0.3c1.4,2,3.7,4,6.6,5.9c2.9,1.9,6.6,2.8,10.9,2.8c5.8,0,10.6-1.8,14.1-5.4
|
|
||||||
c3.5-3.6,5.3-8.4,5.3-14.2V63h-9.7V66.3z M260.6,89.4c-1.7,2-3.9,2.9-6.8,2.9c-2.8,0-5-0.9-6.7-2.9c-1.7-1.9-2.5-4.5-2.5-7.7
|
|
||||||
c0-3.2,0.9-5.8,2.5-7.7c1.7-1.9,3.9-2.9,6.7-2.9c2.8,0,5,1,6.8,2.9c1.7,2,2.6,4.6,2.6,7.7C263.2,84.9,262.3,87.5,260.6,89.4z"
|
|
||||||
/>
|
|
||||||
<rect id="XMLID_272_" x="281.3" y="63" class="st0" width="9.8" height="39.1" />
|
|
||||||
<path
|
|
||||||
id="XMLID_271_"
|
|
||||||
class="st0"
|
|
||||||
d="M286.3,45.9c-1.7,0-3.1,0.6-4.3,1.8c-1.2,1.1-1.8,2.6-1.8,4.2c0,1.7,0.6,3.1,1.8,4.3
|
|
||||||
c1.2,1.2,2.6,1.8,4.3,1.8c1.7,0,3.1-0.6,4.3-1.8c1.2-1.2,1.8-2.6,1.8-4.3c0-1.7-0.6-3.1-1.8-4.2C289.4,46.5,288,45.9,286.3,45.9
|
|
||||||
z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
id="XMLID_270_"
|
|
||||||
class="st0"
|
|
||||||
d="M312.7,52.5H303V63h-5.6v9h5.6v16.2c0,5.1,1,8.7,3,10.8c2,2.1,5.6,3.2,10.6,3.2
|
|
||||||
c1.6,0,3.2-0.1,4.8-0.2l0.4,0v-9l-3.4,0.2c-2.3,0-3.9-0.4-4.7-1.2c-0.8-0.8-1.1-2.6-1.1-5.2V72h9.2v-9h-9.2V52.5z"
|
|
||||||
/>
|
|
||||||
<rect id="XMLID_269_" x="368" y="46.6" class="st0" width="9.8" height="55.5" />
|
|
||||||
<path
|
|
||||||
id="XMLID_268_"
|
|
||||||
class="st0"
|
|
||||||
d="M477.3,88.2c-1.8,2-3.6,3.7-4.9,4.6v0c-1.4,0.9-3.1,1.3-5.1,1.3c-2.9,0-5.2-1.1-7.1-3.2
|
|
||||||
c-1.9-2.2-2.8-4.9-2.8-8.3s0.9-6.1,2.8-8.2c1.9-2.2,4.2-3.2,7.1-3.2c3.2,0,6.5,2,9.4,5.4l6.5-6.2l0,0c-4.2-5.5-9.7-8.1-16.1-8.1
|
|
||||||
c-5.4,0-10.1,2-13.9,5.8c-3.8,3.9-5.7,8.8-5.7,14.6s1.9,10.7,5.7,14.6c3.8,3.9,8.5,5.9,13.9,5.9c7.1,0,12.9-3.1,16.8-8.7
|
|
||||||
L477.3,88.2z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
id="XMLID_265_"
|
|
||||||
class="st0"
|
|
||||||
d="M517.7,68.5c-1.4-1.9-3.3-3.5-5.7-4.7c-2.3-1.1-5.1-1.7-8.1-1.7c-5.5,0-10,2-13.4,6
|
|
||||||
c-3.3,4-4.9,8.9-4.9,14.7c0,5.9,1.8,10.8,5.4,14.6c3.6,3.7,8.4,5.6,14.2,5.6c6.6,0,12.1-2.7,16.2-8l0.2-0.3l-6.4-6.2l0,0
|
|
||||||
c-0.6,0.7-1.4,1.5-2.2,2.3c-1,0.9-1.9,1.6-2.9,2.1c-1.5,0.7-3.1,1.1-5,1.1c-2.7,0-5-0.8-6.7-2.4c-1.6-1.5-2.6-3.5-2.8-5.9h26.1
|
|
||||||
l0.1-3.6c0-2.5-0.3-5-1-7.3C520.1,72.6,519.1,70.4,517.7,68.5z M496.2,77.7c0.5-1.9,1.3-3.4,2.6-4.6c1.3-1.3,3.1-2,5.2-2
|
|
||||||
c2.4,0,4.2,0.7,5.5,2c1.2,1.2,1.8,2.8,2,4.6H496.2z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
id="XMLID_262_"
|
|
||||||
class="st0"
|
|
||||||
d="M555.5,66L555.5,66c-3-2.5-7.1-3.8-12.3-3.8c-3.3,0-6.3,0.7-9.1,2.1
|
|
||||||
c-2.6,1.3-5.1,3.5-6.7,6.3l0.1,0.1l6.3,6c2.6-4.1,5.5-5.6,9.3-5.6c2.1,0,3.8,0.6,5.1,1.6c1.3,1.1,1.9,2.5,1.9,4.2v1.9
|
|
||||||
c-2.4-0.7-4.9-1.1-7.2-1.1c-4.9,0-8.9,1.2-11.8,3.4c-3,2.3-4.5,5.6-4.5,9.8c0,3.7,1.3,6.7,3.8,8.9c2.6,2.1,5.8,3.2,9.5,3.2
|
|
||||||
c3.7,0,7.3-1.5,10.4-4.1v3.2h9.7V77C560,72.2,558.5,68.5,555.5,66z M538,87.2c1.1-0.8,2.7-1.2,4.7-1.2c2.4,0,4.9,0.5,7.5,1.4
|
|
||||||
v3.8c-2.1,2-5,3-8.5,3c-1.7,0-3-0.4-3.9-1.1c-0.9-0.7-1.3-1.7-1.3-2.8C536.4,89,536.9,88,538,87.2z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
id="XMLID_261_"
|
|
||||||
class="st0"
|
|
||||||
d="M597.9,66.7c-2.7-3.1-6.6-4.6-11.5-4.6c-3.9,0-7.1,1.1-9.4,3.3V63h-9.7v39.1h9.8V80.6
|
|
||||||
c0-3,0.7-5.3,2.1-7c1.4-1.7,3.3-2.5,5.8-2.5c2.2,0,3.9,0.7,5.2,2.2c1.3,1.5,1.9,3.6,1.9,6.2v22.7h9.8V79.5
|
|
||||||
C602,74.1,600.6,69.8,597.9,66.7z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
id="XMLID_258_"
|
|
||||||
class="st0"
|
|
||||||
d="M355.6,66L355.6,66c-3-2.5-7.1-3.8-12.3-3.8c-3.3,0-6.3,0.7-9.1,2.1
|
|
||||||
c-2.6,1.3-5.1,3.5-6.7,6.3l0.1,0.1l6.3,6c2.6-4.1,5.5-5.6,9.3-5.6c2.1,0,3.8,0.6,5.1,1.6c1.3,1.1,1.9,2.5,1.9,4.2v1.9
|
|
||||||
c-2.4-0.7-4.9-1.1-7.2-1.1c-4.9,0-8.9,1.2-11.8,3.4c-3,2.3-4.5,5.6-4.5,9.8c0,3.7,1.3,6.7,3.8,8.9c2.6,2.1,5.8,3.2,9.5,3.2
|
|
||||||
c3.7,0,7.3-1.5,10.4-4.1v3.2h9.7V77C360.2,72.2,358.7,68.5,355.6,66z M338.2,87.2c1.1-0.8,2.7-1.2,4.7-1.2
|
|
||||||
c2.4,0,4.9,0.5,7.5,1.4v3.8c-2.1,2-5,3-8.5,3c-1.7,0-3-0.4-3.9-1.1c-0.9-0.7-1.3-1.7-1.3-2.8C336.6,89,337.1,88,338.2,87.2z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
id="XMLID_255_"
|
|
||||||
class="st0"
|
|
||||||
d="M413.6,103c-15.8,0-28.6-12.8-28.6-28.6s12.8-28.6,28.6-28.6s28.6,12.8,28.6,28.6
|
|
||||||
S429.4,103,413.6,103z M413.6,55.8c-10.2,0-18.5,8.3-18.5,18.5s8.3,18.5,18.5,18.5s18.5-8.3,18.5-18.5S423.8,55.8,413.6,55.8z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
@@ -5,7 +5,14 @@ import logoSrc from '~/assets/images/chatbot-whatsapp.png?width=64&height=64&png
|
|||||||
|
|
||||||
export default component$(() => (
|
export default component$(() => (
|
||||||
<span class="self-center ml-2 text-2xl md:text-xl font-bold text-gray-900 whitespace-nowrap dark:text-white flex items-center">
|
<span class="self-center ml-2 text-2xl md:text-xl font-bold text-gray-900 whitespace-nowrap dark:text-white flex items-center">
|
||||||
<img src={logoSrc} class="inline-block mr-1" width={32} height={32} alt="Qwind Logo" loading="lazy" />
|
<img
|
||||||
|
src={logoSrc}
|
||||||
|
class="inline-block mr-1"
|
||||||
|
width={32}
|
||||||
|
height={32}
|
||||||
|
alt="Qwind Logo"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
Chatbot
|
Chatbot
|
||||||
</span>
|
</span>
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
export const Netlify = () => (
|
export const Netlify = () => (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width={147} height={40} role="img" fill="currentColor">
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={147}
|
||||||
|
height={40}
|
||||||
|
role="img"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
<g fill-rule="evenodd">
|
<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 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
|
<path
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ export const RouterHead = component$(() => {
|
|||||||
<title>{head.title}</title>
|
<title>{head.title}</title>
|
||||||
|
|
||||||
<link rel="canonical" href={loc.href} />
|
<link rel="canonical" href={loc.href} />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0"
|
||||||
|
/>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
|
||||||
{head.meta.map((m) => (
|
{head.meta.map((m) => (
|
||||||
|
|||||||
@@ -34,8 +34,14 @@ export const Social = () => {
|
|||||||
content="https://campaign.codigoencasa.com"
|
content="https://campaign.codigoencasa.com"
|
||||||
/>
|
/>
|
||||||
<meta property="og:site_name" content="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
|
||||||
<meta property="og:image:secure_url" content="https://i.imgur.com/0HpzsEm.png" />
|
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:type" content="image/png"></meta>
|
||||||
<meta property="og:image:width" content="1200"></meta>
|
<meta property="og:image:width" content="1200"></meta>
|
||||||
<meta property="og:image:height" content="630"></meta>
|
<meta property="og:image:height" content="630"></meta>
|
||||||
@@ -46,7 +52,10 @@ export const Social = () => {
|
|||||||
name="twitter:title"
|
name="twitter:title"
|
||||||
content="💻 Conviértete en un Programador Backend aprendiendo todo de Cloud y Nodejs"
|
content="💻 Conviértete en un Programador Backend aprendiendo todo de Cloud y Nodejs"
|
||||||
/>
|
/>
|
||||||
<meta name="twitter:image" content="https://i.imgur.com/0HpzsEm.png" />
|
<meta
|
||||||
|
name="twitter:image"
|
||||||
|
content="https://i.imgur.com/0HpzsEm.png"
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ export default component$((props: ItemProps) => {
|
|||||||
// TODO:
|
// TODO:
|
||||||
document.body.classList.toggle('overflow-hidden')
|
document.body.classList.toggle('overflow-hidden')
|
||||||
document.getElementById('header')?.classList.toggle('h-screen')
|
document.getElementById('header')?.classList.toggle('h-screen')
|
||||||
document.querySelector('#header nav')?.classList.toggle('hidden')
|
document
|
||||||
|
.querySelector('#header nav')
|
||||||
|
?.classList.toggle('hidden')
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconMenu class={iconClass} />
|
<IconMenu class={iconClass} />
|
||||||
|
|||||||
@@ -10,13 +10,16 @@ interface ItemProps {
|
|||||||
export default component$((props: ItemProps) => {
|
export default component$((props: ItemProps) => {
|
||||||
const { iconClass } = props
|
const { iconClass } = props
|
||||||
const store = useStore({
|
const store = useStore({
|
||||||
theme: (typeof window !== 'undefined' && window?.localStorage?.theme) || undefined,
|
theme:
|
||||||
|
(typeof window !== 'undefined' && window?.localStorage?.theme) ||
|
||||||
|
undefined,
|
||||||
})
|
})
|
||||||
|
|
||||||
useClientEffect$(() => {
|
useClientEffect$(() => {
|
||||||
store.theme =
|
store.theme =
|
||||||
window.localStorage.theme === 'dark' ||
|
window.localStorage.theme === 'dark' ||
|
||||||
(!('theme' in window.localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
(!('theme' in window.localStorage) &&
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
? 'dark'
|
? 'dark'
|
||||||
: 'light'
|
: 'light'
|
||||||
})
|
})
|
||||||
@@ -39,7 +42,11 @@ export default component$((props: ItemProps) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{store.theme == 'dark' ? <IconMoon class={iconClass} /> : <IconSun class={iconClass} />}
|
{store.theme == 'dark' ? (
|
||||||
|
<IconMoon class={iconClass} />
|
||||||
|
) : (
|
||||||
|
<IconSun class={iconClass} />
|
||||||
|
)}
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ export const IconArrowDownRight = (props: ItemProps) => {
|
|||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class={`icon icon-tabler icon-tabler-arrow-down-right ${className || 'w-5 h-5'}`}
|
class={`icon icon-tabler icon-tabler-arrow-down-right ${
|
||||||
|
className || 'w-5 h-5'
|
||||||
|
}`}
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ export const IconMenu = (props: ItemProps) => {
|
|||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
class={`icon icon-tabler icon-tabler-menu ${className || 'w-5 h-5'}`}
|
class={`icon icon-tabler icon-tabler-menu ${
|
||||||
|
className || 'w-5 h-5'
|
||||||
|
}`}
|
||||||
preserveAspectRatio="xMidYMid meet"
|
preserveAspectRatio="xMidYMid meet"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ export const IconMoon = (props: ItemProps) => {
|
|||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class={`icon icon-tabler icon-tabler-moon ${className || 'w-5 h-5'}`}
|
class={`icon icon-tabler icon-tabler-moon ${
|
||||||
|
className || 'w-5 h-5'
|
||||||
|
}`}
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default component$(
|
|||||||
<a href={props.user.html_url} target="_blank">
|
<a href={props.user.html_url} target="_blank">
|
||||||
<img
|
<img
|
||||||
class="w-16 h-16 rounded-full mx-auto object-cover"
|
class="w-16 h-16 rounded-full mx-auto object-cover"
|
||||||
src={props.user.avatar_url}
|
src={props.user.avatar_url + '&s=80'}
|
||||||
alt={props.user.login}
|
alt={props.user.login}
|
||||||
width="80"
|
width="80"
|
||||||
height="80"
|
height="80"
|
||||||
@@ -23,7 +23,7 @@ export default component$(
|
|||||||
|
|
||||||
<div class="pt-2 space-y-4 justify-center flex">
|
<div class="pt-2 space-y-4 justify-center flex">
|
||||||
<figcaption class="text-sm">
|
<figcaption class="text-sm">
|
||||||
<div class={'font-semibold truncate'}>{props.user.login}</div>
|
<div class={'font-semibold'}>{props.user.login}</div>
|
||||||
</figcaption>
|
</figcaption>
|
||||||
</div>
|
</div>
|
||||||
</figure>
|
</figure>
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ export default component$((props: { users: User[] }) => {
|
|||||||
Super estrellas
|
Super estrellas
|
||||||
</h2>
|
</h2>
|
||||||
<p class="max-w-3xl mx-auto sm:text-center text-xl text-gray-600 dark:text-slate-400">
|
<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{' '}
|
Todo es posible gracias a el mayor recursos de todos, el
|
||||||
|
recurso humano. Tu tambien puedes{' '}
|
||||||
<a class={'font-semibold'} href="/docs/contributing">
|
<a class={'font-semibold'} href="/docs/contributing">
|
||||||
formar parte
|
formar parte
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ export default component$(() => {
|
|||||||
📄 Editar esta pagina
|
📄 Editar esta pagina
|
||||||
</a>
|
</a>
|
||||||
<p class={'text-xs'}>
|
<p class={'text-xs'}>
|
||||||
Forma parte de esta comunidad mejorando la documentación siente libre de poder agregar o editar
|
Forma parte de esta comunidad mejorando la documentación
|
||||||
lo que quieras
|
siente libre de poder agregar o editar lo que quieras
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -56,9 +56,13 @@ export default component$(() => {
|
|||||||
<IconArrowDownRight class="w-7 h-7 text-primary-600 inline-block" />
|
<IconArrowDownRight class="w-7 h-7 text-primary-600 inline-block" />
|
||||||
{question}
|
{question}
|
||||||
</div>
|
</div>
|
||||||
{answer.split('\n\n').map((paragraph) => (
|
{answer
|
||||||
<p class="text-gray-700 dark:text-gray-400 mb-2">{paragraph}</p>
|
.split('\n\n')
|
||||||
))}
|
.map((paragraph) => (
|
||||||
|
<p class="text-gray-700 dark:text-gray-400 mb-2">
|
||||||
|
{paragraph}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -50,11 +50,13 @@ export default component$(() => {
|
|||||||
Caracteristicas
|
Caracteristicas
|
||||||
</p>
|
</p>
|
||||||
<h2 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-4 font-heading">
|
<h2 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-4 font-heading">
|
||||||
Nuestras principales <span class="whitespace-nowrap">funciones</span>
|
Nuestras principales{' '}
|
||||||
|
<span class="whitespace-nowrap">funciones</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="max-w-3xl mx-auto sm:text-center text-xl text-gray-600 dark:text-slate-400">
|
<p class="max-w-3xl mx-auto sm:text-center text-xl text-gray-600 dark:text-slate-400">
|
||||||
El secreto es mantener los procesos repetitivos en procesos automatizados simples, por eso te
|
El secreto es mantener los procesos repetitivos en
|
||||||
mostramos en que destacamos.
|
procesos automatizados simples, por eso te mostramos en
|
||||||
|
que destacamos.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid mx-auto space-y-6 md:grid-cols-2 md:space-y-0">
|
<div class="grid mx-auto space-y-6 md:grid-cols-2 md:space-y-0">
|
||||||
@@ -68,8 +70,12 @@ export default component$(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="mb-3 text-xl font-bold">{title}</h3>
|
<h3 class="mb-3 text-xl font-bold">
|
||||||
<p class="text-gray-600 dark:text-slate-400">{description}</p>
|
{title}
|
||||||
|
</h3>
|
||||||
|
<p class="text-gray-600 dark:text-slate-400">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -9,24 +9,36 @@ import { src as placeholder } from '~/assets/images/chatbot-whatsapp.png?width=4
|
|||||||
|
|
||||||
export default component$(() => {
|
export default component$(() => {
|
||||||
return (
|
return (
|
||||||
<section class={` from-white via-purple-50 to-sky-100 dark:bg-none mt-[-95px]`}>
|
<section
|
||||||
|
class={` from-white via-purple-50 to-sky-100 dark:bg-none mt-[-95px]`}
|
||||||
|
>
|
||||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 md:flex md:h-screen 2xl:h-auto pt-[72px]">
|
<div class="max-w-6xl mx-auto px-4 sm:px-6 md:flex md:h-screen 2xl:h-auto pt-[72px]">
|
||||||
<div class="py-12 md:py-12 lg:py-16 block md:flex text-center md:text-left">
|
<div class="py-12 md:py-12 lg:py-16 block md:flex text-center md:text-left">
|
||||||
<div class="pb-12 md:pb-0 md:py-0 max-w-5xl mx-auto md:pr-16 flex items-center basis-[56%]">
|
<div class="pb-12 md:pb-0 md:py-0 max-w-5xl mx-auto md:pr-16 flex items-center basis-[56%]">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-5xl md:text-[3.48rem] font-bold leading-tighter tracking-tighter mb-4 font-heading px-4 md:px-0">
|
<h1 class="text-5xl md:text-[3.48rem] font-bold leading-tighter tracking-tighter mb-4 font-heading px-4 md:px-0">
|
||||||
Crear chatbot <span class="sm:whitespace-nowrap text-[#25b637]">WhatsApp</span>
|
Crear chatbot{' '}
|
||||||
<br class="hidden lg:block" /> <span class="lg:inline">en minutos</span>
|
<span class="sm:whitespace-nowrap text-[#25b637]">
|
||||||
|
WhatsApp
|
||||||
|
</span>
|
||||||
|
<br class="hidden lg:block" />{' '}
|
||||||
|
<span class="lg:inline">en minutos</span>
|
||||||
</h1>
|
</h1>
|
||||||
<div class="max-w-3xl mx-auto">
|
<div class="max-w-3xl mx-auto">
|
||||||
<p class="text-xl text-gray-600 mb-8 dark:text-slate-400">
|
<p class="text-xl text-gray-600 mb-8 dark:text-slate-400">
|
||||||
<span class="font-semibold ">Con esta libreria, </span>
|
<span class="font-semibold ">
|
||||||
|
Con esta libreria,{' '}
|
||||||
|
</span>
|
||||||
<span class="font-semibold ">
|
<span class="font-semibold ">
|
||||||
puedes configurar respuestas automatizadas para preguntas frecuentes
|
puedes configurar respuestas
|
||||||
|
automatizadas para preguntas frecuentes
|
||||||
</span>{' '}
|
</span>{' '}
|
||||||
, recibir y responder mensajes de manera automatizada, y hacer un seguimiento de las
|
, recibir y responder mensajes de manera
|
||||||
interacciones con los clientes. Además, nuestro Chatbot se integra fácilmente con
|
automatizada, y hacer un seguimiento de las
|
||||||
otros sistemas y herramientas que ya esté utilizando en su negocio.
|
interacciones con los clientes. Además,
|
||||||
|
nuestro Chatbot se integra fácilmente con
|
||||||
|
otros sistemas y herramientas que ya esté
|
||||||
|
utilizando en su negocio.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="max-w-xs sm:max-w-md flex flex-nowrap flex-col sm:flex-col gap-4 m-auto md:m-0 justify-center md:justify-start">
|
<div class="max-w-xs sm:max-w-md flex flex-nowrap flex-col sm:flex-col gap-4 m-auto md:m-0 justify-center md:justify-start">
|
||||||
@@ -35,16 +47,12 @@ export default component$(() => {
|
|||||||
npm create bot-whatsapp@latest
|
npm create bot-whatsapp@latest
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex w-full sm:w-auto gap-3">
|
<div class="flex w-full sm:w-auto">
|
||||||
<a href="/docs" class="btn bg-gray-50 dark:bg-transparent">
|
|
||||||
Ver documentación
|
|
||||||
</a>
|
|
||||||
<a
|
<a
|
||||||
target={'_blank'}
|
href="/docs"
|
||||||
href="https://youtu.be/UgoS8PXxe-A"
|
|
||||||
class="btn bg-gray-50 dark:bg-transparent"
|
class="btn bg-gray-50 dark:bg-transparent"
|
||||||
>
|
>
|
||||||
Ver video
|
Ver documentación
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
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 const onRequest: RequestHandlerCloudflarePages = async () => {
|
|
||||||
console.log('??heree')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const TaleUsers = component$((props: { users: User[] }) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{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">
|
|
||||||
Premium
|
|
||||||
</p>
|
|
||||||
<h2 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-4 font-heading">
|
|
||||||
Miembros
|
|
||||||
</h2>
|
|
||||||
<p class="max-w-3xl mx-auto sm:text-center text-xl text-gray-600 dark:text-slate-400">
|
|
||||||
Conviértete en un miembro destacado y forma parte del proyecto y disfruta de manera adelantada
|
|
||||||
de las actualizaciones{' '}
|
|
||||||
<a class={'font-semibold'} target={'_blank'} href="https://opencollective.com/bot-whatsapp">
|
|
||||||
Únete
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="grid lg:grid-cols-12 grid-cols-1 gap-4 ">
|
|
||||||
<TaleUsers users={props.users} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
@@ -5,45 +5,55 @@ import { DocumentationCtx } from '~/contexts'
|
|||||||
/**
|
/**
|
||||||
* options = [] array con la lista de opciones de la documentacion
|
* options = [] array con la lista de opciones de la documentacion
|
||||||
*/
|
*/
|
||||||
export default component$(({ options = [] }: { options: DocumentationCtx[] }) => {
|
export default component$(
|
||||||
return (
|
({ options = [] }: { options: DocumentationCtx[] }) => {
|
||||||
<div>
|
return (
|
||||||
{options.map((item, i) => (
|
<div>
|
||||||
<UlCompoent key={i} title={item.title} list={item.list} />
|
{options.map((item, i) => (
|
||||||
))}
|
<UlCompoent key={i} title={item.title} list={item.list} />
|
||||||
</div>
|
))}
|
||||||
)
|
</div>
|
||||||
})
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
export const UlCompoent = component$((porps: { title: string; list: { link: string; name: string }[] }) => {
|
export const UlCompoent = component$(
|
||||||
return (
|
(porps: { title: string; list: { link: string; name: string }[] }) => {
|
||||||
<ul>
|
return (
|
||||||
<li class="mt-2 lg:mt-2">
|
<ul>
|
||||||
<h5 class="mb-8 lg:mb-3 font-semibold text-slate-900 dark:text-slate-200">{porps.title}</h5>
|
<li class="mt-2 lg:mt-2">
|
||||||
<LiComponent list={porps.list} />
|
<h5 class="mb-8 lg:mb-3 font-semibold text-slate-900 dark:text-slate-200">
|
||||||
</li>
|
{porps.title}
|
||||||
</ul>
|
</h5>
|
||||||
)
|
<LiComponent list={porps.list} />
|
||||||
})
|
|
||||||
|
|
||||||
export const LiComponent = component$((porps: { list: { link: string; name: string }[] }) => {
|
|
||||||
const location = useLocation()
|
|
||||||
const currentPage = location.pathname
|
|
||||||
return (
|
|
||||||
<ul class="space-y-6 lg:space-y-2 border-l border-slate-100 dark:border-slate-800">
|
|
||||||
{porps.list.map((opt) => (
|
|
||||||
<li>
|
|
||||||
<Link
|
|
||||||
class={[
|
|
||||||
currentPage === `${opt.link}/` ? 'font-semibold' : '',
|
|
||||||
'block border-l pl-4 -ml-px border-transparent hover:border-slate-400 dark:hover:border-slate-500 text-slate-700 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-300 ',
|
|
||||||
]}
|
|
||||||
href={opt.link}
|
|
||||||
>
|
|
||||||
{opt.name}
|
|
||||||
</Link>
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
</ul>
|
||||||
</ul>
|
)
|
||||||
)
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
|
export const LiComponent = component$(
|
||||||
|
(porps: { list: { link: string; name: string }[] }) => {
|
||||||
|
const location = useLocation()
|
||||||
|
const currentPage = location.pathname
|
||||||
|
return (
|
||||||
|
<ul class="space-y-6 lg:space-y-2 border-l border-slate-100 dark:border-slate-800">
|
||||||
|
{porps.list.map((opt) => (
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
class={[
|
||||||
|
currentPage === `${opt.link}/`
|
||||||
|
? 'font-semibold'
|
||||||
|
: '',
|
||||||
|
'block border-l pl-4 -ml-px border-transparent hover:border-slate-400 dark:hover:border-slate-500 text-slate-700 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-300 ',
|
||||||
|
]}
|
||||||
|
href={opt.link}
|
||||||
|
>
|
||||||
|
{opt.name}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,63 +1,74 @@
|
|||||||
import { component$ } from '@builder.io/qwik'
|
import { component$ } from '@builder.io/qwik'
|
||||||
|
|
||||||
export const ButtonLink = component$((props: { name: string; link: string; direction: 'left' | 'right' }) => {
|
export const ButtonLink = component$(
|
||||||
const ArrowRight = () => (
|
(props: { name: string; link: string; direction: 'left' | 'right' }) => {
|
||||||
<svg
|
const ArrowRight = () => (
|
||||||
viewBox="0 0 3 6"
|
<svg
|
||||||
class="ml-3 w-auto h-1.5 text-slate-400 overflow-visible group-hover:text-slate-600 dark:group-hover:text-slate-300"
|
viewBox="0 0 3 6"
|
||||||
>
|
class="ml-3 w-auto h-1.5 text-slate-400 overflow-visible group-hover:text-slate-600 dark:group-hover:text-slate-300"
|
||||||
<path
|
>
|
||||||
d="M0 0L3 3L0 6"
|
<path
|
||||||
fill="none"
|
d="M0 0L3 3L0 6"
|
||||||
stroke="currentColor"
|
fill="none"
|
||||||
stroke-width="2"
|
stroke="currentColor"
|
||||||
stroke-linecap="round"
|
stroke-width="2"
|
||||||
stroke-linejoin="round"
|
stroke-linecap="round"
|
||||||
></path>
|
stroke-linejoin="round"
|
||||||
</svg>
|
></path>
|
||||||
)
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
const ArrowLeft = () => (
|
const ArrowLeft = () => (
|
||||||
<svg
|
<svg
|
||||||
viewBox="0 0 3 6"
|
viewBox="0 0 3 6"
|
||||||
class="mr-3 w-auto h-1.5 text-slate-400 overflow-visible group-hover:text-slate-600 dark:group-hover:text-slate-300"
|
class="mr-3 w-auto h-1.5 text-slate-400 overflow-visible group-hover:text-slate-600 dark:group-hover:text-slate-300"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
d="M3 0L0 3L3 6"
|
d="M3 0L0 3L3 6"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a class="group flex items-center hover:text-slate-900 dark:hover:text-white" href={props.link}>
|
<a
|
||||||
{props.direction === 'left' ? (
|
class="group flex items-center hover:text-slate-900 dark:hover:text-white"
|
||||||
<>
|
href={props.link}
|
||||||
<ArrowLeft />
|
>
|
||||||
{props.name}
|
{props.direction === 'left' ? (
|
||||||
</>
|
<>
|
||||||
) : (
|
<ArrowLeft />
|
||||||
<>
|
{props.name}
|
||||||
{props.name}
|
</>
|
||||||
<ArrowRight />
|
) : (
|
||||||
</>
|
<>
|
||||||
)}
|
{props.name}
|
||||||
</a>
|
<ArrowRight />
|
||||||
)
|
</>
|
||||||
})
|
)}
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
export default component$((props: { pages: ({ name: string; link: string } | null)[] }) => {
|
export default component$(
|
||||||
const { pages } = props
|
(props: { pages: ({ name: string; link: string } | null)[] }) => {
|
||||||
return (
|
const { pages } = props
|
||||||
<div class="text-sm leading-6 mt-12">
|
return (
|
||||||
<div class="mb-10 text-slate-700 font-semibold flex justify-between items-center dark:text-slate-200">
|
<div class="text-sm leading-6 mt-12">
|
||||||
{pages[0] ? <ButtonLink direction="left" {...pages[0]} /> : null}
|
<div class="mb-10 text-slate-700 font-semibold flex justify-between items-center dark:text-slate-200">
|
||||||
{pages[1] ? <ButtonLink direction="right" {...pages[1]} /> : null}
|
{pages[0] ? (
|
||||||
|
<ButtonLink direction="left" {...pages[0]} />
|
||||||
|
) : null}
|
||||||
|
{pages[1] ? (
|
||||||
|
<ButtonLink direction="right" {...pages[1]} />
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
}
|
||||||
})
|
)
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import { component$ } from '@builder.io/qwik'
|
|
||||||
|
|
||||||
export const SearchModal = component$(() => {
|
|
||||||
// const state = useStore({
|
|
||||||
// open: false,
|
|
||||||
// src: '',
|
|
||||||
// })
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class={'bg-gray-100/75 fixed w-[100vw] h-[100vh] z-50'}>
|
|
||||||
<div class={'bg-red-200 w-1/3 m-auto mt-12'}>
|
|
||||||
<SingleModal />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
export const SingleModal = component$(() => {
|
|
||||||
return <div class={'bg-blue-300 w-100 px-3 py-2'}>Modal singlke</div>
|
|
||||||
})
|
|
||||||
@@ -7,8 +7,6 @@ import { src as qwik } from '~/assets/images/qwik.png?width=100&metadata'
|
|||||||
import { src as leanga } from '~/assets/images/leanga.png?width=40&metadata'
|
import { src as leanga } from '~/assets/images/leanga.png?width=40&metadata'
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { src as netlify } from '~/assets/images/full-logo-light.png?width=100&metadata'
|
import { src as netlify } from '~/assets/images/full-logo-light.png?width=100&metadata'
|
||||||
// @ts-ignore
|
|
||||||
import { src as digitalOcean } from '~/assets/images/digital-ocean.png?width=100&metadata'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* options = [] array con la lista de opciones de la documentacion
|
* options = [] array con la lista de opciones de la documentacion
|
||||||
@@ -43,20 +41,7 @@ export default component$(() => {
|
|||||||
<img
|
<img
|
||||||
src={netlify}
|
src={netlify}
|
||||||
class="border border-slate-200 rounded my-2 p-1 bg-gray-50 dark:border-gray-600 dark:bg-gray-700"
|
class="border border-slate-200 rounded my-2 p-1 bg-gray-50 dark:border-gray-600 dark:bg-gray-700"
|
||||||
alt="Netlify"
|
alt="Qwind Hero Image (Cool dog)"
|
||||||
loading="eager"
|
|
||||||
decoding="async"
|
|
||||||
/>
|
|
||||||
</picture>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a target={'_blank'} href="https://m.do.co/c/140291d21736">
|
|
||||||
<picture>
|
|
||||||
<img
|
|
||||||
src={digitalOcean}
|
|
||||||
class="border border-slate-200 rounded my-2 p-1 bg-gray-50 dark:border-gray-600 dark:bg-gray-700"
|
|
||||||
alt="DigitalOcean"
|
|
||||||
loading="eager"
|
loading="eager"
|
||||||
decoding="async"
|
decoding="async"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -5,25 +5,33 @@ export default component$(() => {
|
|||||||
<div class="px-4 py-8 md:py-16 sm:px-6 mx-auto md:px-24 lg:px-8 lg:py-20 max-w-6xl">
|
<div class="px-4 py-8 md:py-16 sm:px-6 mx-auto md:px-24 lg:px-8 lg:py-20 max-w-6xl">
|
||||||
<div class="grid grid-cols-2 row-gap-8 md:grid-cols-4">
|
<div class="grid grid-cols-2 row-gap-8 md:grid-cols-4">
|
||||||
<div class="text-center md:border-r dark:md:border-slate-500 mb-10 md:mb-0">
|
<div class="text-center md:border-r dark:md:border-slate-500 mb-10 md:mb-0">
|
||||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-[#039de1] font-heading">132K</div>
|
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-[#039de1] font-heading">
|
||||||
|
132K
|
||||||
|
</div>
|
||||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
||||||
Downloads
|
Downloads
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center md:border-r dark:md:border-slate-500 mb-10 md:mb-0">
|
<div class="text-center md:border-r dark:md:border-slate-500 mb-10 md:mb-0">
|
||||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-[#039de1] font-heading">24.8K</div>
|
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-[#039de1] font-heading">
|
||||||
|
24.8K
|
||||||
|
</div>
|
||||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
||||||
Stars
|
Stars
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center md:border-r dark:md:border-slate-500 font-heading">
|
<div class="text-center md:border-r dark:md:border-slate-500 font-heading">
|
||||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-[#039de1]">10.3K</div>
|
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-[#039de1]">
|
||||||
|
10.3K
|
||||||
|
</div>
|
||||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
||||||
Forks
|
Forks
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-[#039de1] font-heading">48.4K</div>
|
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-[#039de1] font-heading">
|
||||||
|
48.4K
|
||||||
|
</div>
|
||||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
||||||
Users
|
Users
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ export interface User {
|
|||||||
avatar_url: string
|
avatar_url: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GlobalStore = createContext<DocumentationCtx[]>('documentation-site')
|
export const GlobalStore =
|
||||||
|
createContext<DocumentationCtx[]>('documentation-site')
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
import { component$, useContextProvider, useStore, useStyles$ } from '@builder.io/qwik'
|
import {
|
||||||
import { QwikCityProvider, RouterOutlet, ServiceWorkerRegister } from '@builder.io/qwik-city'
|
component$,
|
||||||
|
useContextProvider,
|
||||||
|
useStore,
|
||||||
|
useStyles$,
|
||||||
|
} from '@builder.io/qwik'
|
||||||
|
import {
|
||||||
|
QwikCityProvider,
|
||||||
|
RouterOutlet,
|
||||||
|
ServiceWorkerRegister,
|
||||||
|
} from '@builder.io/qwik-city'
|
||||||
|
|
||||||
import { RouterHead } from '~/components/core/RouterHead'
|
import { RouterHead } from '~/components/core/RouterHead'
|
||||||
import { DarkThemeLauncher } from '~/components/core/DarkThemeLauncher'
|
import { DarkThemeLauncher } from '~/components/core/DarkThemeLauncher'
|
||||||
@@ -43,22 +52,16 @@ export default component$(() => {
|
|||||||
title: 'Avanzado',
|
title: 'Avanzado',
|
||||||
list: [
|
list: [
|
||||||
{ name: 'Migración', link: '/docs/migration' },
|
{ name: 'Migración', link: '/docs/migration' },
|
||||||
{ name: 'MasterClass', link: '/docs/masterclass' },
|
{ name: 'Extender funcionalidades', link: '/docs/custom' },
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Despliegue',
|
|
||||||
list: [
|
|
||||||
{ name: 'Local', link: '/docs/deploy/local' },
|
|
||||||
{ name: 'Docker', link: '/docs/deploy/docker' },
|
|
||||||
{ name: 'Cloud', link: '/docs/deploy/cloud' },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Comunidad',
|
title: 'Comunidad',
|
||||||
list: [
|
list: [
|
||||||
|
{ name: 'MasterClass', link: '/docs/masterclass' },
|
||||||
{ name: 'Colabores', link: '/docs/contributing' },
|
{ name: 'Colabores', link: '/docs/contributing' },
|
||||||
{ name: 'Unirme al proyecto', link: '/docs/join' },
|
{ name: 'Unirme al proyecto', link: '/docs/join' },
|
||||||
|
{ name: 'Sponsors', link: '/docs/sponsors' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
@@ -69,7 +72,10 @@ export default component$(() => {
|
|||||||
<QwikCityProvider>
|
<QwikCityProvider>
|
||||||
<head>
|
<head>
|
||||||
<meta charSet="utf-8" />
|
<meta charSet="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1"
|
||||||
|
/>
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<RouterHead />
|
<RouterHead />
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import Navigation from '../../../components/widgets/Navigation'
|
|||||||
# DataBase (Base de datos)
|
# DataBase (Base de datos)
|
||||||
|
|
||||||
<Alert>
|
<Alert>
|
||||||
⚡ Dependiendo del tipo de conector que utlices puede que necesites pasar algunas configuracion adicional como
|
⚡ Dependiendo del tipo de conector que utlices puede que necesites pasar
|
||||||
**user, host, password** para esos casos te recomendamos guiarte de los
|
algunas configuracion adicional como **user, host, password** para esos
|
||||||
**[starters](https://github.com/codigoencasa/bot-whatsapp/tree/dev/starters/apps)** o si gustas puedes editar esta
|
casos te recomendamos guiarte de los
|
||||||
documentación para ir agregando más info
|
**[starters](https://github.com/codigoencasa/bot-whatsapp/tree/dev/starters/apps)**
|
||||||
|
o si gustas puedes editar esta documentación para ir agregando más info
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
Es la pieza encargada de mantener el **"estado"** de una conversación, para mayor facilidad la libreria te proporcia diferentes conectores que se de adapten mejor a tu desarrollo
|
Es la pieza encargada de mantener el **"estado"** de una conversación, para mayor facilidad la libreria te proporcia diferentes conectores que se de adapten mejor a tu desarrollo
|
||||||
|
|||||||
@@ -1,108 +0,0 @@
|
|||||||
import Alert from '../../../../components/widgets/Alert'
|
|
||||||
import Navigation from '../../../../components/widgets/Navigation'
|
|
||||||
|
|
||||||
# Entorno Cloud
|
|
||||||
|
|
||||||
Si deseas tener tu chatbot en ejecución en un servidor en la nueba esta, guía te ayudará.
|
|
||||||
El servidor deberá cumplir con los requisitos mínimos, puedes ver en [este enlace.](/docs/requirements)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Dependiendo de tu proveedor de **servicio Cloud** debes crear una instancia (máquina virtual), este ejemplo iremos orientando en un entorno de AWS.
|
|
||||||
En nuestro ejemplo creamos una maquina virtual con **Ubuntu 20.04**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Posterior al proceso de crear la máquina esperamos unos minutos hasta que ya está operativo y tomamos nota del usuario y la IP pública para proceder a conectarnos vía SSH
|
|
||||||
|
|
||||||
## 
|
|
||||||
|
|
||||||
## Conectarse via SSH
|
|
||||||
|
|
||||||
Luego de obtener los datos necesarios para conectarnos a nuestra máquina, procedemos a hacerlo
|
|
||||||
|
|
||||||
```shell
|
|
||||||
ssh -i llaveBot.pem ubutnu@34.228.208.104
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Luego puede aparecer un mensaje como el siguiente donde solo debes de responder **yes**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Una vez conectado ya estás dentro de la máquina virtual, te aconsejamos la primera vez hacer una actualización de dependencias de Ubuntu con los siguientes comandos
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo apt-get update
|
|
||||||
```
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo apt-get upgrade
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Recuerda instalar Node 16 o superior
|
|
||||||
|
|
||||||
Puedes ver más a detalle los pasos de la instalacion en este [blog](https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-20-04-es)
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl -sL https://deb.nodesource.com/setup_18.x -o nodesource_setup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo bash nodesource_setup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo apt-get install -y nodejs
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Implementar el bot
|
|
||||||
|
|
||||||
Si tienes el código de tu chatbot en un repositorio, solo falta que clones el repo en el servidor y ejecutes `npm start`
|
|
||||||
|
|
||||||
Para escanear el **QR** puedes hacerlo vía WEB accediendo a la URL `http://[TU_IP_PUBLICA]:3000` en este ejemplo seria `http://34.228.208.10:3000`
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Firewall
|
|
||||||
|
|
||||||
Si no te abre la pagina web asegurate de tener el puerto abierto en tu firewall.
|
|
||||||
Ejemplo permitir el puerto **3000**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Escanear QR
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ejecutar en Producción
|
|
||||||
|
|
||||||
Debes ubicarte en el directorio donde tienes el codigo fuente de tu chatbot.
|
|
||||||
|
|
||||||
Independientemente de tu sistema operativo deberás ejecutar el chatbot con el comando atrevés de un sistema que mantenga el proceso en ejecución.
|
|
||||||
Recomendamos [Pm2](https://pm2.keymetrics.io/)
|
|
||||||
|
|
||||||
```shell
|
|
||||||
pm2 start app.js --name=bot1
|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
La consola de devolver un mensaje con una lista de procesos, en el ejemplo puedes observar, que tenemos un proceso llamado `bot1`
|
|
||||||
|
|
||||||
De esta manera ya puedes cerrar la terminal y tu bot seguirá en ejecución sin problema
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import Alert from '../../../../components/widgets/Alert'
|
|
||||||
import Navigation from '../../../../components/widgets/Navigation'
|
|
||||||
|
|
||||||
# Entorno Docker
|
|
||||||
|
|
||||||
Previamente, necesitas tener instalado Docker en tu servidor dependiendo del sistema operativo, los procesos cambian,
|
|
||||||
puedes encontrar toda la información oficial de docker en [este enlace.](https://docs.docker.com/get-docker/)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Dependiendo del proveedor que has elegido necesitaras una implementación de Docker específica, pero no te preocupes, ya que viene implementada automáticamente en un archivo llamado **Dockerfile**, también puedes ver los otros Dockerfile en el apartado de [plantillas.](https://github.com/codigoencasa/bot-whatsapp/tree/main/starters/apps)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Contruir imagen
|
|
||||||
|
|
||||||
Solo es necesario construir la imagen del docker lo puedes hacer con el siguiente comando
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker build . -t botwhatsapp:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
## Iniciar contenedor
|
|
||||||
|
|
||||||
Para iniciar el contenedor con la imagen previamente construida puedes realizarlo ejecutando el siguiente comando.
|
|
||||||
Se utiliza el puerto **3001** solo com un ejemplo puedes usar el puerto que tu quieras
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker run -e PORT=3001 -p 3001:3001 botwhatsapp:latest
|
|
||||||
```
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import Alert from '../../../../components/widgets/Alert'
|
|
||||||
import Navigation from '../../../../components/widgets/Navigation'
|
|
||||||
|
|
||||||
# Entorno Local
|
|
||||||
|
|
||||||
Si deseas tener tu chatbot en ejecución en un servidor local (computadora personal, etc.) esta, guía te ayudará.
|
|
||||||
El servidor local deberá cumplir con los requisitos mínimos, puedes ver en [este enlace.](/docs/requirements)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<Alert>Si deseas instalar pm2 puedes ejecutar `npm install pm2 --global`</Alert>
|
|
||||||
|
|
||||||
Debes ubicarte en el directorio donde tienes el codigo fuente de tu chatbot.
|
|
||||||
|
|
||||||
Independientemente de tu sistema operativo deberás ejecutar el chatbot con el comando atrevés de un sistema que mantenga el proceso en ejecución.
|
|
||||||
Recomendamos [Pm2](https://pm2.keymetrics.io/)
|
|
||||||
|
|
||||||
```shell
|
|
||||||
pm2 start app.js --name=bot1
|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
La consola de devolver un mensaje con una lista de procesos, en el ejemplo puedes observar, que tenemos un proceso llamado `bot1`
|
|
||||||
|
|
||||||
De esta manera ya puedes cerrar la terminal y tu bot seguirá en ejecución sin problema
|
|
||||||
@@ -22,7 +22,12 @@ Tan sencillo como decir **palabra/s clave** y **mensaje a responder**
|
|||||||
Ambos metodos **[addKeyword](https://github.com/codigoencasa/bot-whatsapp/blob/dev/packages/bot/io/methods/addKeyword.js)** y el **[addAnswer](https://github.com/codigoencasa/bot-whatsapp/blob/dev/packages/bot/io/methods/addAnswer.js)** tienen una serie opciones disponibles
|
Ambos metodos **[addKeyword](https://github.com/codigoencasa/bot-whatsapp/blob/dev/packages/bot/io/methods/addKeyword.js)** y el **[addAnswer](https://github.com/codigoencasa/bot-whatsapp/blob/dev/packages/bot/io/methods/addAnswer.js)** tienen una serie opciones disponibles
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const { createBot, createProvider, createFlow, addKeyword } = require('@bot-whatsapp/bot')
|
const {
|
||||||
|
createBot,
|
||||||
|
createProvider,
|
||||||
|
createFlow,
|
||||||
|
addKeyword,
|
||||||
|
} = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
const flowPrincipal = addKeyword(['hola', 'alo'])
|
const flowPrincipal = addKeyword(['hola', 'alo'])
|
||||||
.addAnswer(['Hola, bienvenido a mi tienda', '¿Como puedo ayudarte?'])
|
.addAnswer(['Hola, bienvenido a mi tienda', '¿Como puedo ayudarte?'])
|
||||||
@@ -34,10 +39,11 @@ const flowPrincipal = addKeyword(['hola', 'alo'])
|
|||||||
## Provider (Proveedor)
|
## Provider (Proveedor)
|
||||||
|
|
||||||
<Alert>
|
<Alert>
|
||||||
⚡ Dependiendo del tipo de proveedor que utlices puede que necesites pasar algunas configuracion adicional como
|
⚡ Dependiendo del tipo de proveedor que utlices puede que necesites pasar
|
||||||
**token, api, etc.** para esos casos te recomendamos guiarte de los
|
algunas configuracion adicional como **token, api, etc.** para esos casos te
|
||||||
**[starters](https://github.com/codigoencasa/bot-whatsapp/tree/dev/starters/apps)** o si gustas puedes editar esta
|
recomendamos guiarte de los
|
||||||
documentación para ir agregando más info
|
**[starters](https://github.com/codigoencasa/bot-whatsapp/tree/dev/starters/apps)**
|
||||||
|
o si gustas puedes editar esta documentación para ir agregando más info
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
Es la pieza que conectara tu flujo con Whatsapp. En este chatbot tenemos varios proveedores disponibles la mayoria gratis pero tambien tenemos integracion la api oficial de whatsapp o twilio
|
Es la pieza que conectara tu flujo con Whatsapp. En este chatbot tenemos varios proveedores disponibles la mayoria gratis pero tambien tenemos integracion la api oficial de whatsapp o twilio
|
||||||
@@ -65,10 +71,11 @@ Los proveedores disponibles hasta el momento son los siguientes:
|
|||||||
## DataBase (Base de datos)
|
## DataBase (Base de datos)
|
||||||
|
|
||||||
<Alert>
|
<Alert>
|
||||||
⚡ Dependiendo del tipo de conector que utlices puede que necesites pasar algunas configuracion adicional como
|
⚡ Dependiendo del tipo de conector que utlices puede que necesites pasar
|
||||||
**user, host, password** para esos casos te recomendamos guiarte de los
|
algunas configuracion adicional como **user, host, password** para esos
|
||||||
**[starters](https://github.com/codigoencasa/bot-whatsapp/tree/dev/starters/apps)** o si gustas puedes editar esta
|
casos te recomendamos guiarte de los
|
||||||
documentación para ir agregando más info
|
**[starters](https://github.com/codigoencasa/bot-whatsapp/tree/dev/starters/apps)**
|
||||||
|
o si gustas puedes editar esta documentación para ir agregando más info
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
Es la pieza encargada de mantener el **"estado"** de una conversación, para mayor facilidad la libreria te proporcia diferentes conectores que se de adapten mejor a tu desarrollo
|
Es la pieza encargada de mantener el **"estado"** de una conversación, para mayor facilidad la libreria te proporcia diferentes conectores que se de adapten mejor a tu desarrollo
|
||||||
|
|||||||
@@ -5,7 +5,12 @@ import Navigation from '../../../components/widgets/Navigation'
|
|||||||
Si copias y pegas este codigo y tu entorno de trabajo cumple con todos los requesitos te debe funcionar abajo explico muy por encima
|
Si copias y pegas este codigo y tu entorno de trabajo cumple con todos los requesitos te debe funcionar abajo explico muy por encima
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const { createBot, createProvider, createFlow, addKeyword } = require('@bot-whatsapp/bot')
|
const {
|
||||||
|
createBot,
|
||||||
|
createProvider,
|
||||||
|
createFlow,
|
||||||
|
addKeyword,
|
||||||
|
} = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
|
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
|
||||||
const MockAdapter = require('@bot-whatsapp/database/mock')
|
const MockAdapter = require('@bot-whatsapp/database/mock')
|
||||||
@@ -37,7 +42,12 @@ main()
|
|||||||
En esta parte solo estamos declaramos las dependencias que vamos a utilizar. Si quieres saber a fondo cada una de las funciones te recomiendo pasarte por la seccion de **[conceptos](/docs/concepts)**
|
En esta parte solo estamos declaramos las dependencias que vamos a utilizar. Si quieres saber a fondo cada una de las funciones te recomiendo pasarte por la seccion de **[conceptos](/docs/concepts)**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const { createBot, createProvider, createFlow, addKeyword } = require('@bot-whatsapp/bot')
|
const {
|
||||||
|
createBot,
|
||||||
|
createProvider,
|
||||||
|
createFlow,
|
||||||
|
addKeyword,
|
||||||
|
} = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
|
const WebWhatsappProvider = require('@bot-whatsapp/provider/web-whatsapp')
|
||||||
const MockAdapter = require('@bot-whatsapp/database/mock')
|
const MockAdapter = require('@bot-whatsapp/database/mock')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Navigation from '../../../components/widgets/Navigation'
|
import Navigation from '../../../components/widgets/Navigation'
|
||||||
|
|
||||||
# Flow
|
# Flow (Flujos)
|
||||||
|
|
||||||
Los flujos hace referencia al hecho de construir un flujo de conversion. Esto es un flow podemos observar que estan presente dos metodos importantes **addKeyword** y el **addAnswer**.
|
Los flujos hace referencia al hecho de construir un flujo de conversion. Esto es un flow podemos observar que estan presente dos metodos importantes **addKeyword** y el **addAnswer**.
|
||||||
|
|
||||||
@@ -9,7 +9,12 @@ Tan sencillo como decir **palabra/s clave** y **mensaje a responder**
|
|||||||
Ambos metodos **[addKeyword](https://github.com/codigoencasa/bot-whatsapp/blob/dev/packages/bot/io/methods/addKeyword.js)** y el **[addAnswer](https://github.com/codigoencasa/bot-whatsapp/blob/dev/packages/bot/io/methods/addAnswer.js)** tienen una serie opciones disponibles
|
Ambos metodos **[addKeyword](https://github.com/codigoencasa/bot-whatsapp/blob/dev/packages/bot/io/methods/addKeyword.js)** y el **[addAnswer](https://github.com/codigoencasa/bot-whatsapp/blob/dev/packages/bot/io/methods/addAnswer.js)** tienen una serie opciones disponibles
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const { createBot, createProvider, createFlow, addKeyword } = require('@bot-whatsapp/bot')
|
const {
|
||||||
|
createBot,
|
||||||
|
createProvider,
|
||||||
|
createFlow,
|
||||||
|
addKeyword,
|
||||||
|
} = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
const flowPrincipal = addKeyword(['hola', 'alo'])
|
const flowPrincipal = addKeyword(['hola', 'alo'])
|
||||||
.addAnswer(['Hola, bienvenido a mi tienda', '¿Como puedo ayudarte?'])
|
.addAnswer(['Hola, bienvenido a mi tienda', '¿Como puedo ayudarte?'])
|
||||||
@@ -18,206 +23,6 @@ const flowPrincipal = addKeyword(['hola', 'alo'])
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## blackList
|
|
||||||
|
|
||||||
Éste argumento se utiliza para **evitar que el bot se active** cuando los números de la lista activen el bot.
|
|
||||||
Es importante que el número **vaya acompañado de su prefijo**, en el caso de España "34".
|
|
||||||
|
|
||||||
```js
|
|
||||||
createBot(
|
|
||||||
{
|
|
||||||
flow: adapterFlow,
|
|
||||||
provider: adapterProvider,
|
|
||||||
database: adapterDB,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
blackList: ['34XXXXXXXXX', '34XXXXXXXXX', '34XXXXXXXXX', '34XXXXXXXXX'],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## addKeyword()
|
|
||||||
|
|
||||||
Esta funcion se utliza para iniciar un flujo de conversion. <br /> Recibe un `string` o un `array`
|
|
||||||
de string `['hola','buenas']`.
|
|
||||||
|
|
||||||
**Opciones**
|
|
||||||
|
|
||||||
- sensitive: Sensible a mayusculas y minusculas por defecto `false`
|
|
||||||
|
|
||||||
```js
|
|
||||||
const { addKeyword } = require('@bot-whatsapp/bot')
|
|
||||||
|
|
||||||
const flowString = addKeyword('hola')
|
|
||||||
|
|
||||||
const flowArray = addKeyword(['hola', 'alo'])
|
|
||||||
|
|
||||||
const flowSensitive = addKeyword(['hola', 'alo'], {
|
|
||||||
sensitive: true,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## addAnswer()
|
|
||||||
|
|
||||||
Esta funcion se utliza para responder un mensaje despues del `addKeyword()`
|
|
||||||
|
|
||||||
**Opciones**
|
|
||||||
|
|
||||||
- delay: 0 (milisegundos)
|
|
||||||
- media: url de imagen
|
|
||||||
- buttons: array `[{body:'Boton1'}, {body:'Boton2'}, {body:'Boton3'}]`
|
|
||||||
- capture: true (para esperar respuesta)
|
|
||||||
- child: Objecto tipo flujo o arra de flujos hijos
|
|
||||||
|
|
||||||
```js
|
|
||||||
const { addKeyword } = require('@bot-whatsapp/bot')
|
|
||||||
|
|
||||||
const flowString = addKeyword('hola').addAnswer('Este mensaje se enviara 1 segundo despues', {
|
|
||||||
delay: 1000,
|
|
||||||
})
|
|
||||||
|
|
||||||
const flowString = addKeyword('hola').addAnswer('Este mensaje envia una imagen', {
|
|
||||||
media: 'https://i.imgur.com/0HpzsEm.png',
|
|
||||||
})
|
|
||||||
|
|
||||||
const flowString = addKeyword('hola').addAnswer('Este mensaje envia tres botones', {
|
|
||||||
buttons: [{ body: 'Boton 1' }, { body: 'Boton 2' }, { body: 'Boton 3' }],
|
|
||||||
})
|
|
||||||
|
|
||||||
const flowString = addKeyword('hola').addAnswer('Este mensaje espera una respueta del usuario', {
|
|
||||||
capture: true,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ctx
|
|
||||||
|
|
||||||
Este argumento se utiliza para obtener el contexto de la conversación
|
|
||||||
|
|
||||||
```js
|
|
||||||
const { addKeyword } = require('@bot-whatsapp/bot')
|
|
||||||
|
|
||||||
const flowString = addKeyword('hola').addAnswer('Indica cual es tu email', null, (ctx) => {
|
|
||||||
console.log('👉 Informacion del contexto: ', ctx)
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## fallBack()
|
|
||||||
|
|
||||||
Esta funcion se utliza para volver a enviar el ultimo mensaje abajo un ejemplo.
|
|
||||||
En el ejemplo de abajo esperamos que el usuario ingrese un mensaje que contenga `@` sino contiene
|
|
||||||
se repetira el mensaje `Indica cual es tu email`
|
|
||||||
|
|
||||||
```js
|
|
||||||
const { addKeyword } = require('@bot-whatsapp/bot')
|
|
||||||
|
|
||||||
const flowString = addKeyword('hola').addAnswer('Indica cual es tu email', null, (ctx, { fallBack }) => {
|
|
||||||
if (!ctx.body.includes('@')) return fallBack()
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## flowDynamic()
|
|
||||||
|
|
||||||
Esta funcion se utliza para devolver mensajes dinamicos que pueden venir de una API o Base de datos.
|
|
||||||
La funcion recibe un array que debe contener la siguiente estrucutura:
|
|
||||||
|
|
||||||
`[{body:'Mensaje}, {body:'Mensaje2}]`
|
|
||||||
|
|
||||||
```js
|
|
||||||
const { addKeyword } = require('@bot-whatsapp/bot')
|
|
||||||
|
|
||||||
const flowString = addKeyword('hola')
|
|
||||||
.addAnswer('Indica cual es tu email', null, async (ctx, {flowDynamic}) => {
|
|
||||||
const mensajesDB = () => {
|
|
||||||
const categories = db.find(...)
|
|
||||||
const mapDatos = categories.map((c) => ({body:c.name}))
|
|
||||||
return mapDatos
|
|
||||||
}
|
|
||||||
await flowDynamic(mensajesDB())
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## endFlow()
|
|
||||||
|
|
||||||
Esta funcion se utliza para finalizar un flujo con dos o más addAnswer. Un ejemplo de uso sería registrar 3 datos de un usuario en 3 preguntas distinas y
|
|
||||||
que el usuario pueda finalizar por él mismo el flujo.
|
|
||||||
Como podrás comprobar en el ejemplo siguiente, se puede vincular flowDynamic y todas sus funciones; como por ejemplo botones.
|
|
||||||
|
|
||||||
```js
|
|
||||||
const flowFormulario = addKeyword(['Hola'])
|
|
||||||
.addAnswer(
|
|
||||||
['Hola!', 'Escriba su *Nombre* para generar su solicitud'],
|
|
||||||
{ capture: true, buttons: [{ body: '❌ Cancelar solicitud' }] },
|
|
||||||
async (ctx, { flowDynamic, endFlow }) => {
|
|
||||||
if (ctx.body == '❌ Cancelar solicitud') {
|
|
||||||
await flowDynamic([
|
|
||||||
{
|
|
||||||
body: '❌ *Su solicitud de cita ha sido cancelada* ❌',
|
|
||||||
buttons: [{ body: '⬅️ Volver al Inicio' }],
|
|
||||||
},
|
|
||||||
])
|
|
||||||
return endFlow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.addAnswer(
|
|
||||||
['También necesito tus dos apellidos'],
|
|
||||||
{ capture: true, buttons: [{ body: '❌ Cancelar solicitud' }] },
|
|
||||||
async (ctx, { flowDynamic, endFlow }) => {
|
|
||||||
if (ctx.body == '❌ Cancelar solicitud') {
|
|
||||||
await flowDynamic([
|
|
||||||
{
|
|
||||||
body: '❌ *Su solicitud de cita ha sido cancelada* ❌',
|
|
||||||
buttons: [{ body: '⬅️ Volver al Inicio' }],
|
|
||||||
},
|
|
||||||
])
|
|
||||||
return endFlow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.addAnswer(
|
|
||||||
['Dejeme su número de teléfono y le llamaré lo antes posible.'],
|
|
||||||
{ capture: true, buttons: [{ body: '❌ Cancelar solicitud' }] },
|
|
||||||
async (ctx, { flowDynamic, endFlow }) => {
|
|
||||||
if (ctx.body == '❌ Cancelar solicitud') {
|
|
||||||
await flowDynamic([
|
|
||||||
{
|
|
||||||
body: '❌ *Su solicitud de cita ha sido cancelada* ❌',
|
|
||||||
buttons: [{ body: '⬅️ Volver al Inicio' }],
|
|
||||||
},
|
|
||||||
])
|
|
||||||
return endFlow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# QRPortalWeb
|
|
||||||
|
|
||||||
Argumento para asignar nombre y puerto al BOT
|
|
||||||
|
|
||||||
```js
|
|
||||||
const BOTNAME = 'bot'
|
|
||||||
QRPortalWeb({ name: BOTNAME, port: 3005 })
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<Navigation
|
<Navigation
|
||||||
pages={[
|
pages={[
|
||||||
{ name: 'Conceptos', link: '/docs/essential' },
|
{ name: 'Conceptos', link: '/docs/essential' },
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import Navigation from '../../components/widgets/Navigation'
|
|||||||
# Introducción
|
# Introducción
|
||||||
|
|
||||||
<Alert>
|
<Alert>
|
||||||
**Atención** estás leyendo la documentación de la **versión v2** de esta librería, si vienes de la versión anterior
|
**Atención** estás leyendo la documentación de la **versión v2** de esta
|
||||||
te recomendamos pasarte por la sección de **[migración](/docs/migration/)** para que puedas disfrutar de las nuevas
|
librería, si vienes de la versión anterior te recomendamos pasarte por la
|
||||||
características.
|
sección de **[migración](/docs/migration/)** para que puedas disfrutar de
|
||||||
|
las nuevas características.
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
## ¿Qué es esto?
|
## ¿Qué es esto?
|
||||||
@@ -33,7 +34,10 @@ npm create bot-whatsapp@latest
|
|||||||
muted
|
muted
|
||||||
playsinline
|
playsinline
|
||||||
>
|
>
|
||||||
<source src="https://leifer-landing-page.s3.us-east-2.amazonaws.com/console.webm" type="video/webm" />
|
<source
|
||||||
|
src="https://leifer-landing-page.s3.us-east-2.amazonaws.com/console.webm"
|
||||||
|
type="video/webm"
|
||||||
|
/>
|
||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user