mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-19 12:09:15 +00:00
Merge pull request #477 from codigoencasa/fix/refactor-cb
Fix/refactor cb
This commit is contained in:
6
.github/workflows/releases.yml
vendored
6
.github/workflows/releases.yml
vendored
@@ -67,9 +67,13 @@ jobs:
|
|||||||
- name: Release Github
|
- name: Release Github
|
||||||
run: yarn node ./scripts/github.js --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.OCTO_TOKEN }}"
|
run: yarn node ./scripts/github.js --version="${{ steps.package-version.outputs.current-version}}" --token="${{ secrets.OCTO_TOKEN }}"
|
||||||
|
|
||||||
|
- name: 'Run if changes have been detected'
|
||||||
|
run: |
|
||||||
|
git add .
|
||||||
|
git commit -m "chore(version): pre release"
|
||||||
|
|
||||||
- name: Commit Versioning & Push changes
|
- name: Commit Versioning & Push changes
|
||||||
if: github.event_name == 'push'
|
if: github.event_name == 'push'
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
with:
|
with:
|
||||||
commit_message: 'chore(version): launch release 🚀 "${{ steps.package-version.outputs.current-version}}"'
|
commit_message: 'chore(version): launch release 🚀 "${{ steps.package-version.outputs.current-version}}"'
|
||||||
branch: dev
|
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||||
|
|
||||||
|
### [0.1.16](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.15...v0.1.16) (2023-01-11)
|
||||||
|
|
||||||
|
### [0.1.15](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.14...v0.1.15) (2023-01-11)
|
||||||
|
|
||||||
|
### [0.1.14](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.13...v0.1.14) (2023-01-11)
|
||||||
|
|
||||||
### [0.1.13](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.12...v0.1.13) (2023-01-11)
|
### [0.1.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.12](https://github.com/leifermendez/bot-whatsapp/compare/v0.1.10...v0.1.12) (2023-01-11)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@bot-whatsapp/root",
|
"name": "@bot-whatsapp/root",
|
||||||
"version": "0.1.13",
|
"version": "0.1.16",
|
||||||
"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,
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ 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
|
||||||
@@ -84,20 +87,40 @@ class CoreClass {
|
|||||||
this.databaseClass.save(ctxByNumber)
|
this.databaseClass.save(ctxByNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 📄 Esta funcion se encarga de enviar un array de mensajes dentro de este ctx
|
||||||
|
const sendFlow = async (messageToSend, numberOrId) => {
|
||||||
|
const queue = []
|
||||||
|
for (const ctxMessage of messageToSend) {
|
||||||
|
const delayMs = ctxMessage?.options?.delay || 0
|
||||||
|
if (delayMs) await delay(delayMs)
|
||||||
|
QueuePrincipal.enqueue(() =>
|
||||||
|
Promise.all([
|
||||||
|
this.sendProviderAndSave(numberOrId, ctxMessage),
|
||||||
|
resolveCbEveryCtx(ctxMessage),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return Promise.all(queue)
|
||||||
|
}
|
||||||
|
|
||||||
// 📄 [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje
|
// 📄 [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje
|
||||||
const fallBack = () => {
|
const fallBack = async () => {
|
||||||
fallBackFlag = true
|
fallBackFlag = true
|
||||||
msgToSend = this.flowClass.find(refToContinue?.keyword, true) || []
|
await this.sendProviderAndSave(from, refToContinue)
|
||||||
this.sendFlow(msgToSend, from)
|
QueuePrincipal.queue = []
|
||||||
return refToContinue
|
return refToContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 📄 [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 }) => {
|
const flowDynamic = async (
|
||||||
|
listMsg = [],
|
||||||
|
optListMsg = { limit: 5, fallback: false }
|
||||||
|
) => {
|
||||||
if (!Array.isArray(listMsg))
|
if (!Array.isArray(listMsg))
|
||||||
throw new Error('Esto debe ser un ARRAY')
|
throw new Error('Esto debe ser un ARRAY')
|
||||||
|
|
||||||
|
fallBackFlag = optListMsg.fallback
|
||||||
const parseListMsg = listMsg
|
const parseListMsg = listMsg
|
||||||
.map(({ body }, index) =>
|
.map(({ body }, index) =>
|
||||||
toCtx({
|
toCtx({
|
||||||
@@ -108,26 +131,38 @@ class CoreClass {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
.slice(0, optListMsg.limit)
|
.slice(0, optListMsg.limit)
|
||||||
msgToSend = parseListMsg
|
for (const msg of parseListMsg) {
|
||||||
this.sendFlow(msgToSend, from)
|
await this.sendProviderAndSave(from, msg)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback o fallback
|
||||||
|
const resolveCbEveryCtx = async (ctxMessage) => {
|
||||||
|
if (prevMsg?.options?.capture) return cbEveryCtx(prevMsg?.ref)
|
||||||
|
if (!ctxMessage?.options?.capture)
|
||||||
|
return await cbEveryCtx(ctxMessage?.ref)
|
||||||
|
}
|
||||||
|
|
||||||
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback y ejecutarlo
|
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback y ejecutarlo
|
||||||
const cbEveryCtx = (inRef) => {
|
const cbEveryCtx = async (inRef) => {
|
||||||
this.flowClass.allCallbacks[inRef](messageCtxInComming, {
|
if (!this.flowClass.allCallbacks[inRef]) return Promise.resolve()
|
||||||
|
return this.flowClass.allCallbacks[inRef](messageCtxInComming, {
|
||||||
fallBack,
|
fallBack,
|
||||||
flowDynamic,
|
flowDynamic,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prevMsg?.ref) resolveCbEveryCtx(prevMsg)
|
||||||
|
|
||||||
// 📄 [options: callback]: Si se tiene un callback se ejecuta
|
// 📄 [options: callback]: Si se tiene un callback se ejecuta
|
||||||
if (!fallBackFlag) {
|
//TODO AQUI
|
||||||
if (prevMsg?.options?.capture) cbEveryCtx(prevMsg?.ref)
|
// if (!fallBackFlag) {
|
||||||
for (const ite of this.flowClass.find(body)) {
|
// if (prevMsg?.options?.capture) cbEveryCtx(prevMsg?.ref)
|
||||||
if (!ite?.options?.capture) cbEveryCtx(ite?.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 (!fallBackFlag && prevMsg?.options?.nested?.length) {
|
if (!fallBackFlag && prevMsg?.options?.nested?.length) {
|
||||||
@@ -138,11 +173,12 @@ class CoreClass {
|
|||||||
|
|
||||||
msgToSend = this.flowClass.find(body, false, flowStandalone) || []
|
msgToSend = this.flowClass.find(body, false, flowStandalone) || []
|
||||||
|
|
||||||
for (const ite of msgToSend) {
|
// //TODO AQUI
|
||||||
cbEveryCtx(ite?.ref)
|
// for (const ite of msgToSend) {
|
||||||
}
|
// cbEveryCtx(ite?.ref)
|
||||||
|
// }
|
||||||
|
|
||||||
this.sendFlow(msgToSend, from)
|
sendFlow(msgToSend, from)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,13 +189,13 @@ class CoreClass {
|
|||||||
|
|
||||||
if (['string', 'boolean'].includes(typeCapture) && valueCapture) {
|
if (['string', 'boolean'].includes(typeCapture) && valueCapture) {
|
||||||
msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
|
msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
|
||||||
this.sendFlow(msgToSend, from)
|
sendFlow(msgToSend, from)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msgToSend = this.flowClass.find(body) || []
|
msgToSend = this.flowClass.find(body) || []
|
||||||
this.sendFlow(msgToSend, from)
|
sendFlow(msgToSend, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,18 +212,6 @@ class CoreClass {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
sendFlow = async (messageToSend, numberOrId) => {
|
|
||||||
const queue = []
|
|
||||||
for (const ctxMessage of messageToSend) {
|
|
||||||
const delayMs = ctxMessage?.options?.delay || 0
|
|
||||||
if (delayMs) await delay(delayMs)
|
|
||||||
Queue.enqueue(() =>
|
|
||||||
this.sendProviderAndSave(numberOrId, ctxMessage)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return Promise.all(queue)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {*} message
|
* @param {*} message
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ 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()],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
class Queue {
|
class Queue {
|
||||||
static queue = []
|
queue = []
|
||||||
static pendingPromise = false
|
pendingPromise = false
|
||||||
|
|
||||||
static enqueue(promise) {
|
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 {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static dequeue() {
|
dequeue() {
|
||||||
if (this.workingOnPromise) {
|
if (this.workingOnPromise) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Navigation from '../../../components/widgets/Navigation'
|
import Navigation from '../../../components/widgets/Navigation'
|
||||||
|
|
||||||
# Flow (Flujos)
|
# Flow
|
||||||
|
|
||||||
Los flujos hace referencia al hecho de construir un flujo de conversion. Esto es un flow podemos observar que estan presente dos metodos importantes **addKeyword** y el **addAnswer**.
|
Los flujos hace referencia al hecho de construir un flujo de conversion. Esto es un flow podemos observar que estan presente dos metodos importantes **addKeyword** y el **addAnswer**.
|
||||||
|
|
||||||
@@ -23,6 +23,142 @@ const flowPrincipal = addKeyword(['hola', 'alo'])
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## addKeyword()
|
||||||
|
|
||||||
|
Esta funcion se utliza para iniciar un flujo de conversion. <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: false (para esperar respuesta)
|
||||||
|
- child: Objecto tipo flujo o arra de flujos hijos
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { addKeyword } = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
|
const flowString = addKeyword('hola').addAnswer(
|
||||||
|
'Este mensaje se enviara 1 segundo despues',
|
||||||
|
{
|
||||||
|
delay: 1000,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const flowString = addKeyword('hola').addAnswer(
|
||||||
|
'Este mensaje envia una imagen',
|
||||||
|
{
|
||||||
|
media: 'https://i.imgur.com/0HpzsEm.png',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const flowString = addKeyword('hola').addAnswer(
|
||||||
|
'Este mensaje envia tres botones',
|
||||||
|
{
|
||||||
|
buttons: [
|
||||||
|
{ body: 'Boton 1' },
|
||||||
|
{ body: 'Boton 2' },
|
||||||
|
{ body: 'Boton 3' },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const flowString = addKeyword('hola').addAnswer(
|
||||||
|
'Este mensaje espera una respueta del usuario',
|
||||||
|
{
|
||||||
|
capture: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ctx
|
||||||
|
|
||||||
|
Este argumento se utiliza para obtener el contexto de la conversación
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { addKeyword } = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
|
const flowString = addKeyword('hola').addAnswer(
|
||||||
|
'Indica cual es tu email',
|
||||||
|
null,
|
||||||
|
(ctx) => {
|
||||||
|
console.log('👉 Informacion del contexto: ', ctx)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## fallBack()
|
||||||
|
|
||||||
|
Esta funcion se utliza para volver a enviar el ultimo mensaje abajo un ejemplo.
|
||||||
|
En el ejemplo de abajo esperamos que el usuario ingrese un mensaje que contenga `@` sino contiene
|
||||||
|
se repetira el mensaje `Indica cual es tu email`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { addKeyword } = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
|
const flowString = addKeyword('hola').addAnswer(
|
||||||
|
'Indica cual es tu email',
|
||||||
|
null,
|
||||||
|
(ctx, { fallBack }) => {
|
||||||
|
if (!ctx.body.includes('@')) return fallBack()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## flowDynamic()
|
||||||
|
|
||||||
|
Esta funcion se utliza para devolver mensajes dinamicos que pueden venir de una API o Base de datos.
|
||||||
|
La funcion recibe un array que debe contener la siguiente estrucutura:
|
||||||
|
|
||||||
|
`[{body:'Mensaje}, {body:'Mensaje2}]`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { addKeyword } = require('@bot-whatsapp/bot')
|
||||||
|
|
||||||
|
const flowString = addKeyword('hola')
|
||||||
|
.addAnswer('Indica cual es tu email', null, async (ctx, {flowDynamic}) => {
|
||||||
|
const mensajesDB = () => {
|
||||||
|
const categories = db.find(...)
|
||||||
|
const mapDatos = categories.map((c) => ({body:c.name}))
|
||||||
|
return mapDatos
|
||||||
|
}
|
||||||
|
await flowDynamic(mensajesDB())
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
<Navigation
|
<Navigation
|
||||||
pages={[
|
pages={[
|
||||||
{ name: 'Conceptos', link: '/docs/essential' },
|
{ name: 'Conceptos', link: '/docs/essential' },
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
FROM node:lts-bullseye as bot
|
FROM node:18-bullseye as bot
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm i
|
RUN npm i
|
||||||
COPY . .
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
ARG PORT
|
ARG PORT
|
||||||
CMD ["npm", "start"]
|
CMD ["npm", "start"]
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
FROM node:lts-bullseye as bot
|
FROM node:18-bullseye as bot
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm i
|
RUN npm i
|
||||||
COPY . .
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
ARG PORT
|
ARG PORT
|
||||||
CMD ["npm", "start"]
|
CMD ["npm", "start"]
|
||||||
|
|||||||
9
starters/apps/base-meta-json/Dockerfile
Normal file
9
starters/apps/base-meta-json/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:18-bullseye as bot
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm i
|
||||||
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
|
ARG PORT
|
||||||
|
CMD ["npm", "start"]
|
||||||
9
starters/apps/base-meta-memory/Dockerfile
Normal file
9
starters/apps/base-meta-memory/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:18-bullseye as bot
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm i
|
||||||
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
|
ARG PORT
|
||||||
|
CMD ["npm", "start"]
|
||||||
9
starters/apps/base-meta-mongo/Dockerfile
Normal file
9
starters/apps/base-meta-mongo/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:18-bullseye as bot
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm i
|
||||||
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
|
ARG PORT
|
||||||
|
CMD ["npm", "start"]
|
||||||
9
starters/apps/base-meta-mysql/Dockerfile
Normal file
9
starters/apps/base-meta-mysql/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:18-bullseye as bot
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm i
|
||||||
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
|
ARG PORT
|
||||||
|
CMD ["npm", "start"]
|
||||||
9
starters/apps/base-twilio-json/Dockerfile
Normal file
9
starters/apps/base-twilio-json/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:18-bullseye as bot
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm i
|
||||||
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
|
ARG PORT
|
||||||
|
CMD ["npm", "start"]
|
||||||
9
starters/apps/base-twilio-memory/Dockerfile
Normal file
9
starters/apps/base-twilio-memory/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:18-bullseye as bot
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm i
|
||||||
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
|
ARG PORT
|
||||||
|
CMD ["npm", "start"]
|
||||||
9
starters/apps/base-twilio-mongo/Dockerfile
Normal file
9
starters/apps/base-twilio-mongo/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:18-bullseye as bot
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm i
|
||||||
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
|
ARG PORT
|
||||||
|
CMD ["npm", "start"]
|
||||||
9
starters/apps/base-twilio-mysql/Dockerfile
Normal file
9
starters/apps/base-twilio-mysql/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:18-bullseye as bot
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm i
|
||||||
|
COPY . .
|
||||||
|
ARG RAILWAY_STATIC_URL
|
||||||
|
ARG PUBLIC_URL
|
||||||
|
ARG PORT
|
||||||
|
CMD ["npm", "start"]
|
||||||
Reference in New Issue
Block a user