Извлеченные из намерения параметры не присваиваются переменным после анализа JSON из вызова API - PullRequest
0 голосов
/ 01 октября 2018

Я получаю JSON с веб-сайта.Когда я печатаю с console.log(), все хорошо (я вижу, что распечатаны необходимые данные), но параметры, переданные через Intent, не присваиваются переменной, которую позже я добавляю в экспорт, поэтому Google Assistant сообщает мне информацию.

Что я делаю не так?Приведенный ниже код представляет собой облачную функцию Google, работающую в Dialogflow.

'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

1 Ответ

0 голосов
/ 02 октября 2018

У вас есть две связанные с этим проблемы.

Во-первых, если вы делаете асинхронные вызовы, ваш обработчик должен вернуть Promise.В противном случае библиотека не знает, когда выполнен асинхронный вызов, имеет данные, и вы можете отправить ответ.

Поскольку вы делаете HTTP-вызов, это асинхронный запрос, и, следовательно, его необходимосделано с помощью обещания.Самый простой способ сделать это - использовать пакет request-обещание-родной вместо пакета 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() находится вне функции обратного вызова с ответом.В приведенном выше коде это должно быть в той части, где написано «Обработка тела».

...