Заполнить намерение на основе результата вызова API в диалоге Fullfilment - PullRequest
1 голос
/ 20 марта 2019

Я изо всех сил пытаюсь получить следующий полный код для работы Dialogflow:

'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');

process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {

  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));

  function testHandler(agent){
    var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
    var xmlhttp = new XMLHttpRequest();   // new HttpRequest instance
    const proxyurl = "https://cors-anywhere.herokuapp.com/";
    var theUrl = "http://xxxxx/sum?a=5&b=11";
    var url = proxyurl + theUrl;
    var result = "Init";

    getText = function(url, callback)
    {
      var request = new XMLHttpRequest();
      request.onload = function()
      {
        if (request.readyState == 4 && request.status == 200)
        {
          callback(request.responseText);
        }
      };
      request.open('GET', url);
      request.send();
    }

    function mycallback(data) {
      agent.add("DATA:" + data);
    }

    return getText(url, mycallback);
  }

  let intentMap = new Map();
  intentMap.set('test', testHandler);
  agent.handleRequest(intentMap);
});

Линия agent.add("DATA:" + data); не имеет никакого эффекта. При попытке кода в браузерах и изменении agent.add("DATA:" + data) на document.write("DATA:" + data) все работает просто отлично. Я новичок в Dialogflow; любой намек, почему этот обратный вызов не работает?

1 Ответ

1 голос
/ 20 марта 2019

При выполнении асинхронных операций (таких как вызовы сетевого API) ваш обработчик намерений должен вернуть Promise, поэтому диспетчер обработчиков знает, что нужно ждать ответа от API, прежде чем отправлять ответ пользователю , В вашем случае, когда ответ возвращается, он пытается отправить его пользователю, но, поскольку ответ уже был отправлен (ни с чем), никто его не видит.

Ваш веб-браузер обрабатывает все локально, поэтому вы не видите тех же проблем (даже если он делает то же самое).

Хотя вы, вероятно, можете обернуть свой код в Promise, более простой способ - использовать что-то вроде request-обещание-native для выполнения HTTP-вызова, сделайте вызов agent.add() в then() заблокировать и вернуть общее обещание. Возможно, что-то вроде этого:

  function testHandlerPromise(agent){
    const rp = require('request-promise-native');

    const proxyurl = "https://cors-anywhere.herokuapp.com/";
    var theUrl = "http://xxxxx/sum?a=5&b=11";
    var url = proxyurl + theUrl;

    return rp( url ).then( data => {
      agent.add("DATA:" + data);
    } );
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...