【问题标题】:DialogflowSDK middleware return after resolving a promiseDialogflowSDK 中间件在解决承诺后返回
【发布时间】:2018-08-21 03:00:50
【问题描述】:

我目前正在使用 actions-on-google 节点 sdk,我正在努力研究如何等待我的中间件中的承诺解决,然后再执行我的意图。我尝试使用async/await 并从我的中间件函数返回promise,但两种方法似乎都不起作用。我知道通常你不会像我在这里所做的那样覆盖意图,但这是为了测试正在发生的事情。

const {dialogflow} = require('actions-on-google');
const functions = require('firebase-functions');

const app = dialogflow({debug: true});

function promiseTest() {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve('Resolved');
        }, 2000)
    })
}
app.middleware(async (conv) => {
    let r = await promiseTest();
    conv.intent = r
})

    app.fallback(conv => {
    const intent = conv.intent;

    conv.ask("hello, you're intent was " + intent );
});

看起来我至少应该能够返回 promise https://actions-on-google.github.io/actions-on-google-nodejs/interfaces/dialogflow.dialogflowmiddleware.html

但我不熟悉打字稿,所以我不确定我是否正确阅读了这些文档。

任何人都可以建议如何正确地做到这一点?例如,现实生活中的示例可能是我需要进行数据库调用并等待它在我的中间件中返回,然后再继续下一步。

我的功能是在谷歌云功能中使用 NodeJS V8 测试版。

此代码的输出是任何实际意图,例如默认的欢迎意图,而不是“已解决”,但没有错误。因此中间件触发,但随后在承诺解决之前转移到回退意图。例如在设置conv.intent = r之前

【问题讨论】:

  • 这段代码的输出是什么?
  • @AzaTulepbergenov 已更新。但基本上没有错误,它只是触发后备意图。如果我在 await 承诺语句之前将 conv.intent 设置为另一个值,它会设置它,然后在它落入回退意图时正确打印出来

标签: google-cloud-functions dialogflow-es actions-on-google


【解决方案1】:

异步的东西真的很适合 V2 API。对我来说,只有在 NodeJS 8 上才能正常工作。原因是从 V2 开始,除非您返回承诺,否则操作将返回空,因为它在函数的其余部分被评估之前已经完成。有很多工作要做,我有一些样板文件可以帮助你:

'use strict';

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {BasicCard, MediaObject, Card, Suggestion, Image, Button} = require('actions-on-google');
var http_request = require('request-promise-native');

process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));

  function welcome(agent) {
    agent.add(`Welcome to my agent!`);
  }

  function fallback(agent) {
    agent.add(`I didn't understand`);
    agent.add(`I'm sorry, can you try again?`);
  }

  function handleMyIntent(agent) {
      let conv = agent.conv();
      let key = request.body.queryResult.parameters['MyParam'];
      var myAgent = agent;
      return new Promise((resolve, reject) => {
        http_request('http://someurl.com').then(async function(apiData) {
          if (key === 'Hey') {
            conv.close('Howdy');
          } else {
            conv.close('Bye');
          }
          myAgent.add(conv);
          return resolve();
      }).catch(function(err) {
          conv.close('  \nUh, oh. There was an error, please try again later');
          myAgent.add(conv);
          return resolve();
      })})
  }

  let intentMap = new Map();
  intentMap.set('Default Welcome Intent', welcome);
  intentMap.set('Default Fallback Intent', fallback);
  intentMap.set('myCustomIntent', handleMyIntent);
  agent.handleRequest(intentMap);
});

您需要的简要概述:

  • 您必须返回承诺解决方案。
  • 您必须对 HTTP 请求使用“request-promise-native”包
  • 您必须升级您的计划以允许出站 HTTP 请求 (https://firebase.google.com/pricing/)

【讨论】:

  • 所以,我玩了一点,如果我在 fallback 意图中使用与我的承诺类似的代码,我可以像在我的设计中那样操作 conv 对象示例(仅覆盖意图),但是如果我尝试使用中间件更改它,如app.middleware 这不起作用。事实上,返回 promise 然后返回 resolve 函数实际上会导致代理停止工作。错误是:"TypeError: Cannot read property 'parsed' of undefined at Function.<anonymous> (/srv/node_modules/actions-on-google/dist/service/dialogflow/dialogflow.js:115:69)
【解决方案2】:

所以事实证明,我的问题与过时版本的 actions-on-google sdk 有关。 dialogflow firebase 示例使用 v2.0.0,在 package.json 中将其更改为 2.2.0 解决了问题

【讨论】:

    猜你喜欢
    • 2016-08-19
    • 1970-01-01
    • 2022-01-18
    • 2016-07-05
    • 2019-10-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    相关资源
    最近更新 更多