Creando un custom skill para Alexa (VI): Manejando request con fechas
Con todo lo contado hasta ahora podríamos embarcarnos en el proceso de certificación del skill ya que tenemos algo básico y funcional. Pero, como dije en el anterior post, decidí manejar las request con fechas antes de enviarlo. No cubrir eso dejaba una experiencia muy pobre en mi opinión.
Caso de uso
Lo que yo quería soportar era el escenario en el cual un usuario pide los estrenos de cine para una fecha determinada. Algunas frases que me parecían básicas eran:
- "dime los estrenos de cine de esta semana"
- "dime las pelis de la próxima semana"
- "dime los estrenos de este mes"
De esta forma, sabiendo la fecha en la que el usuario estaba interesado, yo podría en la parte back filtrar los estrenos que cumplían ese criterio. Igualmente podría responder mejor ante la casuística de, por ejemplo, no tener estrenos para esa fecha o no haber entendido la fecha que me pedía.
Añadiendo un slot al interactor model
Un slot no es más que una información que puede variar en la petición de un usuario, en el utterance del intent, y que necesitamos conocer. En la documentación de Amazon podéis ver un ejemplo detallado.
Además de detectar la porción del utterance que es un slot, debemos asignarle un tipo. A la hora de elegir un tipo podemos:
- Elegir uno de los tipos predefinidos por Amazon. Estos tipos ya saben manejar ciertos valores de entrada, como fechas o palabras comunes en ciertos contextos como nombres de ciudades o tipos de comida. Los valores que aceptan estos tipos se pueden extender en algunos casos. La documentación oficial indica cuáles.
- Crear un type nuevo. En este tendríamos que darle un nombre al tipo y proveer de una lista de valores que debe manejar.
En este caso, ya que vamos a manejar fechas, opté por usar el built-in slot type para fechas: Amazon.DATE. De esta forma, Alexa convertirá la parte del utterance que hemos identificado con el slot en una fecha con formato ISO-8601. Es posible que no siempre sepa pasar lo que detecte a una fecha y, en ese caso, tendremos un bonito null
como valor del slot. Tenedlo en cuenta porque habrá que manejarlo en el server. Otra true story :)
Identificar el slot en el utterance
Para añadir un slot solo tenemos que identificar la parte del utterance que tendrá la información que necesitamos. Si aplicamos eso a las frases que usé como ejemplo arriba:
- "dime los estrenos de cine de esta semana" > slot = `esta semana`
- "dime las pelis de la próxima semana" > slot = `próxima semana`
- "dime los estrenos de este mes" > slot = `este mes`
Desde la Alexa Developer Console podemos hacer esta identificación del slot sobre los propios utterances de forma muy sencilla:
- Si ya tenemos utterances definidos, tan solo tendríamos que seleccionar la parte que queremos que sea un slot y crearlo dándole un nombre.
- Si metemos un utterance nuevo, podemos indicar directamente, igual que en el ejemplo anterior, la parte que corresponde a un slot.
En ambos casos se creará un slot en la tabla inferior de esa misma pantalla. En esa tabla podremos indicar el tipo del mismo, en este caso, Amazon.DATE.
Así mismo, en el panel lateral de la consola, aparecerá también el slot bajo el intent y el slot type que hemos empezado a usar en nuestro interactor model.
De esta forma, una vez identificado el slot en todos los utterances que lo vayan a contener, ya tendríamos listo el modelo básico para recibir fechas en nuestro intent principal.
Edición avanzada de un slot
A la hora de usar un slot en nuestro skill podremos editar algunos aspectos del type o el comportamiento del mismo en el intent.
Con respecto al type, como os dije antes, podemos añadir valores extra en algunos slots ya predefinido por Amazon. Con Amazon.DATE no se puede pero, por ejemplo, si usamos uno de tipo Amazon.FOOD sí sería posible.
Por otro lado, para el uso del slot por el intent, existen opciones a configurar. Para acceder a ellas solo tenemos que: o clickar en el nombre del slot bajo el intent (desplegable del interaction model), o sobre "Edit Dialog" en la tabla donde se registran los slots para un intent. En ambos casos se llega a la misma pantalla.
En mi caso no he tocado nada de las opciones que se muestran en la captura anterior y no voy a entrar en detalles. Quiero evolucionar el model e ir mejorando la interacción con el usuario y acabaré pasando por esta pantalla. La opción del "Slot Filling", por ejemplo, me podría resultar muy útil para cuando Alexa no consigue identificar el valor del slot (tengo que confirmar si serviría en ese caso). La opción de "Slot Confirmation", creo que sería meterle un paso innecesario aunque sí que podría, al devolver los resultados del back, repetir el valor del slot manejado al cliente al estilo: "Estos son los estrenos de cine para esta semana"
Manejando el slot en el back
Una vez hemos configurado el interaction model, cuando el usuario haga peticiones con frases como las anteriores, nos llegará al back el valor correspondiente.
El trozo de código que os muestro forma parte de la clase que maneja el intent principal de mi skill. He limitado el ejemplo a las líneas que se encargan de recuperar el valor del slot pero podéis consultar la clase entera aquí.
Cada request a un intent tiene acceso a un mapa de slots. Las entradas de los valores de ese mapa son los nombres de slot que se pusieron en el modelo. En mi caso es tan simple como coger el slot releasesDate
y recuperar su valor.
A partir del valor, dependiendo del tipo del slot, habría que hacer la lógica oportuna de interpretarlo. En el caso de Amazon.DATE, sabiendo el formato de la fecha que nos da Alexa, ya podríamos aplicar el formato que nosotros queramos y así comparar con el listado de películas.
El caso del valor null en el slot
Usando el slot type de Amazon.DATE me he encontrado con el caso de recibir en back un valor null
. En los logs del back vi que los usuarios hacían peticiones que Alexa no conseguía pasar a una fecha y, probando, fue bastante fácil de reproducir desde la Developer Console.
Si veis en el código, lo que hago en ese caso es preparar un texto de respuesta distinto donde informo al usuario que no he entendido la fecha que me pide y le incentivo a que vuelva a repetir la petición.
En caso de que tenga un valor de slot es cuestión de filtrar las películas y ofrecer la respuesta adecuada, ya sea porque hay estrenos que conozco o porque no tengo nada.
Una vez configurado nuestro slot podríamos hacer pruebas con las herramientas que mostraba en el post anterior. Una vez estemos satisfechos con el comportamiento, pasaríamos al proceso de certificación de nuestro skill. Os contaré eso junto con temas de analíticas y logging en el siguiente post :)