Conceptos básicos de la sesión en una Alexa Skill
Tags: alexa, alexaskills, skillsession, aws
Published: 2020-02-19 14:51:52

---
title: Conceptos básicos de la sesión en una Alexa Skill
published: true
date: 2020-02-05 18:54:06 UTC
tags: alexa,alexaskills,skill session,aws
canonical_url: https://www.kinisoftware.com/alexa-skill-session/
---

Estas últimas semanas estoy dedicando tiempo a crear un par de skills para Alexa que me están sirviendo para profundizar más y aprender temas nuevos. A partir de lo que aprendo elaboro un listado de posibles posts y los priorizo. Haciendo esto me he dado cuenta que hasta ahora no había hablado de algo esencial en una Alexa Skill y que sale mucho en errores de certificación: la `skill session`.

Aunque no tiene nada de complicado me viene bien contarlo aquí para luego enlazar otros temas: gestión del contexto, persistencia, recuperar información del usuario/dispositivo, contenido de una request/response, etc.

## Skill Session

### Request

Con la invocación de una skill por parte de un usuario se crea una `session` que viajará con la `request` al back. La estructura de esa `request` da para otro post pero veamos aquí la parte que corresponde a la `session`:

{% gist https://gist.github.com/kinisoftware/2cc07be64d6a553272889f595db98251.js %}

La info que tenemos en la `session` es:

- Un flag `new` que nos indica si estamos creando la sesión en esta petición, valor a `true`, o ya estaba abierta, valor a `false`.
- Un `sessionId` como identificador único de la sesión activa de un usuario. Es un valor consistente en cada petición siguiente con la sesión abierta.
- Un objeto `application` que contiene información sobre la skill que crea la sesión. De esta forma se pueden hacer comprobaciones en back que la petición viene de la skill que se espera. Si alojas el back en AWS Lambda y conectas la función con un `trigger` de Alexa para tu skill se hará ese check de forma automática.
- Un objeto `user` que tiene información sobre la cuenta que está usando la skill. Escribiré otro post sobre el uso del `user` y otro objeto en la request que es `persona`. Por el momento, como punto más importante, de aquí sacamos el `userId` que representa de forma única a la cuenta Amazon para la cual la skill está activa. Veremos el uso y otros detalles de este `userId` en otros posts.

El envío de la info de sesión va con cada request al back con la sesión abierta pero con el flag de `new` a `false`.

### Response

Una vez se procese la petición en el back se envía una `response` a Alexa. Uno de los parámetros de esa respuesta es el flag `shouldEndSession` de cuyo valor dependerá lo que pase a continuación:

`true` > La sesión finaliza de forma que la skill termina de ejecutarse. A partir de ahí cualquier petición la manejará Alexa. Cuidado con el cierre de sesión en skills con APL ya que la skill se cierra y si el usuario tenía que leer algo por pantalla no podrá. Es un defecto habitual que se detecta también en certificación.

`false` > Alexa queda a la espera de una respuesta manteniendo la sesión y el micrófono abiertos. Se pueden dar a su vez varias posibilidades:

- Si el usuario dice algo que corresponda a un `intent` de la skill se genera la `request` correspondiente hacía el back. En esa petición la sesión ya llevará el flag `new` a `false`.
- Si el usuario no dice nada en un tiempo determinado se cierra el micro. En el caso de que la `response` llevara un `reprompt` se vuelve a abrir el micro unos segundos más.
- Una vez que el usuario ya no responde más y se cierra el micro, es posible que la sesión quede abierta por un periodo corto de tiempo. Este es el caso en dispositivos con pantalla donde el usuario aún puede interactuar con la skill ya que la sesión se mantiene abierta por un rato con el micro cerrado. Para ello tendría que realizar la petición despertando primero a Alexa. Esta petición iría directa a la skill sin tener que invocarla. En el caso de otros dispositivos la sesión finalizaría.

`undefined/null` > Aquí el comportamiento depende del tipo de dispositivo o de la respuesta. En la [documentación oficial](https://developer.amazon.com/en-US/docs/alexa/echo-button-skills/keep-session-open.html) cuentan las variantes.

## La sesión y el proceso de certificación

Uno de los problemas más comunes que reportan en el proceso de certificación es el manejo incorrecto de la sesión de la skill. En concreto de la decisión que toma el desarrollador para dejar abierta o cerrar la sesión en la respuesta de un `Intent`.

Cuando estás creando las respuestas para el usuario debes pensar si tras esa interacción esperas otra a continuación. Por ejemplo, en el caso de mi skill de [Estrenos de Cine](https://www.amazon.es/Kinisoftware-Estrenos-de-cine/dp/B07MKCLZ62) tengo ambas situaciones:

- El usuario pregunta por los estrenos de esta semana y tengo respuesta de estrenos desde la API. Informo al usuario de las películas y, desde back, indico que quiero que se cierre la sesión luego. No espero otra interacción una vez que le he dado al usuario lo que pedía. 
- El usuario pregunta por los estrenos de esta semana pero la API no me retorna ninguno. Lo que hago en ese caso es mandarle al usuario una pregunta, ya que no tengo los estrenos, si quiere conocer la cartelera actual. O, aunque no se lo indique, también podría preguntar por otra fecha, no es una ejecución lineal. En este caso, en la respuesta de back, indico que quiero que la sesión se quede abierta.

En este código podemos ver ambos casos enviando un `shouldEndSession` en la respuesta:

{% gist https://gist.github.com/kinisoftware/eb3ddeeecf1cbcba9862cb2e0d28e785.js %}

Si por ejemplo hubiéramos cerrado la sesión en el segundo escenario, nos lo hubieran detectado como error en el proceso de certificación. Le estamos haciendo una pregunta al usuario pero luego cerramos la sesión, con lo cual la respuesta no la va a manejar la skill sino Alexa.

Esto también suele pasar cuando manejamos el `Intent` de `Amazon.HelpIntent` donde, habitualmente, lo que esperamos luego es una interacción por parte del usuario.

Igualmente saber cuándo dejar la sesión abierta o no, afecta mucho a la experiencia de usuario final. Podemos llegar a crear una skill que acabe siendo muy pesada esperando siempre respuestas a interacciones que se podrían finalizar de una sola vez.

Para skills con APL, como decía en la primera parte del post, hay que tener cuidado con cerrar la sesión desde el back. En mi skill de Estrenos de Cine estaba cerrando la sesión con la respuesta y esto producía que un usuario no pudiera leer los estrenos de cine por pantalla. Se cerraba la skill al terminar la salida de audio, mostrando el listado, pero se cerraba enseguida.

### SessionEndedRequest

Hay un tema que no había visto documentado en mis primeros procesos de certificación y que descubrí cuando me lo detectaron como fallo. No tenía contemplado una `SessionEndedRequest` a mi back.

Una `SessionEndedRequest` es una petición que Alexa hace al back de una skill para indicar que una sesión finalizó. Esta petición se produce si:

- El usuario dice utterances como "salir" o "quitar".
- El usuario no responde o dice algo que no corresponde a ningún `Intent` definido en el modelo.
- Se produce un error.

Como dato curioso, una respuesta a esta petición debe ser vacía:

{% gist https://gist.github.com/kinisoftware/bfacf122ee738065fade26bc085c3b66.js %}

Hay otras formas de manejar situaciones que envían esta request, como el `FallbackIntent` o registrar un `ErrorHandler` y lo veremos en otro post.

_Nota_: si es la skill, indicado por back, quien decide finalizar la sesión con el flag `shouldEndSession` a `true` no habrá esa `SessionEndedRequest`.

* * *

Un punto que no comento, porque no se ve en la sesión de ejemplo que pongo arriba, es el tema de los atributos de sesión. Ese será mi siguiente post y el motivo inicial de haber escrito este primero :)