从 API 调用中解析 JSON 后,从意图参数中提取的参数未分配给变量

Extracted from intent parameters are not getting assigned to variables after parsing JSON from API call

我正在从一个网站获取 JSON。当我用 console.log() 打印时,一切都很好(我看到打印了所需的数据)但是通过 Intent 传递的参数没有分配给变量,稍后我将导出,所以 Google 助手告诉我信息。

我做错了什么?下面的代码是 Dialogflow 中的 Google Cloud Function 运行。

'use strict';

//This is what I say to get info out
//"Bus line 409 , bus stop nutrio bar"

const request = require('request');
let url = 'https://www.SAMPLESITE.com/Ajax/FindStationDevices?stationId=';

//Creating variables with sample data, that I'm always getting but not the real-time data from JSON.
var arriveInG = "15:15";
var delayG = "7:07";
var arriveTimeG = "13:44";
var distanceLeftG = "2.3 km";

// Import the Dialogflow module from the Actions on Google client library.
const {dialogflow} = require('actions-on-google');

// Import the firebase-functions package for deployment.
const functions = require('firebase-functions');

// Instantiate the Dialogflow client.
const app = dialogflow({debug: true});

// Handle the Dialogflow intent named 'blah-blah'.
// The intent collects a parameters named 'busline,busStop'.
app.intent('getBusTime', (conv, params) => {
    const bLine = params.busline;
    const bStop = params.busStop;

    url+= bStop;

    // These are to tell me if parameters are extracted correctly.
    // conv.ask('Your lucky number is '  + bLine);
    // conv.close(`You said ${num}`);
    // conv.ask('Bus Stop is: '  + bStop + " ");
    // conv.ask(' Bus Line is: '  + bLine);
    // conv.ask(' URL is: '  + url);

    request.get({
        url: url,
        json: true,
        headers: {'User-Agent': 'request'}
      },(err, res, data) => {
        
        if (err) {
    
          console.log('Error:', err);
    
        } else if (res.statusCode !== 200) {
    
          console.log('Status:', res.statusCode);
    
        } else {
          // do something here with received data

          // data is already parsed as JSON:
          // console.log(data.schedule[0].data[0].text);
  
          var i;
          for (i = 0; i < data.liveData.length; i++) { //
              //Check if Live data is not null
              if (data.liveData[i] !== null) {
                //If bus line is the correct one from our question then...
                if (data.liveData[i].allLines[0] == bLine) {

                  arriveInG = data.liveData[i].arriveIn;
                  arriveTimeG = data.liveData[i].arriveTime;
                  delayG = data.liveData[i].delay;
                  distanceLeftG = data.liveData[i].distanceLeft;

                  console.log("Bus Line number " + bLine + 
                              " on Bus Stop " + bStop +  
                              " will arrive in " + arriveInG);
                              
                  console.log("The arrive time is " + arriveTimeG);
                  console.log("Distance left is " + distanceLeftG);
                  
                  assingValues(arriveInG);
                }
                 
              } else {
                 console.log("data.liveData[0] != null");
              }
          }
        }  
    }); 
    
    conv.ask(" Bus Line number " + bLine
        + " on Bus Stop " + bStop
        + " will arrive in " + arriveInG
        + ".The arrive time is " + arriveTimeG
        + ".Distance left is " + distanceLeftG); 
});

function assingValues(arrival) 
{
    arriveInG = arrival;
}

// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

在 Prisoner 的帮助下,工作代码是这样的:

'use strict';

const request = require('request');
const requestNat = require('request-promise-native');

let url = 'https://www.samplewebsite.com/Ajax/FindStationDevices?stationId=';
var arriveInG = "15:15";//sample inital values assigned.
var delayG = "7:07";//sample inital values assigned.
var arriveTimeG = "13:44";//sample inital values assigned.
var distanceLeftG = "2.3 km";//sample inital values assigned.

// Import the Dialogflow module from the Actions on Google client library.
const {dialogflow} = require('actions-on-google');

// Import the firebase-functions package for deployment.
const functions = require('firebase-functions');

// Instantiate the Dialogflow client.
const app = dialogflow({debug: true});

// Handle the Dialogflow intent named 'getBusTime'.
// The intent collects a parameter named 'busline', 'busStop'.
app.intent('getBusTime', (conv, params) => {
    const bLine = params.busline;
    const bStop = params.busStop;

    url+= bStop;

    return requestNat.get({
      url: url,
      json: true,
      headers: {'User-Agent': 'request'}
    }).then( body => {
    
      // Process the body, which is already an object
      // console.log(data.schedule[0].data[0].text);

      var i;
      for (i = 0; i < body.liveData.length; i++) { //
          //Check if Live data is not null
          if (body.liveData[i] !== null) {
            //If bus line is the correct one from our qustion then...
            if (body.liveData[i].allLines[0] == bLine) {

              arriveInG = body.liveData[i].arriveIn;
              arriveTimeG = body.liveData[i].arriveTime;
              delayG = body.liveData[i].delay;
              distanceLeftG = body.liveData[i].distanceLeft;
              console.log("Bus Line number " + bLine + 
                          " on Bus Stop " + bStop +  
                          " will arrive in " + arriveInG);
              console.log("The arrive time is " + arriveTimeG);
              console.log("Distance left is " + distanceLeftG);
            }
             
          } else {
             console.log("data.liveData[0] != null");
          }   
      }

      //Place the google assistant answer here
      conv.ask(" Bus Line number " + bLine
      + " on Bus Stop " + bStop
      + " will arrive in " + arriveInG
      + ".The arrive time is " + arriveTimeG
      + ".Distance left is " + distanceLeftG);

    }).catch( err => {
      // Error handling
      console.log('Error:', err);
    });
});



// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

    // TO TEST Respond individually(put in body !!!)
    // conv.ask('Your lucky number is '  + bLine);
    // conv.close(`You said ${num}`);
    // conv.ask('Bus Stop is: '  + bStop + " ");
    // conv.ask(' Bus Line is: '  + bLine);
    // conv.ask(' URL is: '  + url);
    
    // Test Speach
    // Bus line 409 , bus stop nutrio bar
    // Bus line 148 , bus stop 53

这里有两个相关的问题。

首先,如果您正在进行异步调用,您的处理程序必须 return 一个 Promise。否则图书馆不知道异步调用何时完成,有数据,你可以发回回复。

由于您正在进行 HTTP 调用,因此这是一个异步请求,因此需要使用 Promise 来完成。最简单的方法是使用 request-promise-native 包而不是 request 包。

所以这部分代码可能看起来像这样:

const request = require('request');
return request.get({
  url: url,
  json: true,
  headers: {'User-Agent': 'request'}
}).then( body => {
  // Process the body, which is already an object
}).catch( err => {
  // Error handling
});

第二个问题是您对 conv.ask() 的调用在具有响应的回调函数之外。在上面的代码中,它应该在 "Process the body".

的部分