import Navigation from '../../../components/widgets/Navigation'

# 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**.

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

```js
const { createBot, createProvider, createFlow, addKeyword } = require('@bot-whatsapp/bot')

const flowPrincipal = addKeyword(['hola', 'alo'])
    .addAnswer(['Hola, bienvenido a mi tienda', '¿Como puedo ayudarte?'])
    .addAnswer(['Tengo:', 'Zapatos', 'Bolsos', 'etc ...'])
```

---

## 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
let nombre;
let apellidos;
let telefono;

const flowFormulario = addKeyword(['Hola','⬅️ Volver al Inicio'])
    .addAnswer(
        ['Hola!','Para enviar el formulario necesito unos datos...' ,'Escriba su *Nombre*'],
        { capture: true, buttons: [{ body: '❌ Cancelar solicitud' }] },

        async (ctx, { flowDynamic, endFlow }) => {
            if (ctx.body == '❌ Cancelar solicitud')
             return endFlow({body: '❌ Su solicitud ha sido cancelada ❌',    // Aquí terminamos el flow si la condicion se comple
                 buttons:[{body:'⬅️ Volver al Inicio' }]                      // Y además, añadimos un botón por si necesitas derivarlo a otro flow

            
            })
            nombre = ctx.body
            return flowDynamic(`Encantado *${nombre}*, continuamos...`)
        }
    )
    .addAnswer(
        ['También necesito tus dos apellidos'],
        { capture: true, buttons: [{ body: '❌ Cancelar solicitud' }] },

        async (ctx, { flowDynamic, endFlow }) => {
            if (ctx.body == '❌ Cancelar solicitud') 
                return endFlow({body: '❌ Su solicitud ha sido cancelada ❌',
                    buttons:[{body:'⬅️ Volver al Inicio' }]


        })
        apellidos = ctx.body
        return flowDynamic(`Perfecto *${nombre}*, por último...`)
        }
    )
    .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') 
                return endFlow({body: '❌ Su solicitud ha sido cancelada ❌',
                      buttons:[{body:'⬅️ Volver al Inicio' }]
                })


                telefono = ctx.body
                await delay(2000)
                return flowDynamic(`Estupendo *${nombre}*! te dejo el resumen de tu formulario
                \n- Nombre y apellidos: *${nombre} ${apellidos}*
                \n- Telefono: *${telefono}*`)
        }
    )

```

---

# QRPortalWeb

Argumento para asignar nombre y puerto al BOT

```js
const BOTNAME = 'bot'
QRPortalWeb({ name: BOTNAME, port: 3005 })
```

---

<Navigation
    pages={[
        { name: 'Conceptos', link: '/docs/essential' },
        { name: 'Proveedores', link: '/docs/providers' },
    ]}
/>
