La interacción con Alexa siempre la inicia el usuario, las skills son reactivas y las funciones del back-end realizan siempre estos pasos:

  1. Recoger y validar las estructuras event y context que contienen la entrada proporcionada por el usuario, información del dispositivo y otra información como la fecha y hora de la interacción, identificadores de sesión, de usuario y otros.
  2. Producir la respuesta que se le enviará al usuario
  3. Enviar la respuesta

Está claro que el tiempo de respuesta es crítico y se debe minimizar pero en ocasiones puede ser necesario realizar un procesamiento que lleve varios segundos.

Una de las soluciones para realizar ese procesamiento sin impactar el tiempo de respuesta sería enviar un mensaje a través de SQS (también funcionará con SNS, pero SQS parece más robusto) y desarrollar una función Lambda que escuche los mensajes en esa cola SQS. El envío del mensaje se realiza de manera casi instantánea con lo que se puede enviar la respuesta al usuario y todo el procesamiento en la función lambda se realiza en paralelo y sin bloquear al usuario.

El único inconveniente es que el resultado de ese proceso solo estará disponible la siguiente vez que el usuario use la skill.

  • Envío de mensaje SQS
var AWS = require("aws-sdk");
var sqs = new AWS.SQS();

// En este caso la llamada a sqs.sendMessage se implementa mediante una
// promise, pero funcionaria igualmente con una llamada asincrona normal.
sendSQSrequest.then( function(result) {
    console.log( JSON.stringify(result) );
    this.emit(':tell', this.t('SAY_A_WORD') ); // respuesta al usuario
});

/////////////////////
//
function sendSQSrequest( word )
{
    var params = {
        MessageBody: word,
        QueueUrl: QUEUE_ARN // Se debe crear en SQS
    };

    return new Promise( function(resolve, reject) {
        var sqs = new AWS.SQS();
        sqs.sendMessage( params, function(err, data) {
            if (err) {
                console.log( err, err.stack); // an error occurred
                reject( err );
            }
            else {
                console.log( JSON.stringify(data) ); // successful
                resolve( data );
            }
        });
    });
}
  • Función lambda que lee el mensaje enviado anteriormente y realiza el procesamiento
exports.handler = function ( event, context, callback )
{
    event.Records.forEach( function(item) {
        console.log( "SQS event: " + JSON.stringify(item.body));
       // Procesamiento no bloqueante
}