Utiliza la Web API for Games de Alexa

Utiliza la Web API for Games de Alexa

Amazon acaba de anunciar que su nueva Web API for Games de Alexa está disponible. Ésta es una gran noticia, ya que permite desarrollar skills usando todo el potencial de las aplicaciones Web, tales como WebGL, WebAudio, CSS y Javascript, en la creación de juegos para Alexa.

¿Pero cómo se usa? A modo de demostración, les mostraré cómo crear un juego muy simple con esta API, paso a paso.

El juego

El juego consistirá en que se mostrarán en pantalla algunas formas geométricas, y tú deberás tocar la de color rojo. Como lo he dicho, ¡muy simple!

Las skills basadas en aplicaciones web consisten en dos partes que interactúan: la skill de Alexa propiamente dicha, y la aplicación web. La skill se encargará de administrar los comandos de voz, y la lógica del juego, mientras que la aplicación web mostrará las formas en pantalla y gestionará la interacción táctil.

Tu aplicación web

Tienes que tener en cuenta que, a diferencia de una skill “normal”, en que lo único que necesitas es alojar tu función lambda, aquí deberás también alojar tu aplicación web. Para ello necesitarás un servidor. Alexa requiere que las aplicaciones se sirvan con HTTPS, así que puedes utilizar cualquier servidor que posea un certificado válido. Ten en cuenta que, al momento de lanzar la aplicación web al dispositivo, la URL de la aplicación se muestra en pantalla por unos 8 segundos, junto con el ícono de la skill.

Para mantener las cosas sencillas utilizaremos un bucket S3 para alojar nuestra aplicación, que consistirá solamente un archivo html con el código javascript en el mismo archivo. También utilizaremos una librería para manejar el canvas, optamos por Konva (https://konvajs.org/), pero se puede usar prácticamente cualquier librería que desees.

Además, para que la aplicación web se pueda comunicar con la skill, debemos usar la “Alexa JavaScript API”, simplemente agregando en tu documento HMTL el siguiente script:

https://cdn.html.games.alexa.a2z.com/alexa-html/latest/alexa-html.js

Con lo que nuestra página web nos viene quedando de ésta manera:

<!doctype html>
<html>
<head>
    <title>Web API for Games</title>
    <style>
        body {
            margin: 0;
            color: white;
        }
        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <div id="container"></div>
    <script 
      src="https://cdn.html.games.alexa.a2z.com/alexa-html/latest/alexa-html.js">
    </script>
    <script src="https://unpkg.com/konva@7.0.3/konva.min.js">
    </script>
    <script>
        //aquí el código de la aplicación...
    </script>
</body>
</html>

Ahora es momento de agregar el código de la aplicación web, que por supuesto lo podemos escribir en el mismo archivo html, o en un archivo JS externo.

Lo primero que haremos es crear nuestro canvas, con tres objetos que necesitaremos: un cuadrado, un hexágono y un triángulo. Haremos esto utilizando la librería Konva que mencionamos anteriormente. Puedes ver toda la documentación, demos y tutoriales en este vínculo: https://konvajs.org/

const W = window.innerWidth
const H = window.innerHeight
//definimos el stage
const stage = new Konva.Stage({
    container: 'container',
    width: W,
    height: H
});
//y un layer, al cual le agregamos tres formas
let layer = new Konva.Layer();
stage.add(layer);

let shape1 = new Konva.RegularPolygon({
    x: W / 6,
    y: H / 2,
    sides: 4,
    radius: (H / 3),
    rotation: 45,
    fill: '',
    stroke: 'black',
    strokeWidth: 4,
    name: "cuadrado"
});
layer.add(shape1);

let shape2 = new Konva.RegularPolygon({
    x: W / 2,
    y: H / 2,
    sides: 6,
    radius: (H / 3),
    fill: '',
    stroke: 'black',
    strokeWidth: 4,
    name: "hexagono"
});

layer.add(shape2)

let shape3 = new Konva.RegularPolygon({
    x: 5 * W / 6,
    y: H / 2,
    sides: 3,
    radius: (H / 3),
    fill: '',
    stroke: 'black',
    strokeWidth: 4,
    name: "triangulo"
});
layer.add(shape3)
layer.draw();

Una vez que tenemos las formas definidas, declaramos una función y la asignamos como callback para cuando tocamos uno de los objetos en pantalla.

function shapeClickHandler(e) {
    //por ahora, la funcion solamente imprime el color de la forma que se ha tocado
    //esto lo modificaremos luego para que se comunique con la skill
    console.log(e.target.fill())
}

shape1.on('tap', shapeClickHandler)
shape2.on('tap', shapeClickHandler)
shape3.on('tap', shapeClickHandler)

Ahora, debemos crear el objeto Alexa con el API SDK, mediante la instrucción

var client; //declaramos un objeto para referenciar al cliente
Alexa.create({ version: '1.0' })
    .then((args) => {
        const {
            alexa,
            message
        } = args;
        //guardamos la referencia al cliente
        client = alexa
        //aquí inicializamos el cliente
    })
    .catch(error => {
        console.error('failed to initialize')
    });

Finalmente, debemos que configurar este objeto “cliente”, registrando los callbacks para los diversos eventos que puede manejar. Por ejemplo, puedes registrar funciones que se ejecuten cuando llega un mensaje, cuando el dispositivo comienza a hablar, cuando termina la locución, cuando se abre o cierra el micrófono o cuando el cliente finaliza la inicialización.

Nosotros declararemos solamente una función para manejar los mensajes que nos llegan de la skill, pintando las formas con los colores que nos indique la skill:

function processAlexaMessage(message) {
    if (message.intent == "SetColors") {
        shape1.fill(message.colors[0]);
        shape2.fill(message.colors[1])
        shape3.fill(message.colors[2])
        layer.draw()
    }
}

Llamaremos a esta funcion cuando llegue cualquier mensaje de la skill, aún el de inicialización de la aplicación. Para esto agregamos en la inicialización, con lo que nuestro código queda así:

Alexa.create({ version: '1.0' })
    .then((args) => {
        const {
            alexa,
            message
        } = args;
        //guardamos la referencia al cliente
        client = alexa
        //aquí inicializamos el cliente
        processAlexaMessage(message) //procesa el mensaje de inicialización
        //asigna la funcion como callback para los mensajes recibidos
        client.skill.onMessage(processAlexaMessage);
    })
    .catch(error => {
        console.error('failed to initialize')
    });

Finalmente, modificamos la funcion “shapeClickHandler”, para enviar a la skill los datos de la forma que se tocó en pantalla, de la siguiente manera:

function shapeClickHandler(e) {
    if (client != null) {
        client.skill.sendMessage({
            intent: "AnswerIntent",
            shape: e.target.getAttr('name'),
            color: e.target.fill()
        });
    }
}

Una vez que tenemos la aplicación web terminada, la subimos al bucket S3 (asegurándonos de darle permiso de lectura público), y anotamos la URL de dicho archivo.

Tu skill

Ahora es el turno de programar nuestra skill para que interactúe con la aplicación web que acabamos de desarrollar. No voy a documentar todo el código de la skill, ya que no deja de ser una skill como otras que ya sabes cómo desarrollar. Solamente mostraré los pasos necesarios para que la skill lance la aplicación web, envíe y responda los mensajes.

Antes que nada, necesitamos declarar que nuestra skill declare la nueva interfaz ALEXA_PRESENTATION_HTML. Esto se puede hacer desde la solapa “Interfaces” de la consola de desarrollo, activando “Alexa Web API for Games”, o, si utilizas la interfaz CLI, deberás modificar tu skill manifest (skill.json), agregando en el apartado “interfaces”, el objeto

{  
    "type": "ALEXA_PRESENTATION_HTML"
}

Para arrancar la aplicación web, enviaremos la directiva “Alexa.Presentation.HTML.Start” en el handler del LaunchRequest. En esta directiva indicaremos la URL completa de la aplicación web (que anotamos del bucket S3), y además enviaremos los colores iniciales para las formas

handlerInput.responseBuilder.addDirective({
    type: "Alexa.Presentation.HTML.Start",
    data: {
        "intent": "SetColors",
        "colors": ["green", "red", "blue"]
    },
    request: {
        uri: "https://mi-web-app.com/webapp.html",
        method: "GET"
    },
    configuration: {
        "timeoutInSeconds": 300
    }
});

Esto cargará la aplicación en el dispositivo. ¡Ya tienes tu aplicación corriendo!

La aplicación envía mensajes a la skill…

Cuando toques una forma en la pantalla, la aplicación web ejecutará la funcion “shapeClickHandler” y enviará un mensaje a la skill con un request de ésta forma:

{
    type: 'Alexa.Presentation.HTML.Message',
    requestId: 'amzn1.echo-api.request.21512c3b-18e4-4497-8275-f18e0c70c3b8',
    timestamp: '2020-07-24T16:32:18Z',
    locale: 'es-ES',
    message: {
        intent: "AnswerIntent",
        shape: "cuadrado",
        color: "green"
    }
}

Con lo que debemos declarar un handler para estos requests y actuar según lo que nos diga el mensaje:

AnswerIntentHandler: {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request
        return request.type === 'Alexa.Presentation.HTML.Message'
            && request.message.intent === 'AnswerIntent';
    },
    handle(handlerInput) {
        let speakOutput = ""
        if (handlerInput.requestEnvelope.request.message.color == "red") 
            speakOutput = "Correcto"
        else 
            speakOutput = "Lo siento";

        return handlerInput.responseBuilder
                .speak(speakOutput)
                .getResponse();
    }
}

…y la skill le responde a la aplicación.

Cuando la skill necesita comunicar un evento a la aplicación web, debe enviar una directiva “Alexa.Presentation.HTML.HandleMessage” con el mensaje apropiado.

Por ejemplo, si queremos que nuestra aplicación cambie los colores de las formas agregamos esta directiva antes de devolver la respuesta:

handlerInput.responseBuilder.addDirective({
    "type": "Alexa.Presentation.HTML.HandleMessage",
    "message": {
        "intent": "SetColors",
        "colors": ["red", "blue", "green"]
    }
})

Con lo que nuestro handler quedará así:

AnswerIntentHandler: {
    canHandle(handlerInput) { 
        const request = handlerInput.requestEnvelope.request
        return request.type === 'Alexa.Presentation.HTML.Message'
            && request.message.intent === 'AnswerIntent';
    },
    handle(handlerInput) {
        let speakOutput = ""
        if (handlerInput.requestEnvelope.request.message.color == "red") 
            speakOutput = "Correcto"
        else 
            speakOutput = "Lo siento";

        handlerInput.responseBuilder.addDirective({
            "type": "Alexa.Presentation.HTML.HandleMessage",
            "message": {
                "intent": "SetColors",
                "colors": ["red", "blue", "green"]
            }
        })

        return handlerInput.responseBuilder
                .speak(speakOutput)
                .getResponse();
    }
}

Entonces, declarando este request handler en el SkillBuilder de tu skill, ya podrás responder a los eventos que envíe tu aplicación web. A partir de aquí, puedes agregar eventos, mensajes y lógica a tu aplicación como quieras.

¿Cuándo se cierra la aplicación?

A diferencia de una skill normal, mientras está cargada la aplicación web en pantalla, la sesión quedará abierta, hasta que el usuario salga de la skill diciendo por ejemplo: “Alexa, salir”, o hasta que la skill envíe una directiva para una interfaz diferente de Alexa.Presentation.HTML (por ejemplo, si enviamos una pantalla APL para el dispositivo). En este último caso, se cerrará la aplicación web, pero no necesariamente la sesión de la skill, según el valor de shouldEndSession que contenga la respuesta.

¡No se puede hacer cualquier cosa!

En primer lugar, ¡tu skill debe ser un juego! Si no, no pasará la certificación.
No puedes enviar más de dos mensajes por segundo entre la aplicación web y la skill.
Si bien el dispositivo tiene grandes capacidades, no todas ellas están expuestas, y hay cosas que no podrás hacer:

  • utilizar geolocalización
  • utilizar la cámara o el micrófono
  • utilizar alert(), prompt() o confirm() en JavaScript
  • cargar un archivo local con urls de tipo file://
  • utilizar la API para contenido local
  • utilizar WebSQL
  • utilizar Local Storage
  • acceder a contenido HTTP (solamente se puede usar HTTPS)

Las cookies, datos de formulario y la historia solo están disponibles durante la directiva Start, luego se eliminan estos datos.

¡Sigue leyendo!

Aquí encontrarás toda la documentación relevante (en inglés):

Otros Posts

Integración vocal (hardware)

Integración vocal (hardware)

Explora nuestra guía rápida para crear tu propio asistente de voz. Descubre cómo configurar el hardware necesario, instalar y ajustar el software y poner a prueba tu nuevo sistema de interacción vocal. ¡Haz clic para aprender a integrar tecnologías de voz de manera local y privada en tu proyecto!

más...
Alexa, Feliz cumpleaños

Alexa, Feliz cumpleaños

¡Celebra el aniversario de Alexa en Español con nosotros! Desde 2018, hemos explorado el mercado hispanohablante, desarrollando decenas de skills. Descubre insights sobre el desarrollo de skills en España y México, y análisis de categorias y autores. ¡Accede al reporte y conoce más sobre el mundo de Alexa en Español!

más...
Las leyes del arquitecto frugal

Las leyes del arquitecto frugal

En un análisis de las leyes presentadas por Werner Vogels de AWS en el sitio 'The Frugal Architect', se desglosan conceptos clave sobre la integración del costo en la arquitectura de sistemas. Desde la consideración del costo como un requisito explícito hasta la promoción de una cultura de innovación constante, el análisis busca proporcionar una comprensión clara y equilibrada, dirigida tanto a profesionales del sector como a aquellos interesados en la tecnología. ¿Cómo pueden estas leyes, enfocadas en la eficiencia y la sostenibilidad económica, transformar la forma en que arquitectos y desarrolladores abordan sus proyectos?

más...
Búsqueda Semántica y Bases de Datos Vectoriales:

Búsqueda Semántica y Bases de Datos Vectoriales:

Exploramos cómo la búsqueda semántica y las bases de datos vectoriales están transformando la recuperación de información en la era digital, tecnologías que permiten una comprensión más profunda del contexto y la intención detrás de cada consulta, superando las limitaciones de las búsquedas basadas en palabras clave. Estas bases de datos mapean y recuperan información basándose en sus propiedades semánticas, facilitando una búsqueda más precisa y matizada. En Mindgeist, implementamos estas soluciones para transformar la gestión y búsqueda de conocimiento en algo más intuitivo y poderoso.

más...
David Mantecón

David Mantecón

David Mantecón, experto en diseño sonoro, suma más de 30 años creando paisajes sonoros y música electroacústica para cine, series y publicidad. Su estudio 'No Problem Sonido' combina creatividad con la última tecnología. Especialista en colocar el sonido al mismo nivel que la imagen, su obra puede apreciarse en más de 50 películas y variadas plataformas. Con la revolución 'voice first', David y su equipo exploran el poder del sonido en la experiencia de usuario, analizando su papel en la interacción y comunicación bidireccional.

más...
El establecimiento de las tecnologías de voz.

El establecimiento de las tecnologías de voz.

La evolución de la tecnología de voz nos lleva a una adopción masiva de asistentes y altavoces inteligentes. A pesar de avanzar desde los rudimentarios intentos de IBM en los 50s, los desafíos persisten. El lenguaje humano es ambiguo; para una verdadera comprensión, es vital superar el uso simple de palabras clave. Necesitamos sistemas que sean genuinamente conversacionales, combinando diversas disciplinas para trascender las limitaciones actuales.

más...
Estas son noticias que en mindgeist creemos que no puedes pasar por alto.

Estas son noticias que en mindgeist creemos que no puedes pasar por alto.

El 2020 arranca con el **Consumer Electronic Show**, vitrina de avances tecnológicos. La voz, antes un nicho, ahora redefine la experiencia del usuario. Google reporta 500M de usuarios para su asistente en el CES. Alexa fortalece su presencia en Hispanoamérica. KFC recrea digitalmente la voz de su fundador, el Coronel Sanders. A pesar de avances, el voice commerce aún no satisface todas las expectativas. La tecnología vocal se vuelve cada vez más integral en la vida diaria.

más...
Estas son noticias que en mindgeist creemos que no puedes pasar por alto.

Estas son noticias que en mindgeist creemos que no puedes pasar por alto.

Las tendencias **Voice First** de 2022 evidencian la integración de **Amazon Alexa** en **Jaguar Land Rover** y una modificación para una interacción más fluida con Alexa. James Cameron advierte sobre los peligros de los deepfakes. Un estudio de **IBM** subraya el auge de chatbots de IA. Se destaca la 'curva en J' en la adopción tecnológica. Se pasaron 4 horas diarias en móviles en 2020, mayormente en redes sociales. Por último, **Alexa Together** asiste remotamente a ancianos, facilitando su monitoreo y comunicación.

más...
Estudio de las Skills de Alexa en Español - Invierno 2020

Estudio de las Skills de Alexa en Español - Invierno 2020

Alexa ya opera en español en tres países, reflejando una madurez creciente en estos mercados. En respuesta a esta tendencia ascendente, Mindgeist ha lanzado una edición actualizada de su estudio sobre skills en español, incorporando datos del mercado estadounidense. El informe detalla estadísticas sobre publicaciones de skills, categorias, editores y evaluaciones de usuarios. Además, se han sumado perspectivas de expertos en comunicación para analizar estos datos. El objetivo es entender cómo estas tendencias influirán en la forma en que las empresas se conectan y comunican con su público.

más...
"Hola, este es el resultado de tu búsqueda."​

"Hola, este es el resultado de tu búsqueda."​

La abundancia de información en la web nos inunda, a menudo más allá de nuestra capacidad de procesarla. Esta saturación recuerda a un buffet inagotable. Sin embargo, con la aparición de la búsqueda por voz y la importancia de posicionar contenidos, la dinámica está cambiando hacia una selección más cuidada, similar al concepto japonés de 'omakase', donde se confía en el chef para recibir lo mejor. Los altavoces inteligentes buscan ofrecer una respuesta precisa y directa. En este nuevo paradigma, no luchamos por la atención, sino que debemos ganárnosla.

más...
En mindgeist creemos que no puedes perderte estas noticias.

En mindgeist creemos que no puedes perderte estas noticias.

En Mindgeist, nos dedicamos a curar meticulosamente las noticias más relevantes para nuestra comunidad. Con el constante flujo de información diaria, seleccionamos cuidadosamente aquellas piezas que consideramos valiosas y trascendentales para nuestros lectores. Cada artículo que compartimos refleja nuestro compromiso con la calidad y la relevancia. Nuestra misión es garantizar que te mantengas informado con contenido significativo y actualizado.

más...
El timeline de las interfaces de voz

El timeline de las interfaces de voz

La historia de los asistentes de voz se extiende desde los esfuerzos iniciales en síntesis de voz. nos adentramos en la Comprensión de Lenguaje Natural, pilar de la inteligencia artificial, debatiendo si el enfoque debe ser estadístico o basado en modelos conceptuales. El avance en el Reconocimiento del Habla ha llevado a una comprensión similar a la humana, haciendo las interacciones vocales más naturales. Los Asistentes, que simulan conversaciones o tienen funciones específicas, han visto oportunidades expansivas con mejoras en la síntesis y comprensión del habla. La narración, en constante evolución, promete ser clave del sector.

más...
Truco: como depurar con  Web API for Games

Truco: como depurar con Web API for Games

En el mundo del desarrollo, la depuración es la piedra angular para garantizar aplicaciones de alto rendimiento y sin fallos. Si bien las herramientas locales como la consola Javascript resultan esenciales durante las fases iniciales, cuando migramos aplicaciones a dispositivos como Alexa, nos enfrentamos a un desafío: ¿cómo depurar eficazmente en un entorno remoto? Aquí es donde intervienen los depuradores remotos como RemoteJS. Estos no sólo permiten monitorear eventos en tiempo real, sino que también facilitan la ejecución de código a distancia y la captura de pantallas. Sin embargo, es crucial recordar retirar cualquier herramienta de depuración antes de finalizar y enviar la aplicación.

más...