Сделать синхронный звонок, используя Node.js и Express for Action на Google? - PullRequest
0 голосов
/ 06 июня 2018

Я использую сервер Node.js с Express для взаимодействия с Actions в Google.Для выполнения запроса мне нужно подключиться к внешнему серверу, поэтому я использую библиотеку Fetch.Я не могу заставить сервер узла ждать, пока вызов веб-службы выдаст соответствующий ответ.Я пытался использовать Promises и Await / Async, но я не реализовал это правильно .. Может кто-нибудь, пожалуйста, помогите сделать эту работу?Спасибо!

let fetch = require('node-fetch');
let express = require('express');
let bodyParser = require('body-parser');
let { dialogflow, Image } = require('actions-on-google');
let app = dialogflow();
let json;

function middleware(req,res,next) {
    json = req.body;
    next();
}

app.intent('StartIntent', conv => async function() {
    const response = await communicate(json);
    console.log(response);
    // Not running synchronously
    conv.ask('Need the response from above');
});

function communicate( message ) {
    let response;
    try {
        response = fetch('https://stackoverflow.com', {
            method: 'POST',
            body:   JSON.stringify(message),
            headers: {
                'Content-Type': 'application/json'
            },
        });
        return response;
    } catch(e) {
        console.log(e);
        return null;
    }
}

express().use(bodyParser.json(), middleware, app).listen(3000);

@ Prisoner верен - conv.ask () должен вызываться только после возвращения данных json из результата connect ().Однако единственное, что возвращается в объекте Promise в этот момент.Данные извлекаются правильно как объект json.

let fetch = require('node-fetch');
let express = require('express');
let bodyParser = require('body-parser');
let { dialogflow, Image } = require('actions-on-google');
let app = dialogflow();
let json;

function middleware(req,res,next) {
    json = req.body;
    next();
}

app.intent('StartIntent', conv => {
    const response = communicate(json);
    console.log("StartIntent Response:");
    console.log(response); // output: Promise { <pending> }
    // Not running synchronously :(
    console.log(response.text);
    conv.ask('Need the response from above');
});

function communicate( message ) {
    let response;
    try {
        response = fetch('https://google.com', {
            method: 'POST',
            body:   JSON.stringify(message),
            headers: {
                'Content-Type': 'application/json'
            },
        }).then(function(body) {
            return body.json();
        }).then(function(json) {
            // The data is returning successfully
            // For example: {"BTCUSD":10000}
            return json;
        }).catch(function() {
            // error handling
        });
        return response; // This is returning a pending Promise
    } catch(e) {
        console.log(e);
        return null;
    }
}

express().use(bodyParser.json(), middleware, app).listen(3006);

1 Ответ

0 голосов
/ 06 июня 2018

fetch() возвращает обещание.Вы можете связать then() вызов для communicate() и использовать ответ для conv.ask() в теле.

Вот простой пример кода, в котором используется node-fetch для вызова API и использования ответас этого звонка.(Обратите внимание, что в этом примере выполняется запрос GET к данным JSON.)

'use strict';

const { dialogflow } = require('actions-on-google');
const functions = require('firebase-functions');
const fetch = require('node-fetch');

const app = dialogflow({debug: true});

// Default Welcome Intent
app.intent('Default Welcome Intent', (conv) => {
  return apiCall().then((response) => {
    conv.ask(`Response from above ${JSON.stringify(response)}`);
  });
});

// Makes an API call to a URL to retrieve JSON data.
function apiCall() {
  const URL = 'https://example.com/data.json';
  return fetch(URL).then((response) => response.json());
}

exports.endpoint = functions.https.onRequest(app);
...