diff --git a/__test__/0.1.7-case.test.js b/__test__/0.1.7-case.test.js index 8688aedb2..de889a28d 100644 --- a/__test__/0.1.7-case.test.js +++ b/__test__/0.1.7-case.test.js @@ -29,8 +29,8 @@ suiteCase(`Debe retornar un mensaje resumen`, async ({ database, provider }) => }, async (ctx, { flowDynamic, state }) => { await state.update({ age: ctx.body }) - const myState = state.getMyState() - await flowDynamic(`Gracias por tu edad! ${myState.name}`) + const name = state.get('name') + await flowDynamic(`Gracias por tu edad! ${name}`) } ) .addAnswer(MOCK_VALUES[2], null, async (_, { flowDynamic, state }) => { @@ -98,4 +98,95 @@ suiteCase(`Debe retornar un mensaje resumen`, async ({ database, provider }) => assert.is(undefined, getHistory[18]) }) +suiteCase(`Manejando globalState`, async ({ database, provider }) => { + const MOCK_VALUES = ['¿Cual es tu nombre?', '¿Cual es tu edad?', 'Tu datos son:'] + + const flujoPrincipal = addKeyword(['hola']) + .addAnswer( + MOCK_VALUES[0], + { + capture: true, + }, + async (ctx, { flowDynamic, state, globalState }) => { + await state.update({ name: ctx.body }) + await globalState.update({ value: 'Soy el valor global' }) + await flowDynamic('Gracias por tu nombre!') + } + ) + .addAnswer( + MOCK_VALUES[1], + { + capture: true, + }, + async (ctx, { flowDynamic, state }) => { + await state.update({ age: ctx.body }) + const name = state.get('name') + await flowDynamic(`Gracias por tu edad! ${name}`) + } + ) + .addAnswer(MOCK_VALUES[2], null, async (_, { flowDynamic, state, globalState }) => { + const myState = state.getMyState() + const value = globalState.get('value') + await flowDynamic(`Nombre: ${myState.name} Edad: ${myState.age} Valor Global: ${value}`) + }) + .addAnswer('🤖🤖 Gracias por tu participacion') + + createBot({ + database, + flow: createFlow([flujoPrincipal]), + provider, + }) + + await provider.delaySendMessage(0, 'message', { + from: '000', + body: 'hola', + }) + + await provider.delaySendMessage(5, 'message', { + from: '001', + body: 'hola', + }) + + await provider.delaySendMessage(10, 'message', { + from: '000', + body: 'Leifer', + }) + + await provider.delaySendMessage(15, 'message', { + from: '000', + body: '90', + }) + + await provider.delaySendMessage(20, 'message', { + from: '001', + body: 'Maria', + }) + + await provider.delaySendMessage(25, 'message', { + from: '001', + body: '100', + }) + + await delay(1000) + const getHistory = database.listHistory.map((i) => i.answer) + assert.is(MOCK_VALUES[0], getHistory[0]) + assert.is('¿Cual es tu nombre?', getHistory[1]) + assert.is('Leifer', getHistory[2]) + assert.is('Gracias por tu nombre!', getHistory[3]) + assert.is('¿Cual es tu edad?', getHistory[4]) + assert.is('90', getHistory[5]) + assert.is('Gracias por tu edad! Leifer', getHistory[6]) + assert.is('Tu datos son:', getHistory[7]) + assert.is('Nombre: Leifer Edad: 90 Valor Global: Soy el valor global', getHistory[8]) + assert.is('🤖🤖 Gracias por tu participacion', getHistory[9]) + assert.is('Maria', getHistory[10]) + assert.is('Gracias por tu nombre!', getHistory[11]) + assert.is('¿Cual es tu edad?', getHistory[12]) + assert.is('100', getHistory[13]) + assert.is('Gracias por tu edad! Maria', getHistory[14]) + assert.is('Tu datos son:', getHistory[15]) + assert.is('Nombre: Maria Edad: 100 Valor Global: Soy el valor global', getHistory[16]) + assert.is('🤖🤖 Gracias por tu participacion', getHistory[17]) + assert.is(undefined, getHistory[18]) +}) suiteCase.run() diff --git a/__test__/0.2.0-case.test.js b/__test__/0.2.0-case.test.js index 4b73a0f33..5957389ee 100644 --- a/__test__/0.2.0-case.test.js +++ b/__test__/0.2.0-case.test.js @@ -13,16 +13,19 @@ suiteCase(`Encadenanos addAction con captures`, async ({ database, provider }) = .addAction(async (ctx, { flowDynamic }) => { await flowDynamic(`Hola! primer flow dynamic. respondeme algo`) }) - .addAction({ capture: true }, async (ctx, { flowDynamic }) => { - respuesta = ctx.body - await flowDynamic(`Esto me respondieste ${respuesta}`) + .addAction({ capture: true }, async (ctx, { flowDynamic, state }) => { + const reply = ctx.body + await state.update({ reply }) + await flowDynamic(`Esto me respondieste ${reply}`) }) .addAction(async (ctx, { flowDynamic }) => { await flowDynamic(`Hola! segundo flow dynamic. respondeme algo`) }) - .addAction({ capture: true }, async (ctx, { flowDynamic }) => { - respuesta = ctx.body - await flowDynamic(`Esto me respondieste ${respuesta}`) + .addAction({ capture: true }, async (ctx, { flowDynamic, state }) => { + const currentState = state.getMyState()?.reply + const reply = ctx.body + await state.update({ reply: currentState + ' ' + reply }) + await flowDynamic(`Esto me respondieste ${reply}`) }) .addAnswer('Chao') diff --git a/package.json b/package.json index e10417c44..4b0e38799 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "build": "pnpm run cli:rollup && pnpm run bot:rollup && pnpm run provider:rollup && pnpm run database:rollup && pnpm run contexts:rollup && pnpm run create-bot-whatsapp:rollup && pnpm run portal:rollup", "copy.lib": "node ./scripts/move.js", "test.unit": "node ./node_modules/uvu/bin.js packages test", - "test.e2e": "node ./node_modules/uvu/bin.js __test__ 0.2.1-case.test.js", + "test.e2e": "node ./node_modules/uvu/bin.js __test__", "test.coverage": "node ./node_modules/c8/bin/c8.js npm run test.unit", "test": "npm run test.coverage", "cli": "node ./packages/cli/bin/cli.js", diff --git a/packages/bot/context/globalState.class.js b/packages/bot/context/globalState.class.js index 75bc4909c..df7dde293 100644 --- a/packages/bot/context/globalState.class.js +++ b/packages/bot/context/globalState.class.js @@ -21,6 +21,9 @@ class GlobalState { return () => this.STATE.get('__global__') } + get = () => { + return (prop) => this.STATE.get('__global__')[prop] + } /** * * @returns diff --git a/packages/bot/context/state.class.js b/packages/bot/context/state.class.js index d724c8dae..93490ffcb 100644 --- a/packages/bot/context/state.class.js +++ b/packages/bot/context/state.class.js @@ -26,6 +26,15 @@ class SingleState { return () => this.STATE.get(from) } + /** + * + * @param {*} prop + * @returns + */ + get = (from) => { + return (prop) => this.STATE.get(from)[prop] + } + /** * * @returns diff --git a/packages/bot/core/core.class.js b/packages/bot/core/core.class.js index cf6a04b93..1d7a8d988 100644 --- a/packages/bot/core/core.class.js +++ b/packages/bot/core/core.class.js @@ -127,6 +127,7 @@ class CoreClass extends EventEmitter { // 📄 Mantener estado de conversacion por numero const state = { getMyState: this.stateHandler.getMyState(messageCtxInComming.from), + get: this.stateHandler.get(messageCtxInComming.from), getAllState: this.stateHandler.getAllState, update: this.stateHandler.updateState(messageCtxInComming), clear: this.stateHandler.clear(messageCtxInComming.from), @@ -135,6 +136,7 @@ class CoreClass extends EventEmitter { // 📄 Mantener estado global const globalState = { getMyState: this.globalStateHandler.getMyState(), + get: this.globalStateHandler.get(), getAllState: this.globalStateHandler.getAllState, update: this.globalStateHandler.updateState(messageCtxInComming), clear: this.globalStateHandler.clear(), diff --git a/packages/docs/public/videos/console.mp4 b/packages/docs/public/videos/console.mp4 new file mode 100644 index 000000000..f89dfba61 Binary files /dev/null and b/packages/docs/public/videos/console.mp4 differ diff --git a/packages/docs/public/videos/console.webm b/packages/docs/public/videos/console.webm new file mode 100644 index 000000000..4dc6acd40 Binary files /dev/null and b/packages/docs/public/videos/console.webm differ diff --git a/packages/docs/public/videos/xbmcc-kx99h.webm b/packages/docs/public/videos/xbmcc-kx99h.webm new file mode 100644 index 000000000..e73eb4496 Binary files /dev/null and b/packages/docs/public/videos/xbmcc-kx99h.webm differ diff --git a/packages/docs/src/components/widgets/CallToAction.tsx b/packages/docs/src/components/widgets/CallToAction.tsx index 1ca9b40a3..11a06b67f 100644 --- a/packages/docs/src/components/widgets/CallToAction.tsx +++ b/packages/docs/src/components/widgets/CallToAction.tsx @@ -21,12 +21,12 @@ export default component$(() => { playsInline > diff --git a/packages/docs/src/routes/docs/add-action/index.mdx b/packages/docs/src/routes/docs/add-action/index.mdx index bc5163693..212a5e261 100644 --- a/packages/docs/src/routes/docs/add-action/index.mdx +++ b/packages/docs/src/routes/docs/add-action/index.mdx @@ -2,10 +2,9 @@ import Navigation from '../../../components/widgets/Navigation' # addAction -Es una función útil para definir acciones que se activan cuando se recibe un mensaje de WhatsApp específico. -La función action puede realizar diversas tareas y acceder a los métodos y propiedades. En general, **addAction()** te permite crear Chat Bots de WhatsApp personalizados que pueden interactuar con los usuarios de una manera programática. -Puedes definir acciones específicas que se activan cuando se recibe un mensaje específico, lo que te permite crear una variedad de flujos de conversación y respuestas automatizadas. +El addAction es una función que se utiliza en la librería bot-whatsapp para definir acciones específicas en respuesta a los mensajes de WhatsApp recibidos. Esta función te permite crear flujos de conversación y definir cómo el bot debe responder a ciertos mensajes o palabras clave. +Aquí tienes un ejemplo de cómo se utiliza el addAction: ```js const { addKeyword } = require('@bot-whatsapp/bot') const flowPrincipal = addKeyword(['hola', 'alo']) @@ -27,10 +26,99 @@ const { addKeyword } = require('@bot-whatsapp/bot') return flowDynamic('Buenas! ¿Cual es tu nombre?') }) .addAction({ capture: true }, async (ctx, { flowDynamic, state }) => { - state.update({ name: ctx.body }) + await state.update({ name: ctx.body }) return flowDynamic(`Gracias por tu nombre!: ${ctx.body}`) }) .addAnswer('Chao!') +``` + +--- + +## Ejemplos + +En este ejemplo, hemos creado un flujo de conversación utilizando la palabra clave "hola" y "alo". + +Cuando el usuario envía un mensaje con alguna de estas palabras clave, el bot responde con un saludo. Luego, el bot captura el siguiente mensaje del usuario y lo muestra en la respuesta. + +Puedes agregar tantas acciones como desees en tu flujo de conversación, y cada acción puede tener su propia lógica y respuesta personalizada. + +Espero que esto te ayude a entender cómo utilizar el addAction en la creación de tu bot de WhatsApp. Si tienes alguna otra pregunta, no dudes en hacerla. + +```js +const { addKeyword } = require('@bot-whatsapp/bot') + +const flowPrincipal = addKeyword(['hola', 'alo']) + .addAction(async (_, { flowDynamic }) => { + return flowDynamic('¡Hola! ¿En qué puedo ayudarte?') + }) + .addAction({ capture: true }, async (ctx, { flowDynamic }) => { + const mensaje = ctx.body + return flowDynamic(`Has dicho: ${mensaje}`) + }) +``` + +--- + +En este ejemplo, hemos creado varios flujos de conversación utilizando la función addKeyword y la función addAction. Cada flujo se activará cuando se envíe un mensaje que contenga una palabra clave específica. Dentro de cada flujo, definimos acciones que se ejecutarán en respuesta al mensaje recibido. + +El flujo principal se activará cuando se envíe un mensaje que contenga las palabras clave "hola" o "alo". La acción asociada simplemente devuelve un mensaje de bienvenida. + +Los flujos de consulta de producto, soporte técnico y otras consultas se activarán cuando se envíen mensajes que contengan las palabras clave "producto", "soporte" y "consultas", respectivamente. Cada acción asociada devuelve un mensaje solicitando más información sobre el tema específico. + +El flujo de ayuda se activará cuando se envíe un mensaje que contenga la palabra clave "ayuda". La primera acción asociada devuelve un mensaje que enumera los temas de ayuda disponibles. La segunda acción, con la opción capture: true, captura la respuesta del usuario y la utiliza para determinar qué acción ejecutar a continuación. + +Finalmente, creamos el bot utilizando la función createBot y agregamos todos los flujos creados. Luego, iniciamos el bot con bot.start(). + +Este ejemplo muestra cómo utilizar addAction para definir acciones específicas en respuesta a mensajes de WhatsApp y cómo crear flujos de conversación utilizando addKeyword. Puedes adaptar este ejemplo a tus necesidades y agregar más flujos y acciones según sea necesario. + +```js +const { addKeyword } = require('@bot-whatsapp/bot'); + +// Crear flujo principal +const flowPrincipal = addKeyword(['hola', 'alo']) + .addAction(async (_, { flowDynamic }) => { + return flowDynamic('¡Hola! ¿En qué puedo ayudarte?'); + }); + +// Crear flujo de consulta de producto +const flowConsultaProducto = addKeyword(['producto']) + .addAction(async (_, { flowDynamic }) => { + return flowDynamic('Por favor, especifica qué producto te interesa.'); + }); + +// Crear flujo de soporte técnico +const flowSoporteTecnico = addKeyword(['soporte']) + .addAction(async (_, { flowDynamic }) => { + return flowDynamic('Por favor, describe el problema que estás experimentando.'); + }); + +// Crear flujo de otras consultas +const flowOtrasConsultas = addKeyword(['consultas']) + .addAction(async (_, { flowDynamic }) => { + return flowDynamic('Por favor, proporciona más detalles sobre tu consulta.'); + }); + +// Crear flujo de ayuda +const flowAyuda = addKeyword(['ayuda']) + .addAction(async (_, { flowDynamic }) => { + return flowDynamic('¡Estoy aquí para ayudarte! ¿Necesitas ayuda con alguno de los siguientes temas?:\n 1. Información de producto.\n 2. Soporte técnico.\n 3. Otras consultas.'); + }) + .addAction({ capture: true }, async (ctx, { flowDynamic }) => { + const opcion = parseInt(ctx.body); + switch (opcion) { + case 1: return flowDynamic('Especifica qué producto te interesa.'); + case 2: return flowDynamic('Describe el problema que tienes.'); + case 3: return flowDynamic('Proporciona más detalles sobre tu consulta.'); + } + }); + +// Crear bot y agregar flujos +const bot = createBot({ + flows: [flowPrincipal, flowConsultaProducto, flowSoporteTecnico, flowOtrasConsultas, flowAyuda], +}); + + + ``` --- diff --git a/packages/docs/src/routes/docs/add-answers/index.mdx b/packages/docs/src/routes/docs/add-answers/index.mdx index 54f44f12b..05cab8ddf 100644 --- a/packages/docs/src/routes/docs/add-answers/index.mdx +++ b/packages/docs/src/routes/docs/add-answers/index.mdx @@ -88,7 +88,6 @@ Dependiendo de tus sistema operativo asegurate de colocar bien la ruta absoluta media: 'c:/ruta/imagen.png', //'c:\ruta\imagen.png' }) - ``` --- @@ -121,6 +120,48 @@ En algunas ocaciones necesitamos esperar por la respuesta del usuario para ello ``` +--- + +### Ejemplos + +En este ejemplo, se crean dos flujos de conversación: uno para saludar al usuario cuando escribe "hola" y otro para despedirse cuando escribe "adios". + +Cada flujo tiene una respuesta predefinida que se mostrará al usuario. Puedes personalizar las respuestas según tus necesidades. + +```js + const { addKeyword } = require('@bot-whatsapp/bot') + + const flowSaludo = addKeyword('hola') + .addAnswer('¡Hola! ¿En qué puedo ayudarte?') + + const flowDespedida = addKeyword('adios') + .addAnswer('¡Hasta luego! Espero haberte sido de ayuda. ¡Vuelve pronto!') + +``` + +--- + +En este ejemplo, se crean dos flujos de conversación: uno para el saludo y otro para la despedida. + +Además, se agrega un flujo adicional para enviar una imagen cuando se recibe el mensaje 'imagen'. + +```js +const flowSaludo = addKeyword('hola').addAnswer('¡Hola! ¿En qué puedo ayudarte?'); +const flowDespedida = addKeyword('adios').addAnswer('¡Hasta luego! Espero haberte sido de ayuda.'); + +const flowImagen = addKeyword('imagen').addAnswer('¡Aquí tienes una imagen!', { media: 'https://ruta/a/imagen.jpg' }); + +const adapterFlow = createFlow([flowSaludo, flowDespedida, flowImagen]); + +const adapterProvider = createProvider(WebWhatsappProvider); +createBot({ + flow: adapterFlow, + provider: adapterProvider, + database: adapterDB, +}); + +``` + --- diff --git a/packages/docs/src/routes/docs/flow-dynamic/index.mdx b/packages/docs/src/routes/docs/flow-dynamic/index.mdx index 4094c8271..08f390828 100644 --- a/packages/docs/src/routes/docs/flow-dynamic/index.mdx +++ b/packages/docs/src/routes/docs/flow-dynamic/index.mdx @@ -41,11 +41,18 @@ const flowString = addKeyword('ver categorias') await flowDynamic(mapeoDeLista) - await flowDynamic({body:'Tambien puedes enviar un mensaje de esta manera'}) + await flowDynamic([ + {body:'Tambien puedes enviar un mensaje de esta manera'} + ]) // Enviar una imagen o pdf o etc - await flowDynamic({media:'https://i.imgur.com/0HpzsEm.png'}) + await flowDynamic([ + { + body:"soy una imagen", + media:'https://i.imgur.com/0HpzsEm.png' + } + ]) }) ``` diff --git a/packages/docs/src/routes/docs/index.mdx b/packages/docs/src/routes/docs/index.mdx index 9813ca5c6..c69f10243 100644 --- a/packages/docs/src/routes/docs/index.mdx +++ b/packages/docs/src/routes/docs/index.mdx @@ -24,7 +24,7 @@ npm create bot-whatsapp@latest muted playsinline > - + diff --git a/packages/docs/src/routes/docs/install/index.mdx b/packages/docs/src/routes/docs/install/index.mdx index 6157c6d6c..5c7df049c 100644 --- a/packages/docs/src/routes/docs/install/index.mdx +++ b/packages/docs/src/routes/docs/install/index.mdx @@ -28,7 +28,7 @@ El **CLI** te hace una revisión previa, de versión de Node y sistema operativo muted playsinline > - + diff --git a/packages/docs/src/routes/docs/provider-meta/index.mdx b/packages/docs/src/routes/docs/provider-meta/index.mdx index f2e3953d7..b0488bc5d 100644 --- a/packages/docs/src/routes/docs/provider-meta/index.mdx +++ b/packages/docs/src/routes/docs/provider-meta/index.mdx @@ -7,6 +7,36 @@ Más detalles de configuración puedes consultarlos [__aquí__](/docs/providers/ --- +### Configuracion inicial + +Referencia completa: [aqui](https://github.com/codigoencasa/bot-whatsapp/blob/main/starters/apps/base-meta-memory/app.js) + +```js +const MetaProvider = require('@bot-whatsapp/provider/meta') + +const main = async () => { + const adapterDB = new MockAdapter() + const adapterFlow = createFlow([flowPrincipal]) + + const adapterProvider = createProvider(MetaProvider, { + jwtToken: 'jwtToken', + numberId: 'numberId', + verifyToken: 'verifyToken', + version: 'v16.0', + }) + + createBot({ + flow: adapterFlow, + provider: adapterProvider, + database: adapterDB, + }) +} + +main() +``` + +--- + ### Enviar texto Te presentamos aquí un ejemplo de cómo puedes enviar un mensaje con Meta. @@ -32,16 +62,20 @@ const flowMensaje = addKeyword('hola') Aquí te mostramos un ejemplo de cómo puedes enviar archivos multimedia con Meta ```js -const flowMensaje = addKeyword('hola') - .addAnswer( - 'Aqui va un mensaje', +const flujoFinal = addKeyword('hola').addAnswer('Hola!', null, async (ctx, { flowDynamic}) => { + await flowDynamic([ { - capture: true, - }, - async (ctx, {provider}) => { - await sendMedia = async (ctx.from, 'mensaje', 'url de la media') + body:'imagen', + media:"https://i.imgur.com/1XEiIGq.png" } - ) + ]) + await flowDynamic([ + { + body:'video', + media:"https://bot-whatsapp.netlify.app/videos/console.mp4" + } + ]) +}) ``` --- diff --git a/packages/docs/src/routes/docs/state/index.mdx b/packages/docs/src/routes/docs/state/index.mdx index fcc397de2..b453b3240 100644 --- a/packages/docs/src/routes/docs/state/index.mdx +++ b/packages/docs/src/routes/docs/state/index.mdx @@ -14,7 +14,7 @@ Esto tambien funcion si usas `gotoFlow` capture: true, }, async (ctx, { flowDynamic, state }) => { - state.update({ name: ctx.body }) + await state.update({ name: ctx.body }) flowDynamic('Gracias por tu nombre!') } ) @@ -24,7 +24,7 @@ Esto tambien funcion si usas `gotoFlow` capture: true, }, async (ctx, { flowDynamic, state }) => { - state.update({ age: ctx.body }) + await state.update({ age: ctx.body }) const myState = state.getMyState() await flowDynamic(`Gracias por tu edad! ${myState.name}`) } @@ -37,6 +37,23 @@ Esto tambien funcion si usas `gotoFlow` ``` +## state.get('prop') + +De esta manera puedes recuperar el valor de una propiedad del estado + +```js +... + .addAnswer( + 'Tu edad es', + null, + async (ctx, { flowDynamic, state }) => { + const age = state.get('age') + await flowDynamic(`Edad: ${age}`) + } + ) +... +``` + ## GlobalState De igual manera que el `state` anterior nosotros podemos usar `globalState` para tener un esta general de la app (NO es por usuario), esto es muy util si quieres ejemplo apagar o prener el bot @@ -48,9 +65,9 @@ De igual manera que el `state` anterior nosotros podemos usar `globalState` para .addAction(async (_, { flowDynamic, globalState }) => { const currentGlobalState = globalState.getMyState(); if(currentGlobalState.encendido){ - globalState.update({encendido:false}) + await globalState.update({encendido:false}) }else{ - globalState.update({encendido:true}) + await globalState.update({encendido:true}) } }) .addAnswer('🤖🤖 Gracias por tu participacion') @@ -84,6 +101,58 @@ De igual manera que el `state` anterior nosotros podemos usar `globalState` para ``` +## globalState.get('prop') + +De esta manera puedes recuperar el valor de una propiedad del estado global + +```js +... + .addAnswer( + 'La version del bot es', + null, + async (ctx, { flowDynamic, globalState }) => { + const version = globalState.get('version') + await flowDynamic(`Version: ${version}`) + } + ) +... +``` + +## Ejemplos + +En este ejemplo, se utiliza el contexto para capturar y almacenar información proporcionada por el usuario en diferentes etapas del flujo de conversación. El método addAnswer se utiliza para hacer preguntas al usuario y capturar sus respuestas utilizando `{capture: true}`. Luego, se utiliza state.update para actualizar el estado con la información capturada. + +En la última respuesta, se utiliza state.get para obtener los valores almacenados en el estado y mostrarlos en la consola. Esto demuestra cómo se puede acceder a la información almacenada en el estado en diferentes partes del flujo de conversación. + +Recuerda que estos son solo ejemplos básicos y puedes adaptarlos según tus necesidades específicas. + +```js +const flujo = addKeyword(['hola']) + .addAnswer('¿Cual es tu nombre?', {capture: true}, async (ctx, { state }) => { + await state.update({ name: ctx.body }) + }) + .addAnswer('¿Cual es tu edad?', {capture: true}, async (ctx, { state }) => { + await state.update({ age: ctx.body }) + }) + .addAnswer('¿Prefieres inglés o español?', {capture: true}, async (ctx, { state }) => { + await state.update({ language: ctx.body }) + }) + .addAnswer('¿Cuál es tu comida favorita?', {capture: true}, async (ctx, { state }) => { + await state.update({ favoriteFood: ctx.body }) + }) + .addAnswer('¡Gracias por la información!',null, async ({ state }) => { + const name = state.get('name'); + const age = state.get('age'); + const language = state.get('language'); + const favoriteFood = state.get('favoriteFood'); + + console.log(`Nombre: ${name}`); + console.log(`Edad: ${age}`); + console.log(`Lenguaje preferido: ${language}`); + console.log(`Comida favorita: ${favoriteFood}`); + }); +``` + --- { + sendMedia = async (number, text = '', mediaInput) => { const fileDownloaded = await generalDownload(mediaInput) const mimeType = mime.lookup(fileDownloaded) - + mediaInput = fileDownloaded if (mimeType.includes('image')) return this.sendImage(number, mediaInput) if (mimeType.includes('video')) return this.sendVideo(number, fileDownloaded) if (mimeType.includes('audio')) { - const fileOpus = await convertAudio(fileDownloaded) + const fileOpus = await convertAudio(mediaInput) return this.sendAudio(number, fileOpus, text) } - return this.sendFile(number, fileDownloaded) + return this.sendFile(number, mediaInput) } /**