2

我有一些意图需要触发履行 webhook 并且不关心响应。webhook 的响应时间比超时时间长,所以我希望简单地回复“感谢聊天”,然后在实际触发 webhook 时关闭对话。

感觉很容易,但我错过了一些东西。我也是对话框流的新手。

我可以用任何语言做到这一点,但这里有一个 Javascript 示例:

fdk.handle(function (input) {
  // Some code here that takes 20 seconds.

  return {'fulfillmentText': 'i can respond but I will never make it here.'}
});

编辑 1 - 尝试异步

当我使用异步函数时,POST 请求永远不会发生。所以在下面的代码中:

fdk.handle(function (input) {
  callFlow(input);
  return { 'fulfillmentText': 'here is the response from the webhook!!' }
});

async function callFlow(input) {
  console.log("input is --> " + input)

  var url = "some_url"

  console.log("Requesting " + url)

  request(url, { json: true, headers: {'Access-Control-Allow-Origin' : '*'} }, (err, res, body) => {
    if (err) { return console.log(err); }
    console.log("body is...")
    console.log(body)
  });
}

我在日志中看到了两个 console.log 输出,但没有从请求中看到。而且该请求似乎也没有发生,因为我在端点上看不到它。

解决方案

感谢囚犯的提示。似乎我需要通过 callFlow() 和 handle() 函数返回履行 JSON。现在 Google Home 不会超时,并且会生成 HTTP 调用和响应。

const fdk = require('@fnproject/fdk');
const request = require('request');

fdk.handle(function (input) {
  return callFlow(input);
});

async function callFlow(input) {
  var searchPhrase = input || "cats"
  var url = "some url"

  return new Promise((resolve, reject) => {
    request.post(url, {
      headers: { 'content-type': 'application/x-www-form-urlencoded' },
      body: searchPhrase
    },
      function (err, resp, body) {
        if (err) { return console.log(err) }
        r = { 'fulfillmentText': `OK I've triggered the flow function with search term ${searchPhrase}` }
        resolve(r)
      }
    );
  });

}
4

1 回答 1

2

您不能异步触发履行。在会话模型中,预期实现将执行一些确定响应的逻辑。

但是,您可以在返回结果之前在未完成的实现中执行异步操作。

如果您使用的是足够现代的 node 版本(版本 8 及更高版本),您可以通过将函数声明为函数来做到这一点async,但不要await使用关键字调用它。(如果您确实使用 调用它await,它将等待异步操作完成后再继续。)

因此,鉴于您的示例,这样的事情应该可以工作:

async function doSomethingLong(){
  // This takes 20 seconds
}

fdk.handle(function (input) {
  doSomethingLong();

  return {'fulfillmentText': 'This might respond before doSomethingLong finishes.'}
});

根据您的代码示例更新 1 。

您报告调用request似乎根本没有完成,这似乎很奇怪,但有一些奇怪的事情可能会导致它。

首先,request它本身不是一个异步函数。它使用回调模型,async函数不只是自动等待这些回调被调用。所以你的callFlow()函数调用console.log()了几次,request()在回调被回调之前调用并返回。

您可能应该替换为request-promise-nativerequest包之类的东西,并等待您从通话中获得的 Promise。这使得真正的异步(并且您可以在它完成调用时记录)。callFlow()

其次,我要指出您显示的代码不执行 POST 操作。它默认执行 GET。如果您或您正在调用的 API 期待 POST,这可能是错误的根源。但是,我希望该err参数会被填充,并且您的代码看起来确实会检查并记录这个。

对我来说,整个设置中的一个未知之处是我不知道如何fdk处理异步函数,而且我粗略地阅读文档并没有教育我。我已经用其他框架做到了这一点,这不是问题,但我不知道fdk处理程序是否超时或在发送回复后执行其他操作来终止调用。

于 2019-02-03T00:14:11.583 回答