Los chatbots, las interfaces conversacionales, que empezaron a estar de moda hace un par de años resultan muy divertidos, pero no siempre son útiles. Requiere bastante esfuerzo diseñar una conversación teniendo en cuenta todas las opciones de respuesta que pueden plantear los usuarios. Pero: ¿es necesario controlar todas las posibles entradas para realizar una tarea de negocio? En la mayoría de las aplicaciones, la respuesta es un rotundo “no”. Si así fuese, no se basarían la mayoría de apps en formularios para recoger datos con los que hacer algo.
Microsoft nos provee, dentro del Bot Framework, de un modo sencillo de modelar pequeñas funcionalidades de negocio que antes resolveríamos con un simple formulario. FormFlow es un motor que, a partir de un modelo de datos, es capaz de automatizar una conversación para recuperar toda la información necesaria para completar el modelo y que así podamos hacer lo que queramos con los datos.
Gracias a él, podemos aprovechar la omnipresencia (por estar en muchos canales en los que ya están presentes los usuarios) de un chatbot para estar más cerca de nuestro público objetivo.
Vamos a ver a continuación como podemos desplegar un chatbot sencillo en Azure. Veréis que el uso de FormFlow es tan sencillo que ni siquiera necesitaremos abrir Visual Studio para codificarlo. ¡Va a ser cosa de magia! En concreto, vamos a hacer un simulador del Sombrero Seleccionador de Howarts que decidía, en las historias de J. K. Rowling, a que casa iban los alumnos de la escuela de magia.
Es un ejemplo muy sencillo, pero completo, que nos servirá de base para afrontar cualquier aplicación sencilla que se base en la recopilación de un conjunto de los datos con los que después hacer algo, ya sea realizar unos cálculos (como es nuestro caso, pero podría ser el de calcular las condiciones de una hipoteca, o el precio que se aplicaría en tu seguro de coche), llamar a una API (por ejemplo para grabar la solicitud de esa hipoteca, o la petición de la llamada de un comercial de seguros), o cualquier otra cosa que se nos ocurra.
Como la mayoría del bot está basado en la definición de un modelo de datos será una tarea sencilla por muy complejo que lo queramos hacer, ya que la magia ya está codificada por Microsoft en las tripas de FormFlow.
Lo primero que tenemos que hacer, es crear en Azure un nuevo bot (Web App Bot). Para facilitarnos el trabajo, vamos a partir de un bot de ejemplo, por lo que a la hora de crear la aplicación le diremos que use la plantilla de FormFlow.
Una vez desplegado, tendremos dos elementos con el mismo nombre, una Web App y el Web App Bot propiamente dicho. En el Web App Bot una de las opciones es editar el código online (dentro del menú Build), que es lo que usaremos para editar el código de nuestro bot, ya que su sencillez no requiere montar un proyecto complejo o utilizar toda la potencia de Visual Studio.
Dado que los bots que utilizan FormFlow se basan en un modelo, lo primero que tenemos que hacer será definir este. Nuestro Sombrero Seleccionador no es tan mágico como el de Howarts, el nuestro recopila distinta información sobre los alumnos para tomar una decisión de a qué casa mandarles.
Las variables del modelo pueden ser de tipos básicos (los distintos tipos de enteros, los distintos tipos de números de coma flotantes, strings, DateTime, enumeraciones) y listas de enumeraciones. En nuestro caso, inicialmente, hemos usado sólo enumeraciones porque los valores que vamos a manejar son muy específicos de nuestro negocio.
1 public enum Nombres { Godric, Helga, Rowena, Salazar }; public enum Cualidades { Valentía, Honestidad, Inteligencia, Ambición }; public enum Colores { Rojo, Amarillo, Azul, Verde }; public enum ColoresDeJoyas { Oro, Negro, Bronce, Plata }; public enum Animales { Leon, Tejon, Aguila, Serpiente }; public enum LugaresParaVivir { TorreOscura, Bodega, TorreLuminosa, Mazmorras }; public enum Titulos { Sir, Fraile, Dama, Barón }; public enum Amigos { Ron, Neville, Hermione, Harry }; public enum Accesorios { Espada, Copa, Diadema, Guardapelo } [Serializable] public class SortingTest { public Nombres? Nombre; public Cualidades? Cualidad; public Colores? Color; public ColoresDeJoyas? ColorDeJoyas; public Animales? Animal; public LugaresParaVivir? LugarParaVivir; public Titulos? Titulo; public Amigos? Amigo; public Accesorios? Accesorio;23 public static IForm<SortingTest> BuildForm() { OnCompletionAsyncDelegate<SortingTest> evaluate = async (context, state) => { await context.PostAsync(“OK”); };return new FormBuilder<SortingTest>() .Message(“Hola”) .OnCompletion(evaluate) .Build(); } };4
Si ahora decidiéramos manejar nueva información como el nombre o la fecha de nacimiento, tan sólo tendríamos que añadir nuevas propiedades a nuestra clase modelo para almacenar estos datos, que posteriormente el bot se encargará de recoger y validar.
1 public string TuNombre;23 public DateTime? FechaDeNacimiento;4
Una vez que tenemos nuestra clase definida, solo la tendremos que añadir a nuestro proyecto creando un archivo online, y aprovecharemos a eliminar el modelo del ejemplo de la plantilla que no encaja para nada con nuestro mundo mágico.
Además, tendremos que hacer unos cambios menores en el controlador para que use nuestro nuevo modelo en lugar del que hemos eliminado. Para esto editaremos el archivo MessagesController.cs y cambiaremos las referencias al modelo en el método MakeRootDialog.
1 internal static IDialog<SortingTest> MakeRootDialog()2 {3 return Chain.From(() => FormDialog.FromForm(SortingTest.BuildForm));4 }5
A partir de aquí ya podemos compilar (build.cmd) y probar nuestro bot. En el componente del Web App Bot tenemos una opción para testear nuestro bot con un web client sin salir del portal de Azure. En cuanto le hablemos, nos responderá y podremos ver cómo nos hace preguntas para rellenar nuestro modelo.
Una vez que ya estamos capturando los datos, sólo tenemos que procesarlos, para eso cambiaremos el código de BuildForm dentro de nuestro SortingTest a nuestro gusto. Si lo probamos, veremos que ya lo tenemos todo funcionando. Sin embargo, no queda muy bien que si nuestro bot está pensado para público castellano parlante le hable en inglés. FormFlow está pensado para localizarlo a distintos idiomas, pero en nuestro caso solo cambiaremos un par de detalles usando atributos sobre nuestro modelo.
Hay atributos para distintas cosas como por ejemplo para marcar qué campos son opcionales o introducir nuestras propias validaciones. Nosotros usaremos un atributo de plantilla para modificar la pregunta que se hace por cada campo.
1 [Template(TemplateUsage.EnumSelectOne, "Elige un {&} {||}", ChoiceStyle = ChoiceStyleOptions.Auto)]2
Hay un lenguaje completo para editar el formato de los mensajes. En nuestro caso los caracteres "&" representan el nombre del campo y los caracteres "||" las distintas opciones que tendrá el usuario. La enumeración ChoiceStyleOptions nos permite indicar cómo se mostrarán estas opciones.
Si volvemos a probar veremos que ya queda mucho más aparente, pero no queda del todo bien ya que, por ejemplo, la propiedad Cualidad es femenina y al no haber planteado una pregunta neutra se hace raro el resultado. Pasa lo mismo con las propiedades de tipo string y DateTime, para las que no hemos cambiado su plantilla. Podemos usar un atributo similar al anterior pero que se aplica sólo sobre una propiedad para cambiar estos casos concretos.
1 [Prompt("Elige una cualidad {||}")]2
FormFlow tiene más capacidades, pero con esto hemos podido hacer un poco de "magia de informático" en unos pocos minutos, para tener algo funcional y aparente. Tan sólo nos queda elegir uno o varios canales en los que publicarlo para empezar a llegar a nuestro público objetivo justo en el canal en el que ya están trabajando a diario. Por ejemplo, si queréis saber qué opina de vosotros nuestro Sombrero Seleccionador, sólo tendréis que visitar mi web en javilopezg.com/SortingHat y charlar con él.
Javi López G. mail@javilopezg.com @javilopezg https://javilopezg.com