Crear un Alexa Skill

En este tutorial crearemos un Alexa Skill, pero nuestro principal objetivo es explorar estas herramientas de AWS y familiarizarnos con su uso para poder elaboraro soluciones más complejas y determinar cómo podemos usarlas para nuestros fines.

Antes de comenzar vale la pena hacer una aclaración sobre la diferencia entre Alexa y Echo:

  • Alexa es el servicio de voz ubicado en la nube de Amazon disponible en los dispositivos de Amazon y dispositivos tercios con Alexa integrada.

  • Amazon Echo es un altavoz inteligente, es un dispositivo de hardware producido por Amazon.

Sucede a menudo que los usuarios utilizan el término alexa para referirse indiscriminadamente a ambas cosas, pero lo cierto es que tecnicamente son diferentes.

A lo anterior debemos agregar que Alexa está presente en muchos dispositivos de Amazon.

Luego de la aclaración anterior comenzaremos con el tutorial.

1. Crear un S3 bucket público

  • Ingresamos a la consola de AWS

  • Buscamos el servicio S3

  • Seleccionamos la opción create bucket

  • Asignamos un nombre válido para el nuevo bucket, un nombre que no haya sido usado para ningun otro bucket (recibiremos un mensaje de error si el nombre no fuera válido).

  • Seleccionamos la opción create

Posteriormente hacemos todo el contenido del bucket público, para ello seleccionamos nuestro bucket creado y hacemos click en el boton Edit public access settings

Validamos que todas las opciones no esten seleccionadas y hacemos click en save.

Escribimos el texto solicitado y hacemos click en confirm.

Entramos al bucket cerado, nos movemos a la pesataña properties y en la opción Bucket Policy, configuramos la siguiente política:

1
2
3
4
5
6
7
8
9
10
11
12
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "ARN here/*"
}
]
}

Es impotante cambiar la parte de “ARN here” por el ARN de nuestro bucket, posteriormente hacemos click en save y nuestra política será aplicada:

2. Explorar Amazon Polly

En este segmento del tutorial podremos explorar el servicio de Amazon Polly a nivel general, lo haremos creando un audio a partir de cierto texto, este audio será almacenado en S3, lo primero es buscar el servicio Amazon Polly :

Una vez dentro de la consola de Amazon Polly, hacemos click en Get Started:

Posteriormente nos encontraremos con un panel en el que podemos escribir texto que será leído según las configuraciones que hagamos, podemos por ejemplo configurar el idioma del texto y la persona que lo leerá, es decir, si esta persona leerá con un tono de voz masculino o femenino y el tono de voz de la persona en específico, incluso tenemos para el mismo idioma diferentes acentos, por ejemplo, yo incrusté cierto texto que será leído en español mexicano, con una voz femenina perteneciente a Mia.

Luego vamos a hacer click en synthesize to S3, para poder exportar el audio correspondiente a este texto en nuestro bucket de S3.

Al hacerlo nos desplegará una ventana en la que debemos ingresar el nombre de nuestro bucket.

Seleccionamos Synthesize y se creará una tarea para sintetizar el audio correspondiente al texto ingresado.

En la pestaña de S3 synthesis tasks podemos ver el estado de esta tarea para determinar si ya fue completada o no.

Al completar la tarea, tendremos este audio en el bucket que indicamos.

3. Crear una función Lambda

Buscamos el servicio AWS Lambda en la consola de aws.

Una vez en la consola de AWS Lambda, procedemos a crear una nueva función, es importante crear esta función en una region en donde Alexa trigger esté habilitado, yo lo haré en US East (N. Virginia). Esto puede verse en la esquina superior derecha de nuestra consola.

Luego de hacer click en Create function, encontraremos en el panel 3 opciones, Author from scratch, Use a blueprint y Browse serverless app repository, nosotros seleccionaremos esta última y buscaremos el repositorio alexa-skills-kit-nodejs-factskill.

Escogemos el respositorio y dejamos todas sus configuraciones con los valores por defecto, posteriormente hacemos click en deploy y esperamos hasta que termine el proceso de deploy de nuestra función:

Ingresamos a la función y vemos que ya cuenta con un alexa trigger, esto porque hicimos el deploy de la función en una región que lo soporta, en este caso N. Virginia.

En el código autogenerado por la función veremos que hay un set de oraciones aleatoreas, agregaré mi nombre en el listado, luego procedí a hacer click en Save, para guardar los cambios en la función.

Vamos a https://developer.amazon.com/ e ingresamos a Amazon Alexa:

Una vez registrados y dentro de nuestra cuenta, procedemos a buscar el Alexa Skills kit:

En la consola de Alexa, escogemos la opción Create Skill.

Luego de crearla nos da la opción de escoger un template, escogemos Fact Skill y continuamos:

Luego estaremos en el Alexa Development Console:

Vamos a la sección de invocations, asignamos un nombre a nuestra invocation, en este caso coloque el nombre Cloud Facts y seleccionamos la opción save model:

Regresamos a la consola de Lambda, a la función anteriormente creada e identificamos y copiamos el ARN de nuestra función:

Vamos de nuevo a Alexa Developer Console, a la sección Endpoint y configuramos el ARN de nuestra función, de tal manera que nuestro Alexa Skill apuntará a la fución Lambda anteriormente creada. Luego de agregar el ARN, seleccionamos Save Endpoints.

Vamos a la sección GetNewFactIntent, incresamos un nuevo fact, a cloud fact en este caso, luego agregamos este fact y seleccionamos Save Model para guardar el modelo. Y luego Build Model para construir nuestro modelo. Al finalizar el Build recibiremos una notificación.

Luego de terminar el Build, vamos a la sección Test, cambiamos el modo a Development e ingresamos la instrucción open cloud facts. Luego vamos a obtejer un fact de la función asociada. En este caso recibí el siguiente: Here’s your fact: A year on Mercury is just 88 days long. Con lo anterior tenemos que nuestra Alexa Skill funciona y que nuestra función lambda también lo hace.

Regresamos a la consola de Lambda y seleccionamos todos los facts del arreglo.

Los eliminamos, dejamos solamente nuestro nombre y guardamos los cambios haciendo click en el boton Save.

Vamos nuevamente a Alexa Developer Console e ingresamso open cloud facts.

Luego de ingresarlo el único resultado posible es nuestro nombre, pues eliminamos el resto de facts.

Ahora en lugar de usar mi nombre como Fact, usaremos el archio de audio generado anteriormente con Polly, para ello vamos a nuestro bucket, a nuestro archivo de audio y en sus propiedades de la pestaña Overview encontraremos el URL del file.

Vamos a la consola de Lambda y modificamos el fact, en lugar de ser nuestro nombre introducimos el URL de nuestro audio con el siguiente formato para indicar que se trata de un audio

1
'<audio src=\"https://s3.amazonaws.com/ericknavarropolly2019/c4c0a83c-3718-49b4-bb72-0ee529ddf95b.mp3\"/>'

Y hacemos click en Save.

Antes de ejecutar nuestro Skill, es importante que nos aseguremos de que el file en el bucket es público, para ello vamos a la consola de S3, seleccionamos nuestro bucket, seleccionamos nuestro archivo y seleccionamos la opción Make Public.

Posteriormente vamos a nuestro Skill, ingresamos la instrucción open cloud facts y obtendremos el audio configurado.

Con esto llegamos al final del tutorial, espero que esta introducción a Alexa Skills, les motive a seguir explorando estas herramientas de AWS.

Creación de un CloudFront distribution

En este tutorial se creará un CDN utilizando AWS CloudFront.

Para ello se utilizarán las siguientes tecnologías:

  • AWS CloudFront: Servicio CDN con el que serviremos nuestro contenido, es decir, nuestra página no será servida directamente de S3.

  • AWS S3: Almacenamiento en la nube en el que alojaremos nuestros recursos.

Lo primero es buscar el servicio S3 en la consola de AWS, una vez en la consola de S3, procedemos a crear un nuevo bucket, haciendo click en la opción Create Bucket.

En el asistente de creación del bucket:

  • Name and Region: Indicamos el nombre del bucket, en mi caso es 20190416-sydney-cloudfront-origin, este nombre debe ser único en todo el universo de buckets de AWS, puede que el nombre del bucket ya exista, si es ese el caso recibiremos un mensaje de error y tendremos que modificar el nombre del bucket, dejamos los valores por defecto para el resto de opciones. Además escogemos una región que geográficamente esté muy lejos de nosotros, en mi caso la región más alejada es la de Asia Pacific (Sydney).

  • Configure options: Dejamos los valores por defecto para estas opciones.

  • Set permissions: Nos aseguramos que las restricciones para asignar permisos publicos no estén chequeadas, estas opciones aparecen en la siguiente imagen encerradas en dos recuadros amarillos, podemos dejar las opciones de configuración por defecto.

  • Review: Validamos que toda la configuración realizada corresponda con lo que necesitamos y creamos el bucket.

Posteriormente procedemos a cargar una imagen en alta definición, haciendo click en el boton Upload, en mi caso cargué una fotografía de 4.3 MB.

Dentro del asistente nos aseguramos de hacer público el archivo cargado.

Continuamos con las siguientes fases del asistente dejando el resto de las configuraciones con sus valores por defecto.

Hacemos click en el nombre de la imagen recién cargada y en el Overview del objeto veremos la URL con la que podemos acceder a él.

Copiamos la URL y la pegamos en el navegador, veremos cómo la imagen carga lentamente, esto debido a que físicamente la región de Sydney está muy lejos de mí.

Procedemos a crear nuestro CDN, para ello buscamos el servicio CloudFront en la consola de AWS, una vez en la consola de CloudFront, hacemos click en el boton Create Distribution.

En la sección Web, hacemos click en el botón Get Started.

Configuramos como Origen el bucket que recientemente creamos en la región de Sydney.

Luego de seleccionar nuestro bucket para la opción Origin Domain Name, se asigna automáticamente un Origin ID, este es un nombre que nos permitirá identificar el origen dentro de la distribución.

Seleccionamos la opción Restrict Bucket Access: Yes, esto hará que nuestro bucket que inicialmente era público deje de serlo para que podamos acceder a los archivos del bucket solamente a través de nuestro CDN, de nuestra distribución de CloudFront.

Seleccionamos Origin Access Identity: Create a New Identity, esto creará un identificador que se usará para crear una política en S3 que permita a nuestro CDN acceder a los recursos de S3, que ya no serán públicos debido a la configuración anterior.

Seleccionamos Grant Read Permissions on Bucket: Yes, Update Bucket Policy, esta opción actualizará la política de nuestro bucket y la cambiará para que deje de ser público y comience a ser solamente accesible para nuestro CDN.

En la configuración Viewer Protocol Policy, seleccionamos la opción Redirect HTTP to HTTPS, pues este el principal objetivo en este tutorial, servir la página con a través de HTTPS.

El resto de configuraciones las dejamos con sus valores por defecto y procedemos a hacer click en Create Distribution.

Al finalizar la creación, el status será Deployed y el state será Enabled.

Vamos a S3 y en las propiedades de la imagen cargada, en la sección Permissions, validamos que la imagen sea pública.

Vamos a CloudFront y hacemos click en el identificador de nuestro recién creado CDN, con esto accederemos a sus propiedades, una vez dentro copiamos el dominio del CDN.

Vamos un navegador e ingresamos el nombre dominio de la distribución recién creada, seguida de slash y el nombre de nuestra imagen. Veremos que nuestra imagen cargará lentamente la primera vez, pero si hacemos muchas veces Ctrl+F5. Veremos que solo la primera vez fue lenta, todas las demás cargo más rápido, esto porque la primera vez que se carga, la imagen queda guardada en la cache de nuestra distribución, en un Edge Location que físicamente está cerca de nosotros, mucho más cerca que la región de nuestro bucket (Sydney). Esta es una de las utilidades más importantes de CloudFront.

Por otro lado si cargamos nuestra imagen consultando directamente el bucket de S3, veremos que nuestra imagen cargará lentamente la primera vez, pero si hacemos muchas veces Ctrl+F5. Veremos que todas las veces la imagen carga lentamente, esto porque con cada solicitud, vamos a traer la imagen hasta la región de Sydney, que físicamente está lejos de nosotros.

Con esto llegamos al fin de nuestro tutorial, en el que claramente pudimos apreciar como el uso de una distribución o CDN tiene un impacto positivo en el performance cuando nuestra página o recursos web son consumidos desde muchos lugares diferentes a lo largo y ancho del mundo.

Construcción de un sitio serverless simple con Route 53, API Gateway, Lambda y S3

En este tutorial se creará un sitio serverless que consume una función Lambda sencilla.

Para ello se utilizarán las siguientes tecnologías:

  • AWS S3: Almacenamiento en la nube en el que alojaremos nuestro sitio estático.

  • AWS Route 53: DNS que resolverá el dominio personalizado que utilizaremos en nuestro sitio.

  • API Gateway: Servicio que actuará como “puerta delantera” para que las aplicaciones obtengan acceso a datos, lógica de negocio o funcionalidades desde sus servicios backend, en este caso, código ejecutado en AWS Lambda.

  • AWS Lambda: Servicio que permite ejecutar código sin aprovisionar ni administrar servidores. Solo pagará por el tiempo informático que consuma. No se cobra nada cuando el código no se está ejecutando.

1. Creación del bucket que almacenará nuestra página web

Abrimos la consola de S3.

Creamos un nuevo bucket, nos aseguramos de que el nombre sea válido (que no exista en todo el universo de S3, un bucket con ese nombre).

Nos aseguramos de remover las opciones que bloqueen la posibilidad de hacer el bucket público desmarcando estas restricciones.

Una vez creado nuestro bucket hacemos click sobre su nombre para acceder a sus configuraciones.

Nos dirigimos a la sección Static website hosting.

Configuramos como página principal index.html y como página de error error.html.

2. Creación nuestra función lambda

Abrimos la consola de AWS Lambda.

Creamos una nueva función con la opción Author from scratch.

Colocamos un nombre a la función y escogemos Python como lenguaje de la función, en el momento del tutorial, está disponible Python 3.6 por lo que escogeré este.

Incrustamos el código que devolverá la función, en este caso simplemente devuelve mi nombre.

Con esto finalizamos la creación de nuestra función.

3. Creación nuestro API Gateway

Dentro de la barra izquierda en el segmento Add triggers, encontraremos API Gateway, lo seleccionamos.

Seleccionamos el bloque recién creado.

En la parte inferior veremos que tenemos que configurar el API Gateway. Seleccionamos Create a new API, en este caso para fines de prueba la seguridad seleccionada sera Open, colocamos el nombre de nuestro API y en Deployment stage colocamos prod, que sería la abreviatura de producción.

Para el resto de configuraciones dejamos los valores por default.

Guardamos los cambios en nuestra función.

Al seleccionar el API y dirigirnos a la parte inferior veremos el API endpoint.

Siempre en la parte inferior hacemos click sobre el nombre de nuestro API Gateway, para poder llegar a sus configuraciones.

Seleccionamos el método ANY.

Eliminamos el método ANY.

Creamos un nuevo método.

El nuevo método será GET.

En las configuraciones del nuevo método, seleccionaremos Integration type: Lambda funcion, Use Lambda Proxy Integration: check. Nuestra Lambda region y el nombre de nuestra Lambda function.

Nos preguntará si queremos dar permisos al API para acceder a nuestra función lambda, seleccionamos que sí estamos de acuerdo.

Vamos nuevamente a acciones y seleccionamos Deploy API.

En Depoyment stage: prod nuevamente y colocamos una descripción relacionada con nuestro deploy.

Al finalizar nos indica un Invoke URL, que será utilizado para invocar la función.

Si colocamos el URL en un navegador estaremos invocando el método GET de nuestro API Gateway y se nos mostrará el resultado de la función, que era mi nombre.

Vamos al bucket que creamos index.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html>
<head>
<script>
function myFunction() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("my-demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "YOUR-API-GATEWAY-LINK-HERE", true);
xhttp.send();
}
</script>
</head>
<body>
<div align="center">
<br>
<br>
<br>
<br>
<h1>Hola <span id="my-demo">lectores</span></h1>
<button onclick="myFunction()">Haz click</button>
</div>
</body>
</html>

Es importante que en index.html, reemplacemos YOUR-API-GATEWAY-LINK-HERE, por el enlace con el que invocamos a nuestra función lambda.

Y error.html.

1
2
3
4
5
6
<html>
<head></head>
<body>
<h1>¡Hemos tenido un problema!</h1>
</body>
</html>

Estos archivos se cargan con la opción Upload.

Cargamos directamente, sin modificar ninguna configuración, dejamos todos los valores por default.

Seleccionamos ambos archivos y los hacemos públicos.

Confirmamos que queremos hacer los archivos públicos.

Accedemos al endpoint de nuestra página.

Se nos mostrará el saludo por defecto.

Luego de hacer click en el botón se cambiará el saludo con mi nombre, que es el valor que devuelve nuestra función Lambda.

4. Personalizar el dominio de nuestra página

Para personalizar el dominio de nuestra página debemos ir a la consola de Route 53.

En Route 53 podemos comprar un dominio o transferir un dominio.

Vamos a la sección Registered domains y podremos ver nuestro dominio.

Vamos a la sección Hosted zones y hacemos click en el nombre de nuestro dominio para acceder a su configuración.

Hacemos click en Create Record Set para asociar nuestro nombre de dominio a con nuestro sitio web.

Creamos un record set de tipo A, escogemos la opción Alias y configuramos como Alias Target el nombre de nuestro S3 bucket.

Procedemos a crear el Record Set.

Con esto tenemos creado nuestro Record Set.

Si ingresamos nuestro dominio en el navegador se desplegará nuestra página.

Hacemos click y vemos que la función opera correctamente.

Con esto hemos llegado al final de nuestro tutorial.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×