带有 node.js 的对话流中的 Bigquery ML

Posted

技术标签:

【中文标题】带有 node.js 的对话流中的 Bigquery ML【英文标题】:Bigquery ML in dialogflow with node.js 【发布时间】:2019-10-11 23:18:43 【问题描述】:

我是 javascript 的菜鸟。我不明白 dialogflow 中 Promise 的语法。

我正在尝试使工作变得简单 BigQuery 调用,但没有成功。

它在控制台中的某个位置返回正确的信息,但不在流程中

示例最初来自本教程“https://codelabs.developers.google.com/codelabs/cloud-dialogflow-bqml/index.html?index=..%2F..cloudai#4”。我更改了一些代码,因为我想让它与“app.intent”一起使用:exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app) 而不是“agent.handleRequest(intentMap)

我尝试使用return new Promise((resolve,reject) => resolve。我在 *** 中花了几个小时尝试了几种代码组合,但都没有奏效。

const ticketCollection=(conv,EMAIL,CATEGORY) => 

  // The SQL Query to Run
  const SQLQUERY = `WITH pred_table AS (SELECT 5 as seniority, "3-Advanced" as experience,
          "$CATEGORY" as category, "Request" as type)
          SELECT cast(predicted_label as INT64) as predicted_label
          FROM ML.PREDICT(MODEL helpdesk.predict_eta,  TABLE pred_table)`;

  const OPTIONS = 
    query: SQLQUERY,
    // Location must match that of the dataset(s) referenced in the query.
    location: "US",
    params: 
      category: CATEGORY
    
  ;
  console.log("options",OPTIONS);
  return new Promise((resolve,reject) => 
    BIGQUERY_CLIENT.query(OPTIONS)
      .then(results => 
        //Capture results from the Query
        console.log(JSON.stringify(results[0]));
        const QUERY_RESULT = results[0];
        const ETA_PREDICTION = QUERY_RESULT[0].predicted_label;
        console.log("results",QUERY_RESULT);
        console.log("eta",ETA_PREDICTION);
        resolve();
        reply(conv,`Thanks a lot, we will get back to you in $ETA_PREDICTION minutes`);
      );
  );
;


app.intent('Submit Ticket', (conv) => 
  console.log("Parameters", conv.parameters);
  const EMAIL = conv.parameters.email;
  const CATEGORY = conv.parameters.category;
  ticketCollection(conv,EMAIL,CATEGORY);
);

我希望聊天机器人返回预期时间。同样,我是 javascript 的菜鸟。任何建议或观察将不胜感激!提前非常感谢您!

【问题讨论】:

【参考方案1】:

有很多事情可能会导致您的问题。没有看到所有代码,很难确定,但这里有几个问题:

Promises 和 Intent 处理程序

你创建的意图处理程序

app.intent('Submit Ticket', (conv) => 

需要返回一个 Promise,因为您正在那里的某处进行异步操作。库需要知道什么时候所有的工作都完成了,响应消息已经设置好了,它实际上可以将响应返回给用户。

由于ticketCollection() 返回一个 Promise,最简单的方法就是将该调用更改为

return ticketCollection(conv,EMAIL,CATEGORY);

承诺和解决()

下一个问题是你在做进一步的工作之前调用resolve()(调用reply(),不管是什么):

    resolve();
    reply(conv,`Thanks a lot, we will get back to you in $ETA_PREDICTION minutes`);

如上所述,库假定当 Promise 解析时一切都已完成,但看起来您正尝试在调用 resolve() 之后设置回复

在这种情况下,交换两行将处理此问题。但可能有更好的解决方案。

使用提供给您的 Promise

整个代码块看起来相当复杂,并且可能可以以一种有意义的方式进行简化,因为BIGQUERY_CLIENT.query(OPTIONS) 返回一个 Promise(正如 then() 块所建议的那样。所以你可能只返回它的 Promise创建而不是必须自己包装它。(对于不返回自己的 Promises 的库,您可能仍然需要包装它,但越来越多的库返回 Promises,因为它是一个更好的解决方案。)

因此,您可以通过删除整个 new Promise 部分和对 resolve() 的调用来简化它,它可能看起来像

  console.log("options",OPTIONS);
  return BIGQUERY_CLIENT.query(OPTIONS)
    .then(results => 
      //Capture results from the Query
      console.log(JSON.stringify(results[0]));
      const QUERY_RESULT = results[0];
      const ETA_PREDICTION = QUERY_RESULT[0].predicted_label;
      console.log("results",QUERY_RESULT);
      console.log("eta",ETA_PREDICTION);
      reply(conv,`Thanks a lot, we will get back to you in $ETA_PREDICTION minutes`);
    );

您仍然需要确保返回 Promise,并确保它被返回到处理程序库,但这比尝试包装内容更容易阅读代码。

【讨论】:

很高兴它有帮助!请注意,我在第一部分中修复了一个 Brain-o

以上是关于带有 node.js 的对话流中的 Bigquery ML的主要内容,如果未能解决你的问题,请参考以下文章

Node.js中的代码AWS Lambda Package不会调用putRecord()来将数据添加到AWS Kinesis Firehose Stream中

带有 Express 框架的 Node.js 中的自定义事件

带有预检的 Node.JS 中的跨域 POST 请求?

如何将二进制缓冲区解码为 node.js 中的图像?

如何在 node.js 中搜索字符串的流?

带有 Node.js/Socket.IO 服务器和客户端的 Phonegap 应用程序中的 Android 的 WebSockets