问题
I have implemented a dialogFlow fulfillment without using the node js client library. I have been parsing requests and preparing responses manually. Now, I wanted to start using the node js client library, as found here: https://actions-on-google.github.io/actions-on-google-nodejs/
I am using the express framework as generated by the express generator. Here is some of the contents of my app.js:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var smarthome5 = require('./routes/smarthome5');
app.set('view engine', 'jade');
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/smarthome5',smarthome5);
module.exports = app;
my ./routes/smarthome5 contains these:
const express = require('express')
var router = express.Router();
const {dialogflow} = require('actions-on-google')
const dfApp = dialogflow()
router.post('/', dfApp)
// Register handlers for Dialogflow intents
dfApp.intent('Default Welcome Intent', conv => {
conv.ask('Hi, how is it going?')
conv.ask(`Here's a picture of a cat`)
})
// Intent in Dialogflow called `Goodbye`
dfApp.intent('Goodbye', conv => {
conv.close('See you later!')
})
dfApp.intent('Default Fallback Intent', conv => {
conv.ask(`I didn't understand. Can you tell me something else?`)
})
module.exports = router;
However, when I run the code and make a POST request to /smarthome5, I get an error like so:
SyntaxError: Unexpected number in JSON at position 1
at JSON.parse (<anonymous>)
at new User (/app/node_modules/actions-on-google/dist/service/actionssdk/conversation/user.js:75:43)
at new Conversation (/app/node_modules/actions-on-google/dist/service/actionssdk/conversation/conversation.js:73:21)
at new DialogflowConversation (/app/node_modules/actions-on-google/dist/service/dialogflow/conv.js:38:9)
at Function.<anonymous> (/app/node_modules/actions-on-google/dist/service/dialogflow/dialogflow.js:113:24)
at Generator.next (<anonymous>)
at /app/node_modules/actions-on-google/dist/service/dialogflow/dialogflow.js:22:71
at new Promise (<anonymous>)
at __awaiter (/app/node_modules/actions-on-google/dist/service/dialogflow/dialogflow.js:18:12)
at Function.handler (/app/node_modules/actions-on-google/dist/service/dialogflow/dialogflow.js:84:16)
when I try replacing the post handler in ./routes/smarthome5 with this:
router.post('/', function(req, res, next) {
console.log('POST ' + __filename);
console.dir(req.body, {depth: null});
})
I am able to see the POST request. So my routes are working it's just that I do not know if I am using the dfApp correctly.
sample post request body and error
Request body 1
originalDetectIntentRequest
headers
userStorage Field
回答1:
The issue is that your userStorage has been set to a string. The library assumes that this string is JSON and attempts to decode it. However, the library fails to handle when it isn't (likely because it ensures it is JSON when it saves it).
Fixing this will be difficult. If the code was in production, you can view and clear the user storage, but this isn't available before it is listed in the directory. You can clear the user storage in code - but this error is happening when it initializes the request, so you need to do this first. (And you only need to do this the first time for each user you've tested with.) In the line router.post('/', dfApp)
, instead of calling the dfApp
function directly, call a function that modifies req.body
to remove or reset that field from the JSON. I haven't tested, but possibly something like
router.post('/', function( req, res ){
req.body.originalDetectIntentRequest.payload.user.userStorage='{}';
dfApp( req, res );
});
If you really need to preserve that ID (instead of just generating a new one), you can do so there as well, but make sure the string is a valid JSON string.
Going forward, you should treat conv.user.storage
as an object. Storing a user ID there would be done with something like
conv.user.storage.id = generateId();
(Or pick some attribute name that works for you.)
回答2:
The Actions-On-Google NodeJS client's Github pages show different ways to build your agent. There is also a code snippet showing the use of Express to develop a webhook. Check out the Readme here. It is all covered.
UPDATE
here you have it
'use strict';
const {dialogflow} = require('actions-on-google');
const express = require('express');
const bodyParser = require('body-parser');
const app = dialogflow();
app.intent('Default Welcome Intent', conv => {
conv.ask('Hi, Welcome to Assistant by Express JS ');
});
express().use(bodyParser.json(), app).listen(8080);
来源:https://stackoverflow.com/questions/51925556/how-to-use-the-node-js-client-library-with-express