Как сделать http запрос к другому сервису при выполнении диалогового потока без firebase? - PullRequest
0 голосов
/ 25 ноября 2018

Я написал код выполнения node.js для отправки своих сообщений из Dialogflow в другие службы (в данном коде это почтальон), просто используя функцию http.request.

"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}...`));

Теперь я обновил свой код в соответствии с этой ссылкой с помощью модуля actions-on-google, но без 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}...`));

Кто-нибудь знает, почему это происходит?Модуль Actions-on-google предотвращает это?

1 Ответ

0 голосов
/ 26 ноября 2018

У вас есть несколько проблем в коде, который использует библиотеку actions-on-google.Одна из проблем заключается в том, что ни callback, ни mainFunction() не определены, однако эти ошибки скрывают большую проблему, с которой вы столкнетесь.

При использовании библиотеки Actions-on-Google (и при регистрации IntentОбработчики, использующие библиотеку диалогового потока-выполнения (в этом отношении), вы должны вернуть Promise, если используете функцию, которая возвращает асинхронно, что и делает http.request.

Самый простой способ - эточтобы переключиться на что-то вроде библиотеки request-обещание-native .

Я не проверял это, но код для обработчика намерений Echo может выглядеть примерно так:

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
      }));
    });

});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...