如何使用 Lambda 函数对 Alexa Skill 应用程序进行异步 API 调用?

2023-12-03

我想从 Lambda 函数调用 api。我的处理程序由包含两个必需插槽的意图触发。因此我事先不知道我是否会退货Dialog.Delegate指令或我对 api 请求的响应。在调用意图处理程序时,我如何承诺这些返回值?

这是我的处理程序:

const FlightDelayIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'MyIntent';
  },

  handle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;

    if (request.dialogState != "COMPLETED"){
      return handlerInput.responseBuilder
        .addDelegateDirective(request.intent)
        .getResponse();
    } else {
      // Make asynchronous api call, wait for the response and return.
      var query = 'someTestStringFromASlot';

      httpGet(query,  (result) => {
        return handlerInput.responseBuilder
          .speak('I found something' + result)
          .reprompt('test')
          .withSimpleCard('Hello World', 'test')
          .getResponse();
      });
    }
  },
};

这是我的辅助函数,它提出了请求:

const https = require('https');

function httpGet(query, callback) {
    var options = {
        host: 'myHost',
        path: 'someTestPath/' + query,
        method: 'GET',
        headers: {
            'theId': 'myId'
        }
    };

    var req = https.request(options, res => {
        res.setEncoding('utf8');
        var responseString = "";

        //accept incoming data asynchronously
        res.on('data', chunk => {
            responseString = responseString + chunk;
        });

        //return the data when streaming is complete
        res.on('end', () => {
            console.log('==> Answering: ');
            callback(responseString);
        });

    });
    req.end();
}

所以我怀疑我必须使用承诺并在我的句柄函数前面放置一个“异步”?我对这一切都很陌生,所以我不知道这意味着什么,特别是考虑到我有两个不同的返回值,一个是直接返回值,另一个是延迟返回值。我该如何解决这个问题?

先感谢您。


正如您所怀疑的,您的处理程序代码在异步调用 http.request 之前完成,因此 Alexa SDK 不会从handle函数并将向 Alexa 返回无效响应。

我稍微修改了您的代码以在笔记本电脑上本地运行它来说明问题:

const https = require('https');

function httpGet(query, callback) {
    var options = {
        host: 'httpbin.org',
        path: 'anything/' + query,
        method: 'GET',
        headers: {
            'theId': 'myId'
        }
    };

    var req = https.request(options, res => {
        res.setEncoding('utf8');
        var responseString = "";

        //accept incoming data asynchronously
        res.on('data', chunk => {
            responseString = responseString + chunk;
        });

        //return the data when streaming is complete
        res.on('end', () => {
            console.log('==> Answering: ');
            callback(responseString);
        });

    });
    req.end();
}

function FlightDelayIntentHandler() {

    // canHandle(handlerInput) {
    //   return handlerInput.requestEnvelope.request.type === 'IntentRequest'
    //     && handlerInput.requestEnvelope.request.intent.name === 'MyIntent';
    // },

    // handle(handlerInput) {
    //   const request = handlerInput.requestEnvelope.request;

    // if (request.dialogState != "COMPLETED"){
    //     return handlerInput.responseBuilder
    //       .addDelegateDirective(request.intent)
    //       .getResponse();
    //   } else {
        // Make asynchronous api call, wait for the response and return.
        var query = 'someTestStringFromASlot';

        httpGet(query,  (result) => {
            console.log("I found something " + result);

        //   return handlerInput.responseBuilder
        //     .speak('I found something' + result)
        //     .reprompt('test')
        //     .withSimpleCard('Hello World', 'test')
        //     .getResponse();
        });

        console.log("end of function reached before httpGet will return");
    //   }
    // }
}

FlightDelayIntentHandler();

要运行此代码,请不要忘记npm install http , then node test.js。它产生

stormacq:~/Desktop/temp $ node test.js
end of function reached before httpGet will return
==> Answering:
I found something {
  "args": {},
  "data": "",
... 

所以关键是要等http get在向 Alexa 返回响应之前返回。为此,我建议修改您的httpGet函数返回一个承诺而不是使用回调。

修改后的代码是这样的(我保留了你原来的代码作为注释)

const https = require('https');

async function httpGet(query) {
    return new Promise( (resolve, reject) => {
        var options = {
            host: 'httpbin.org',
            path: 'anything/' + query,
            method: 'GET',
            headers: {
                'theId': 'myId'
            }
        };

        var req = https.request(options, res => {
            res.setEncoding('utf8');
            var responseString = "";

            //accept incoming data asynchronously
            res.on('data', chunk => {
                responseString = responseString + chunk;
            });

            //return the data when streaming is complete
            res.on('end', () => {
                console.log('==> Answering: ');
                resolve(responseString);
            });

            //should handle errors as well and call reject()!
        });
        req.end();

    });

}



async function FlightDelayIntentHandler() {

        // canHandle(handlerInput) {
    //   return handlerInput.requestEnvelope.request.type === 'IntentRequest'
    //     && handlerInput.requestEnvelope.request.intent.name === 'MyIntent';
    // },

    // handle(handlerInput) {
    //   const request = handlerInput.requestEnvelope.request;

    // if (request.dialogState != "COMPLETED"){
    //     return handlerInput.responseBuilder
    //       .addDelegateDirective(request.intent)
    //       .getResponse();
    //   } else {
        // Make asynchronous api call, wait for the response and return.
        var query = 'someTestStringFromASlot';

        var result = await httpGet(query);
        console.log("I found something " + result);

        //   return handlerInput.responseBuilder
        //     .speak('I found something' + result)
        //     .reprompt('test')
        //     .withSimpleCard('Hello World', 'test')
        //     .getResponse();
        //});

        console.log("end of function reached AFTER httpGet will return");
    //   }
    // }
}

FlightDelayIntentHandler();

运行此代码会产生:

stormacq:~/Desktop/temp $ node test.js
==> Answering:
I found something{
  "args": {},
  "data": "",
...
end of function reached AFTER httpGet will return
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Lambda 函数对 Alexa Skill 应用程序进行异步 API 调用? 的相关文章

随机推荐

  • 使用 ReflectiveInjector 注入服务,无需指定依赖树中的所有类

    我目前有一个服务为我生成一个对象 该对象应该表现为一种活动记录 因为它可以在访问它的属性时延迟填充自身 我的第一种方法是将生成的对象使用的服务注入到创建服务中 然后将它们传递给创建的对象的构造函数 但由于创建服务从不使用这些服务 所以看起来
  • 如何将 CloudWatch 自定义日志组与 Python Shell Glue 作业结合使用?

    我有一些 Python Shell 类型的 Glue 作业 我想将作业日志发送到自定义 CloudWatch 日志组而不是默认日志组 我可以通过提供如下作业参数来实现 Spark 类型胶水作业 enable continuous cloud
  • 如何在 WinForms 应用程序中使用 Salesforce OAuth 2.0 隐式流身份验证?

    我编写了一个 Web 应用程序 它使用 OAuth 2 0 Web 服务器流连接到 Salesforce API 一切正常 但现在需要从 WinForms 桌面应用程序访问 Salesforce API 我陷入了困境 Salesforce
  • 在Scheme中添加一个元素到列表的末尾

    负责添加a到结束 b c 使 b c a 到目前为止 当我尝试时 print cons a b c I get a b c 但当我这样做时 print cons b c a I get b c a Stack 上的所有其他类似问题似乎都比这
  • Flutter:请求的资源上不存在“Access-Control-Allow-Origin”标头

    我已经使用 python Flask 创建了 REST GET API 它的代码如下 app Flask name app route youtube def firstGetAPI try url request args get url
  • 我们可以使用 Meteor 框架和 mysql 数据库吗

    我发现很多 Meteor 框架的参考网址 其中我发现 mongodb 作为数据库 因为我对 mongodb 没有太多了解 那么有没有办法实现mysql而不是mongodb There is一种方式 但就目前的框架而言 它是一条未铺砌的道路
  • 多线程聊天服务器

    我是线程新手 我正在尝试从服务器向客户端广播消息 但我不能 看起来服务器总是在侦听新连接 但我可以使用客户端终端向其他客户端发送消息 我的问题是如何在聆听的同时允许输入 这是代码 多线程聊天服务器同步 java import java io
  • 为什么我收到错误无法解析模块路径? Eslint 与 Typescript

    我阅读了很多资源 包括将 eslint 与 Typescript 结合使用 无法解析模块的路径 我一次又一次地遇到同样的错误 yarn lint 2 24 error Unable to resolve path to module com
  • 查找非 Visual C# 组件

    我尝试了多种方法来列出表单的所有非可视组件 例如 OpenDialog ImageList TableAdapters 等 但找不到任何内容 为了找到屏幕上的控件 我在 控件 屏幕中使用了 Foreach 但对于那些非可视组件我什么也没找到
  • 使用 JNI 时 Eclipse 对 C 文件的行为令人惊讶,为什么会这样?

    我正在开发一个 Android 应用程序 其中使用了大量 JNI 代码 最近 从过去 2 3 天开始 我真的对 Eclipse 的意外行为感到恼火 一旦我打开 c 文件 它就会显示模糊的错误 但是 如果我关闭并重新打开项目 错误就会消失 请
  • 获取一个月内的工作日

    我正在尝试获取给定月份内的日期 我的计划是 获取给定月份的开始日期和结束日期 获取该范围内的所有日期 迭代它们并使用以下方法消除周末内的日期isDateInWeekend method 其余日期为工作日 所以我创建了两个NSDate扩展方法
  • groovy++ 发生了什么? [关闭]

    Closed 这个问题是无关 目前不接受答案 我刚刚偶然发现了 groovy 发现它非常有趣 不幸的是 它似乎没有进一步发展 根据 github 的说法 最后一次提交是一年多前 邮件列表完全不活跃 最后一条消息是在四月份返回的 最近没有这方
  • 如何从 XML 文档中删除所有文本

    如何删除所有文本 但保持结构完整 例如
  • 清除MySQL查询缓存而不重新启动服务器

    有什么办法可以clear mysql 查询缓存无需重新启动 mySQL 服务器 我相信你可以用 RESET QUERY CACHE 如果您运行的用户具有重新加载权限 或者 您可以通过以下方式对查询缓存进行碎片整理 FLUSH QUERY C
  • MySQL - 来自另一个表的总和

    我想运行一个包含另一个表中的总和的 select 语句 我知道我可能需要设置一个连接 但我不知道如何处理它 我想选择一个帐户列表 然后获取它们的余额 来自另一个表的总和 这是我一直以来的想法 但显然它是不正确的 SELECT account
  • 如何从 Android 应用程序将 db 文件上传到 google 驱动器?

    我想将数据库文件从我的应用程序上传到谷歌驱动器 我可以在谷歌驱动器中创建一个文件夹 但我不知道如何上传数据库文件 这是我的代码 import java io BufferedInputStream import java io Buffer
  • 使用 Gatsbyjs 包含本地 JS 和 CSS 文件

    我对这个完全陌生gatsbyjs生态系统 同时我正在学习一些reactjs 我最近购买了一个 html 模板 并尝试将其用作 UIgatsbyjs应用 该模板有很多 css 和 js 无论是专有的还是定制的 这意味着没有插件gatsbyjs
  • 添加对 Jtree 的拖放支持

    我想为我的 JTree 应用程序添加拖放支持 我创建了一个自定义的 DefaultMutableTreeNode 子类 有一个默认的 TreeCellRenderer 我需要添加哪些内容以及在哪里添加 最简单的方法是1 调用tree set
  • UIWebView 没有释放内存

    我在尝试恢复分配给 a 的内存时遇到了一些真正的麻烦UIWebView在我的应用程序中 我本质上是创造并呈现UIWebView暂时为用户单独ViewController 然后删除所有引用并弹出ViewController从堆栈中 尽管做了所
  • 如何使用 Lambda 函数对 Alexa Skill 应用程序进行异步 API 调用?

    我想从 Lambda 函数调用 api 我的处理程序由包含两个必需插槽的意图触发 因此我事先不知道我是否会退货Dialog Delegate指令或我对 api 请求的响应 在调用意图处理程序时 我如何承诺这些返回值 这是我的处理程序 con