在没有Firebase的情况下,如何在对话框流实现中向其他服务发出HTTP请求?

时间:2018-11-25 01:59:47

标签: firebase google-cloud-platform dialogflow actions-on-google

我编写了一个node.js实现代码,只需使用http.request函数即可将我的消息从Dialogflow发送到另一个服务(在此代码中是邮递员)。

"use strict";

const express = require("express");
const bodyParser = require("body-parser");
const https = require('https');
const app = express();

app.use(
  bodyParser.urlencoded({
    extended: true
  })
);

app.use(bodyParser.json())

app.post("/echo", function(req, res) {
    var speech =
    req.body.queryResult &&
    req.body.queryResult.parameters && 
    req.body.queryResult.parameters.echoText
      ? req.body.queryResult.parameters.echoText
      : "Seems like some problem. Speak again.";
    
    function mainFunction(callback){    

    var options = {
      hostname : "postman-echo.com",
      path : "/post",
      method : "POST",
      headers: {
        'Content-Type': 'application/json'
    }
    };

    var body = JSON.stringify({
        message: speech
    });
    
    
    var req = https.request(options, function(res) {
        var respBody = "";
        console.log("Response from server started");
        console.log(`Server status: ${res.statusCode}`);
    });
    
    //Necessary, otherwise a socket hangup error
    req.end(body);
    
    req.on('response', function(res){
        //console.log('STATUS: ' + res.statusCode);
        res.setEncoding('utf8');

        res.on('data',function(chunk){
            var temp = JSON.parse(chunk.toString());
            //console.log('Dit is de response');
            console.log(temp.data.message);
            
            var resp_message = [];
            if (temp.data.length > 1) {
              var i;
              for (i = 0; i < temp.data.length; i++) {
                var resp_message_single = temp.data[i].message;
                resp_message.push(resp_message_single);
              };
              callback(resp_message)
            }
            else{
              var resp_message_single = temp.data.message;
              resp_message.push(resp_message_single);
              callback(resp_message)
            };
        });
    });
  };

  mainFunction(function(resp_message){
    if (resp_message.length != 1) {
      var i;
      speech = "";
      var displayText = "";
      for (i = 0; i < resp_message.length; i++) {
        speech = speech+resp_message[i]+'<break time="500ms"/>';
        displayText = displayText+resp_message[i]+" ";
      };
      speech = '<speak>'+speech+'</speak>';
    }
    else{
      speech ='<speak>'+resp_message+'</speak>';
      displayText = resp_message[0];
    };
    return res.json({
      fulfillmentText: speech,
      fulfillmentMessages:[
        {
          text: {
            text: [
              displayText
            ]
          }
        }
      ]
    });
  });

});


const port = process.env.PORT || 8000;
app.listen(port,()=> console.log(`Listening on port ${port}...`));

现在,我使用Google动作模块根据this link更新了我的代码,但没有使用Firebase。但是,我似乎无法像以前一样使用http.request函数中的assistant.intent函数。

"use strict";

const express = require("express");
const bodyParser = require("body-parser");
const https = require('https');

const {dialogflow} = require('actions-on-google');

const assistant = dialogflow();
const app = express();

app.use(
  bodyParser.urlencoded({
    extended: true
  })
);

app.use(bodyParser.json());

assistant.intent('Default Welcome Intent', (conv) => {
  conv.ask('Welkom bij test.');
});

assistant.intent('Echo', (conv) => {
var speech = conv.query    

  var options = {
    hostname : "postman-echo.com",
    path : "/post",
    method : "POST",
    headers: {
      'Content-Type': 'application/json'
  }
  };;

  var body = JSON.stringify({message: speech});
    
  var req = https.request(options, function(res) {
      var respBody = "";
  });

  req.end(body);
  
  req.on('response', function(res){
      res.setEncoding('utf8');

      res.on('data',function(chunk){
          var temp = JSON.parse(chunk.toString());
          var resp_message = [];
          if (temp.data.length != 1) {
            var i;
            for (i = 0; i < temp.data.length; i++) {
              var resp_message_single = temp.data[i].message;
              resp_message.push(resp_message_single);
            };
            callback(resp_message)
          }
          else{
            var resp_message_single = temp.data[0].message;
            resp_message.push(resp_message_single);
            callback(resp_message)
          };
      });
  });

  mainFunction(function(resp_message){
    if (resp_message.length != 1) {
      var i;
      speech = "";
      var displayText = "";
      for (i = 0; i < resp_message.length; i++) {
        speech = speech+resp_message[i]+'<break time="500ms"/>';
        displayText = displayText+resp_message[i]+" ";
      };
      speech = '<speak>'+speech+'</speak>';
    }
    else{
      speech ='<speak>'+resp_message+'</speak>';
      displayText = resp_message[0];
    };
    conv.ask(speech);
    });

});

app.post('/echo', assistant);

const port = process.env.PORT || 8000;
app.listen(port,()=> console.log(`Listening on port ${port}...`));

有人知道为什么会这样吗? Google行动模块是否可以阻止这种情况?

1 个答案:

答案 0 :(得分:0)

您在使用Google动作库的代码中遇到了一些问题。一个问题是callbackmainFunction()都没有定义-但是,这些错误隐藏了您将遇到的更大问题。

在使用Google Actions-on-Google库时(以及在使用dialogflow-fulfillment库注册Intent Handler时),如果您使用的是异步返回的函数,则应返回Promise。完全http.request的作用。

最简单的方法是切换到request-promise-native库之类的东西。

我还没有测试过,但是Echo Intent处理程序的代码可能看起来像这样:

assistant.intent('Echo', (conv) =>{
  const requestPromise = require('request-promise-native');
  const speech = conv.query;

  const options = {
    uri: "http://postman-echo.com/post",
    method: "POST",
    json: true,
    body: {
      message: speech
    }
  };

  return requestPromise( options )
    .then( body => {
      let speech = "I didn't hear anything.";
      let text   = "I didn't hear anything.";
      if (body.data && body.data.length > 0){
        speech = body.data[0].message;
        text   = body.data[0].message;
        for (let co=1; co<body.data.length; co++){
          speech += `<break time="500ms"/>${body.data[co].message}`;
          text   += ' '+body.data[co].message;
        }
      }
      speech = `<speak>${speech}</speak>`;
      return conv.ask( new SimpleResponse({
        speech: speech,
        text:   text
      }));
    });

});