Google API.ai запустил webhook после запуска вызова node.js даже без значения параметра
У меня есть работающий проект Google API.ai, с которым я разговариваю, и я прошу его включить компонент, он отправляет json по URL-адресу webhook, и мой nodejs анализирует json для выполнения сценария python на малине. Проблема в том, что, по-видимому, просто вызывая приветственное намерение, запускает сообщение json и переключает скрипт python для включения компонента. Странно то, что состояние компонента, требуемое оператором if для определения, какой скрипт Python вызывать, пусто в состоянии приветствия.
Это мой node.js:
'use strict';
require('dotenv').config();
const PythonShell = require('python-shell');
const fs = require('fs');
const express = require('express');
const bodyParser= require('body-parser');
const path = require('path')
const app = express();
process.env.DEBUG = 'actions-on-google:*';
let Assistant = require('actions-on-google').ApiAiAssistant;
app.use(bodyParser.json({type: 'application/json'}));
const GENERATE_ANSWER_ACTION = 'generate_answer';
const EXECUTE_HOME_COMMAND = 'execute_home_command';
const switches = [];
var readableStream = fs.createReadStream('saveState.json');
var data = ''
readableStream.on('data', function(chunk) {
data+=chunk;
});
readableStream.on('end', function() {
var parsed = JSON.parse(data);
for (var i=0;i<parsed.switches.length;i++){
switches.push(new Switch(parsed.switches[i]))
}
});
function Switch(switchValues){
this.id = switchValues.id || "sw"
this.state = switchValues.state || "off"
this.name = switchValues.name || "switch"
this.toggle = function(){
if(this.state === "on"){
this.setState("off")
}
else{
this.setState("on");
}
}
this.setState = function(state){
var str = state === "on" ? onString(this.id[2]) : offString(this.id[2]);
PythonShell.run(str, function (err) {
if (!process.env.DEV){
if (err) throw err;
}
});
this.state = state
}
this.setState(this.state);
}
function onString(number){
return './public/python/sw' + number + '_on.py'
}
function offString(number){
return './public/python/sw' + number + '_off.py'
}
function getSwitch(string){
return switches.filter(function(element){
return element.id === string;
})[0]
}
function saveState (){
var formattedState = {
switches: switches
}
fs.writeFile('./saveState.json', JSON.stringify(formattedState) )
}
app.use(bodyParser.urlencoded({ extended: true }))
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.sendFile('index');
})
// Switch Routes for API
app.get('/api/switches', function(req, res){
res.send(switches);
})
app.get('/api/switches/:id', function(req, res){
var found = getSwitch(req.params.id);
res.json(found);
})
app.post('/api/switches/:id', function(req, res){
console.log('headers: ' + JSON.stringify(req.headers));
console.log('body: ' + JSON.stringify(req.body));
const assistant = new Assistant({request: req, response: res});
let soc = assistant.getArgument('state-of-component')
function generateAnswer(assistant) {
console.log('genera answer');
assistant.ask('I\'m thinking of a number from 0 and 100. What\'s your first guess?');
}
function executeHomeCommand(assistant) {
console.log('revisear guess');
console.log(soc);
if (soc === "on") {
console.log('SUCCESS soc=ON');
} else {
console.log('FAILUER soc=OFF');
}
}
// //MAP ACTIONS to functions
let actionMap = new Map();
actionMap.set(GENERATE_ANSWER_ACTION, generateAnswer);
actionMap.set(EXECUTE_HOME_COMMAND, executeHomeCommand);
assistant.handleRequest(actionMap);
if (req.query.password === process.env.PASS){
var foundSwitch = getSwitch(req.params.id);
if (soc === "on") {
foundSwitch.setState("on");
console.log('SWITCHING ON');
} else {
foundSwitch.setState("off");
console.log('SWITCHING OFF');
}
saveState();
console.log("postSwitch "+JSON.stringify(foundSwitch));
res.json(foundSwitch);
}
else {
console.log("invalid password")
res.send("try again")
}
})
app.listen(process.env.PORT, function(){
console.log('Listening on port ' + process.env.PORT);
})
Я думал, что это был мой код app.js, делающий сообщение о желательном намерении, но я не очень уверен, потому что в желательном состоянии состояние компонента пустое, никакого значения, поэтому soc is!= "On", так что оператор if работает правильно. Проблема в том, что:
if (soc === "on") {
foundSwitch.setState("on");
console.log('SWITCHING ON');
Код вызывается также по желанию и не должен.
1 ответ
Ну, настоящая проблема в том, что вы, кажется, делаете обработку для всех намерений, а не для конкретных вещей, основанных на определенных намерениях. С API.AI у вас есть два способа справиться с этим:
Вы всегда можете отключить разрешение webhook для определенного Намерения и оставить его включенным для других Намерений. В этом случае вы можете оставить его для вашего приветственного намерения (которое будет отправлять приветствие и т. Д.), Но включить его для обработки других команд.
Как только ваш webhook вызван, библиотека actions-on-google определяет конкретную функцию для вызова Action, для которой она была вызвана. Это обрабатывается через
assistant.handleRequest(actionMap);
линия.
В вашем коде у вас есть дополнительная обработка после вызова assistant.handleRequest(actionMap);
, Таким образом, этот дополнительный код обрабатывается для каждого вызова. Похоже, это не то, что вы хотите.
Вы должны переместить этот код в конкретный код обработки действий, который зарегистрирован в actionMap. (Я не знаю, каковы ваши действия, но я предполагаю, что размещение кода только в функции executeHomeCommand() было бы наиболее целесообразным, предполагая, что все остальное правильно подключено.)