当前位置: 首页 > 面试题库 >

DialogFlow V2 Webhook-立即获得语音响应,而不是在异步请求之后

傅茂实
2023-03-14
问题内容

我有一个DialogFlow V2 node.js Webhook。

我有一个通过webhook动作调用的意图:

const { WebhookClient } = require('dialogflow-fulfillment');
const app = new WebhookClient({request: req, response: res});

function exampleIntent(app) {

   app.add("Speak This Out on Google Home!");   // this speaks out fine. no error. 
}

现在,如果我有一个成功完成的异步请求,并且 在成功块中 执行app.add, 如下所示:

 function exampleIntent(app) {  
      myClient.someAsyncCall(function(result, err) {
          app.add("This will not be spoken out");  // no dice  :(
      }
      // app.add("but here it works... so it expects it immediately");
  }

…则对话流不等待语音返回。我在Response对象中收到错误:

  "message": "Failed to parse Dialogflow response into AppResponse, exception thrown with message: Empty speech response",

如何让DialogFlow V2等待Webhook的Async操作完成,而不是立即等待语音响应?

注意:此问题仅在V2中开始发生。在V1中,app.ask在异步调用的末尾工作良好。

例如,应用程序的主映射器将调用exampleIntent,如下所示:

let actionMap = new Map();
actionMap.set("my V2 intent name", exampleIntent);
app.handleRequest(actionMap);

我的myClient.someAsyncCall内部的异步请求正在使用Promises:

exports.someAsyncCall = function someAsyncCall(callback) {
    var apigClient = getAWSClient(); // uses aws-api-gateway-client
    apigClient.invokeApi(params, pathTemplate, method, additionalParams, body)
    .then(function(result){
        var result = result.data;
        var message = result['message'];
        console.log('SUCCESS: ' + message);
        callback(message, null);  // this succeeds and calls back fine. 
    }).catch( function(error){
        console.log('ERROR: ' + error);
        callback(error, null);
    });
};

问题答案:

它在V1中起作用的原因是ask()实际上会发送请求。

使用V2,您可以add()多次调用以同一回复将所有内容发送给用户。因此,它需要知道何时发送消息。它是处理处理程序响应的一部分。

如果您的处理程序是同步的,它将立即发送答复。

但是,如果您的处理程序是异步的,则它将假定您正在返回一个Promise,并等待该Promise解析之后再发送答复。因此,要处理异步调用,您需要返回一个Promise。

由于您的呼叫已经在使用Promises,因此您的状态非常好!重要的是您还要 返回
Promise并使用它。因此,这样的事情可能是您的异步​​调用(返回了Promise):

exports.someAsyncCall = function someAsyncCall() {
    var apigClient = getAWSClient(); // uses aws-api-gateway-client
    return apigClient.invokeApi(params, pathTemplate, method, additionalParams, body)
    .then(function(result){
        var result = result.data;
        var message = result['message'];
        console.log('SUCCESS: ' + message);
        return Promise.resolve( message );
    }).catch( function(error){
        console.log('ERROR: ' + error);
        return Promise.reject( error );
    });
};

然后您的Intent处理程序将类似于

function exampleIntent(app) {  
  return myClient.someAsyncCall()
    .then( function( message ){
      app.add("You should hear this message": message);
      return Promise.resolve();
    })
    .catch( function( err ){
      app.add("Uh oh, something happened.");
      return Promise.resolve();  // Don't reject again, or it might not send the reply
    })
}


 类似资料:
  • 我试图理解异步响应在Jersey上的工作方式。我阅读了新泽西文档(https://jersey.java.net/documentation/latest/async.html)的第10章,但它对我的问题没有帮助。这里关于stackoverflow的研究也没有得出令人满意的答案(这一点我可以理解)。 我试图做的与本文中的一个问题类似(使用http状态202进行异步操作)。我想使用HTML表单文档将

  • 我正在尝试找到一种异步的方式来立即返回客户端请求的响应。 我所需要的只是记录请求数据,调用新线程请求其他服务器上昂贵的操作(一些后端操作),并且无需等待它们的响应,立即返回200状态响应给客户端。 此时此刻,我正试图用完整的未来来做这件事,但我错过了一些东西。 总之,我得到了立即响应,但veryExpensiveOperations()方法似乎丢失了httpRequest值,这对我来说太糟糕了,因

  • 问题内容: 我有一个提供标准扩展点的JavaScript小部件。其中之一是功能。它应返回以防止创建项目。 我已经使用jQuery在此函数中添加了Ajax调用: 但是我想防止我的小部件创建项目,所以我应该在母函数中返回,而不是在回调中返回。有没有一种方法可以使用jQuery或任何其他浏览器内API执行同步AJAX请求? 问题答案: 从jQuery文档开始:您将 异步 选项指定为 false, 以获取

  • 我希望我的请求触发一些长时间运行的操作,这些操作应该在后台执行。我编写了以下实现,应该在后台处理我的操作,但实际上我的请求是同步执行的: 在日志中,我看到以下内容: 我看到我的在另一个线程中执行,但出于某种原因,我的原始请求等待sleep完成 更新1:

  • 我们正在尝试使用 guzzle 执行并发异步请求。在浏览了一些资源(例如这样和这样)之后,我们提出了一些在下面共享的代码。但是,它没有按预期工作。 看起来Guzzle正在同步而不是异步地处理这些请求。 出于测试目的,我们点击一个内部url,它会Hibernate5秒钟。当并发数为10时,我们预计所有10个请求最初将被排队并几乎同时发送到服务器,在那里它们将等待5秒钟,然后几乎所有的请求将几乎同时完

  • 我已经创建了一个简单的Jersey客户端,它能够成功地使用有效负载执行POST请求。但现在它正在等待来自httpendpoint的响应: 问:代码是否有可能不等待响应。 我试图阅读泽西客户端文档,以确定我的代码是否有可能不等待响应?我看到我们只能在读取响应后关闭连接,但在我的情况下没有用。我想在将有效负载发布到endpoint后立即关闭连接。 我只需要触发并忘记POST请求,因为我不关心响应。这是