通过事件网关异步回答 Alexa Smart Home Skill 时要回答 AWS Lambda 什么?

What to answer an AWS Lambda when answering Alexa Smart Home Skill asynchronous via event gateway?

我正在为 Alexa 开发智能家居技能。因此,来自 Alexa 的所有请求都被发送到我的 AWS Lambda 函数,然后该函数将请求转发到我们的服务器,该服务器与各个智能家居设备联系。 所以根据 Alexa 文档 (https://developer.amazon.com/en-US/docs/alexa/device-apis/alexa-response.html#response) 我可以同步回答这些请求,这意味着我一直等到设备上的操作完成(同时 lambda 和我们的服务器之间的 http 连接保持打开状态 -> 导致由于 lambda 比 运行 长而收费)并通过 lambda 将响应发送回 Alexa。

另一种选择是通过将答案作为新的 http 请求发送到 Alexa 事件网关来异步回答。

因为有些操作需要一些时间(考虑从我们的服务器到智能家居设备的方式,执行操作,回答等)我更喜欢异步方法,因为它也节省了 lambda 的时间。我已经实现了所有必要的组件来回答异步,但我不知道我应该回答什么 lambda 以防我回答异步。

我的 Lambda 目前看起来有点像这样:

const https = require('https');

exports.handler = function (request, context) {

    function handleServerRequest(request, context) {

        const doPostRequest = () => {

            const data = request;

            return new Promise((resolve, reject) => {
                const options = {
                    host: 'xxx.ngrok.io',
                    path: '/dyn/alexa/request',
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    }
                };

                /* ... perform https request and resolve promise*/
            });
        };


        doPostRequest().then((response) => {

            log("DEBUG", "Server Response: ", JSON.stringify(response));

            // in case the server decides to answer async (via event gateway) it 
            // immediately answers the https request with a flag "async: true". 

            if(response.async) {
                // -> WHAT TO TELL THE LAMBDA HERE?
                //context.succeed();
                return;
            }
            context.succeed(response);
        });

    }

    handleServerRequest(request, context, "");


当我只是执行 context.succeed() 而没有得到适当的响应时,我会在 Alexa 应用程序中收到一个错误,告诉我 "the device is not reacting",然后尽快指示正确的状态Alexa 通过事件网关接收有效的 StateReport 指令。

如果我会异步回答,我该如何正确结束 lambda 函数?

根据我的经验,您可以发送同步或异步响应(不能同时发送),这需要事先设置。

要设置异步响应,请参阅此 doc,其中提到:

On the PERMISSIONS page, slide Send Alexa Events to indicate your skill will send asynchronous responses and/or change report events.

我遇到了同样的问题。 我刚刚验证了在处理程序中发送 DeferredResponse 同步POST 稍后异步更新 到 Alexa Event Gateway,它有效。

我测试了 PowerControllerPowerLevelController 的请求,在不久的将来我会测试其他的。

我就此事联系了 Alexa 支持人员。我从谈话中得到的是

the documented method of approaching asynchronous responses is to send the asynchronous response before any sort of synchronous response

其中“任何类型的同步响应”根据经验包括 returning null、一个空对象甚至 returning 而根本不向输出流写入任何内容(在 Java 11 Lambda 函数).

对我来说,这在很大程度上破坏了异步响应的意义,因为 Lambda 函数不能完全委托给设备云,return 而是必须等待它响应。那个,或者干脆睡到超时,希望设备云在那个时间点之前异步响应。