DialogFlow: Как вы обрабатываете сервер NodeJS с несколькими маршрутами? - PullRequest
0 голосов
/ 06 апреля 2020

Я создаю проект в DialogFlow и NodeJS, где я хочу назвать свои достижения с помощью webhook. На моем NodeJS сервере у меня есть несколько маршрутов для разных функций / намерений. Например, / getWeather вызывает API погоды, чтобы вернуть ответ о погоде в указанном c городе. Или / getMov ie вызывает API для возврата информации о mov ie.

DialogFlow допускает только один API-интерфейс webhook, поэтому мой вопрос в том, как я могу вызвать универсальный c API "/", где он может обрабатывать все различные маршруты и вызывать правильный маршрут, когда это необходимо?

Я могу использовать встроенный редактор DialogFlow для вызова каждого API с правильным маршрутом; тем не менее, я хочу использовать один веб-крюк, а не использовать функции firebase для вызова правильных намерений.

Мне не удается найти пример этого онлайн, где несколько маршрутов обрабатываются с помощью общего c маршрута ,

Изображение моего стека кодов

index. js:

const http = require('http');
const app = require('./app');

const port = process.env.PORT || 3000;

const server = http.createServer(app);

server.listen(port);

server.post

app. js

const express = require('express');
const app = express();
const morgan = require('morgan');
const bodyParser = require('body-parser');
const mongoose= require('mongoose');

const issuesRoutes = require('./API/Routes/issues');
const movieRoute = require('./API/Routes/getmovie');
const resolvedtaskroute = require('./API/Routes/resolvedtask');
const newtaskRoute = require('./API/Routes/newtask');

mongoose.connect('link', {
  useNewUrlParser: true,
  useUnifiedTopology: true
})
.then(() => console.log('MongoDB connected...'))
.catch(err => console.log(err));

app.use(morgan('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use((req, res, next) => {
  res.header('Acces-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', '*');
  if (req.method === 'OPTIONS'){
    res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
    return res.status(200).json({});
  }
  next();
});

//routes to handle requests
app.use('/issues', issuesRoutes);
app.use('/newtask', newtaskRoute);
app.use('/resolvedtask', resolvedtaskroute);
app.use('/getmovie', movieRoute);

//error handling
app.use((req, res, next) => {
  const error = new Error('Not Found');
  error.status = 404;
  next(error);
})

app.use((error, req, res, next) => {
  res.status(error.status || 500);
  res.json({
    error: {
      message: error.message
    }
  })
})

module.exports = app;

Пример одного из моих маршрутов: getMov ie. js

const express = require('express');
const router = express.Router();

const http = require('http');

router.post('/', (req, res, next) => {
    const movieToSearch = req.body.queryResult.parameters.movie;


    const API_KEY = 'XXXXX';
    const reqUrl = `http://www.omdbapi.com/?t=${movieToSearch}&apikey=${API_KEY}`
    http.get(
        reqUrl,
        responseFromAPI => {
            let completeResponse = ''
            responseFromAPI.on('data', chunk => {
                completeResponse += chunk
            })
            responseFromAPI.on('end', () => {
                const movie = JSON.parse(completeResponse)

                let dataToSend = movieToSearch
                dataToSend = `${movie.Title} was released in the year ${movie.Year}. It is directed by ${
                    movie.Director
                    } and stars ${movie.Actors}.
                }`

                return res.json({
                    fulfillmentText: dataToSend,
                    source: 'getmovie'
                })
            })
        },
        error => {
            return res.json({
                fulfillmentText: 'Could not get results at this time',
                source: 'getmovie'
            })
        }
    )
})

module.exports = router;

1 Ответ

0 голосов
/ 06 апреля 2020

Совершенно очевидно, что Dialogflow допускает один URL-адрес POST веб-крюка, где выполняется каждый вызов намерений. Если вы хотите использовать различные службы API внутри, тогда вы должны определить webhook, а внутри webhook просто вызывать функции, связанные с намерениями, используя intentMAP. Для каждой функции вызовите внешний API и верните ответ обратно в диалог. Я опишу немного больше об этом, используя dialogflow-выполнение.

Первое, что вам нужно, это POST-маршрут webhook для обработки запросов и ответов диалогового потока, и внутри него вам нужно сопоставить намерения с его конкретной c функцией как как:

const { WebhookClient } = require("dialogflow-fulfillment");
const movieService= require("your function for movie API");
router.post("/", async (req, res, next) => {
const agent = new WebhookClient({ request: req, response: res });
const movie = new movieService(agent);
let intentMap = new Map();

intentMap.set("Movie Intent", () => {
//make an api call inside this function
return movie.getinfo();
});

if (agent.intent) {
agent.handleRequest(intentMap);
}
});

Теперь создайте еще один файл для внешних вызовов API, который будет выглядеть как

async getMovie(){
// get all required paramters from dialogflow here and call APIS and return back response using
agent.add("The info about movie is");
}
...