You are currently viewing Dialogflow 15 – Esperando a que se complete un proceso

Dialogflow 15 – Esperando a que se complete un proceso

Hola,

Me han pedido resolver este tema un par de veces, así que lo voy a dejar en un post.

La idea es que para algunos procesos de back-end, puede que necesites que tu agente de Dialogflow espere durante un tiempo “prolongado” hasta que ese proceso termine para que puedas responder al usuario. Un ejemplo sería hacer la reserva en un sistema de reserva de hoteles … si el proceso tarda más de 5 segundos, que es el tiempo máximo que puede tardar en responder un fulfillment de Dialogflow, necesitarías manejar una espera “prolongada” en tu agente.

En agentes de voz las esperas no son la mejor experiencia de usuario; recomendaría mantener algún tipo de interacción, poner algo de música, hacer un cuestionario … tu decides, pero definitivamente es algo a lo que prestar atención. Para agentes de texto el tema probablemente es menos crítico.

Bien, digamos que tienes una función llamada “transactionIsFinished” que verifica si tu proceso ha terminado o no. Con el siguiente código podemos crear un fulfillment que espera unos cuantos segundos (recuerda que el máximo es 5 incluyendo el tiempo de ejecución de la función):

Para hacer que esto funcione vamos a necesitar varios intents:

  1. Primero uno que lance la espera; en un escenario real sería la petición que lanza ese proceso de back-end “lento”. Es mi ejemplo solo vamos a decir que queremos esperar, lo he llamado waitStart, y lanza el código de arriba.
  2. Un intent al que llamar cuanto tenemos que esperar más. Se llama waitMore, y pregunta al usuario si quiere seguir esperando.
  3. 2 intents con las respuestas Si o No a la pregunta anterior.
  4. Un intent para terminar el flujo una vez el proceso ha terminado.

Como puedes ver en el código tanto waitMore como waitReturnAfterFinished serán llamados mediante eventos (como explicamos aquí) desde el fulfillment de espera. El intent waitMore tiene esta pinta:

El usuario responderá con un Si o No, que serán capturados por los correspondientes intents, que tienen acotado su ámbito de ejecución por un Contexto (más info sobre contextos aquí):

El intent No termina el flujo, y el de Si lo que hace es volver al llamar al código de fulfillment anterior, para lo que necesitaremos un mapeo doble:

Con esto ya lo tenemos todo listo para que el usuario espere todo lo que quiera hasta que la transacción se complete.

Saludos,

Jamarmu

============================================================

Trabajo para Google Cloud, pero este artículo son ideas y opiniones personales

Esta públicación tiene 11 comentarios

  1. Nicolas

    Amigo muy buenos blogs de dialogflow! Los leí prácticamente todos, lo único que te recomendaría constructivamente es que dejes el código entero del fullfilment escrito al final porque algunas cosas quedan como cortadas y no se entiende como hiciste o de donde las sacaste! Si puedes actualizar eso seria excelente! Saludos

    1. jamarmu

      Gracias por tus comentarios Nicolas!

      Si tienes dudas con algún ejemplo en particular escríbeme un email y lo vemos, me temo que el código no está en condiciones de ser publicado 😀

      Saludos,

      Jamarmu

  2. German

    Javier quería felicitarte por tus blogs, no he encontrado muchos ejemplos del uso del fullfilment y tus blogs me han ayudado en este aspecto, muchas gracias por ello!
    También decirte que aunque la mayoría se entiende bien también te recomendaría si puedes poner más imágenes o más código.
    Y por ultimo, y si no es molestia, aprovecho para preguntarte si es posible enviar un mensaje cuando el bot olvida el contexto? ( es para los casos en que las personas demoren en responder para que cuando responda no de error porque se termino el contexto).
    También quería saber si es posible que, en ciertos puntos, el bot a los 5 minutos de la ultima respuesta envíe una pregunta para saber si el cliente “necesita algo más” ? (obvio que esta pregunta no se tendría que enviar si la conversación termina, que en mi caso se termina con un intent despedida)
    Te agradezco nuevamente y te mando saludos desde Uruguay!!

    1. jamarmu

      Gracias German,

      Tomo nota de los del código … intentaré ser más detallado, pero como he comentado en alguna ocasión no pongo el código completo para evitar problemas de calidad si alguien decide reusar estos ejemplos tal cual.

      Respecto a lo que preguntas de olvidar el contexto, la clave aquí es el session ID que mantiene la covensarción, y que tiene un timeout de 20 minutos, tras lo que se pierde la info de contextos y parámetros capturados.

      Se podría solucionar guardando esta info en una base de datos externa y luego recuperando esa información, si es que puedes identificar al usuario.

      Lo que no se puede hacer es mandar mensajes desde Dialogflow; la herramienta responde a peticiones, pero no genera interacciones sola. Esto se podría implementar en el cliente que se usa para conectar al Dialogflow, si por ejemplo es una app que estás desarrollando para teléfono, pero si llamas a Dialogflow desde Assistant, Slack, o similar, no vas a poder hacerlo.

      Saludos,

      Javier

      1. German

        Claro, lo entiendo.
        Bien, muchas gracias por las respuestas!
        No, de momento no lo tengo conectado a ninguna base o app externa, esta directamente integrado con menssegger de facebook. La pregunta surgía porque pensé que, al igual que en tu ejemplo que se espera unos segundos, era posible poner una especie de temporizador en forma de función o promesa, que cuente 5 minutos y pasados esos minutos dispare un evento con setFollowupEvent para enviar la pregunta o para dar como terminada la charla antes de que se termine la sesión. Básicamente era para enviar un mensaje de fin de sesión o de despedida antes que pasen los 20 minutos y así evitar que las personas respondan algo cuando el bot ya perdió el contexto.
        Bueno estaré atento a las respuestas o futuros blogs! (tal vez surja alguna idea con respecto a esto o la solución de algún otro problema jaja)
        Realmente muchas gracias por la ayuda y saludos!!

  3. Juan Montano

    Hola Javier, Excelente tus blogs me han ayudado bastante en el mundo de Dialogflow.
    Te quería hacer una consulta es posible utilizar los FollowupEvents cuando estoy utilizando servicios Web que se demoran mas de 5 segundos en responder? Me podrías ayudar con una guía o recomendación de como se podría hacer?

    1. jamarmu

      Hola,

      Si, efectivamente puedes montar un proceso de espera llamando a eventos. A ver si saco un rato y lo documento.

      La otra posibilidad, especialmente si tu agente es de texto, es que gestiones esa espera, o el chequear si un proceso ha terminado, desde el cliente de chat que llama al agente o algún elemento de proxy intermedio si es que lo tienes.

      Saludos,

      Javier

      1. Juan Montano

        Hola Javier, cuando te refieres a chequear si el proceso ha terminado, como se haria ese proceso si estoy manejando funciones que invocan el consumo de WebService con Fetch?

        1. jamarmu

          Hola,

          Tienes que definir alguna función que devuelva si el proceso ha terminado o no y hacer algo como esto:

          function waitStart(agent) {
          console.log(“Waiting function … sleeping for 3 secs”);
          agent.add(“We have to wait a few seconds for your transaction”);
          return sleep(“3000”)
          .then( test_trans => { if ( transactionIsFinished() ) {
          agent.setFollowupEvent(“ReturnAfterWait”);
          } else {
          agent.setFollowupEvent(“WaitMore”);
          }}
          );
          }

          En este caso transactionIsFinished() es la función que me dice si mi operación ha terminado, y por tanto termino el bucle de espera.

          Necesitarás un par de intents que capturen los eventos de esperar y de terminar.

          Saludos,

          Jamarmu

          1. Juan Montano

            Hola Javier,
            Cuando se hace el llamado de los FollowupEvent, debo llamar nuevamente la función waitStart al hacer el mapeo de los Intents. En ese caso, cada vez que se llama se ejecuta nuevamente la funcion? o hay alguna forma que no se llame nuevamente sino que mantenga en memoria la ejecución?

          2. jamarmu

            Hola,

            Tendrías que llamar a esa o a otra función, lo que prefieras, pero si, cada vez es una ejecución independiente.

            Saludos,

            Javier

Deja una respuesta