简体   繁体   English

DialogFlow:如何处理具有多个路由的 NodeJS 服务器?

[英]DialogFlow: How do you handle a NodeJS server with multiple routes?

I am creating a project in DialogFlow and NodeJS where I want to call my fulfillments with a webhook.我正在 DialogFlow 和 NodeJS 中创建一个项目,我想用 webhook 调用我的实现。 In my NodeJS server, I have multiple routes for different functions/intents.在我的 NodeJS 服务器中,我有多个路由用于不同的功能/意图。 For example, /getWeather calls a weather API to return a response about the weather in a specific city.例如,/getWeather 调用天气 API 以返回有关特定城市天气的响应。 Or /getMovie calls an API to return information about a movie.或者 /getMovie 调用 API 以返回有关电影的信息。

DialogFlow only allows for one webhook API, so my question is, how can I call a generic API "/" where it can handle all the different routes and call the correct route when it needs to? DialogFlow 只允许一个 webhook API,所以我的问题是,我怎样才能调用一个通用的 API “/”,它可以处理所有不同的路由并在需要时调用正确的路由?

I can use the inline editor on DialogFlow to call each API with the correct route;我可以使用 DialogFlow 上的内联编辑器以正确的路线调用每个 API; however, I want to use a single webhook rather than using the firebase functions to call the correct intents.但是,我想使用单个 webhook 而不是使用 firebase 函数来调用正确的意图。

I can't seem to find example of this online where multiple routes are handled with a generic route.我似乎无法在网上找到使用通用路由处理多条路由的示例。

Image of my Code Stack我的代码堆栈的图像

index.js: 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应用程序.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;

Example of one of my routes: getMovie.js我的一条路线示例:getMovie.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;

It is very clear that Dialogflow allows one webhook POST url where every call for intents are made.很明显,Dialogflow 允许一个 webhook POST url,其中每次调用意图。 IF you want to use different API services inside then You should define a webhook and inside the webhook just call the functions which are related to intents using intentMAP.如果您想在内部使用不同的 API 服务,那么您应该定义一个 webhook,并且在 webhook 内部只需使用 intentMAP 调用与意图相关的函数。 On each function call the external API and return the response back to dialogflow.在每个 function 上调用外部 API 并将响应返回给对话流。 I will describe a bit more about it using dialogflow-fulfillment.我将使用 dialogflow-fulfillment 对其进行更多描述。

first thing you need is a webhook POST route for handling dialogflow requests and responses and inside it you need to map intents to its specific function as like:您需要的第一件事是用于处理对话流请求和响应的 webhook POST 路由,在其中您需要 map 意图到其特定的 function ,如下所示:

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

Now create another file for external API calls which will be like现在为外部 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");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM