Python Google API.ai webhook post-firing node.js调用,即使没有参数值

Python Google API.ai webhook post-firing node.js调用,即使没有参数值,python,json,node.js,actions-on-google,google-home,Python,Json,Node.js,Actions On Google,Google Home,我有一个正在工作的GoogleAPI.ai项目,我和它交谈,让它打开一个组件,它将json发布到webhook URL,我的nodejs解析json,在树莓上执行python脚本。问题在于,显然只是调用欢迎意图就会触发json post并切换python脚本以打开组件。奇怪的是,if语句确定调用哪个python脚本所需的组件状态在welcome-intent状态下为空 这是我的node.js: 'use strict'; require('dotenv').config(); const Py

我有一个正在工作的GoogleAPI.ai项目,我和它交谈,让它打开一个组件,它将json发布到webhook URL,我的nodejs解析json,在树莓上执行python脚本。问题在于,显然只是调用欢迎意图就会触发json post并切换python脚本以打开组件。奇怪的是,if语句确定调用哪个python脚本所需的组件状态在welcome-intent状态下为空

这是我的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);
})

代码也会在欢迎意图上被调用,它不应该被调用。

好吧,真正的问题是,您似乎在处理所有意图,而不是基于特定意图的特定事情。使用API.AI,您有两种方法来处理此问题:

  • 您可以始终为特定目的关闭webhook resolution,为其他目的保持打开状态。在本例中,您可以出于欢迎的目的将其关闭(这将发送问候语提示等),但为其他命令处理打开它

  • 一旦您的webhook被调用,GoogleLibrary上的操作将确定要为其调用的操作调用的特定函数。这是通过
    assistant.handleRequest(actionMap)处理的

  • 在代码中,在调用
    assistant.handleRequest(actionMap)之后,会发生额外的处理。因此,每次调用都会处理此附加代码。听起来这不是你想要的


    您应该将此代码移动到使用actionMap注册的特定操作处理代码中。(我不知道您的操作是什么,但我假设将代码放在executeHomeCommand()函数中最有意义,假设其他所有操作都已正确连接。)

    好吧,真正的问题是您似乎在处理所有意图,而不是基于特定意图的特定事情。使用API.AI,您有两种方法来处理此问题:

  • 您可以始终为特定目的关闭webhook resolution,为其他目的保持打开状态。在本例中,您可以出于欢迎的目的将其关闭(这将发送问候语提示等),但为其他命令处理打开它

  • 一旦您的webhook被调用,GoogleLibrary上的操作将确定要为其调用的操作调用的特定函数。这是通过
    assistant.handleRequest(actionMap)处理的

  • 在代码中,在调用
    assistant.handleRequest(actionMap)之后,会发生额外的处理。因此,每次调用都会处理此附加代码。听起来这不是你想要的


    您应该将此代码移动到使用actionMap注册的特定操作处理代码中。(我不知道您的操作是什么,但我假设将代码放在executeHomeCommand()函数中最有意义,假设其他所有操作都已正确连接。)

    您为欢迎目的设置的操作值是多少?如果您可以发布API.AI欢迎意图的屏幕截图,这可能也会有所帮助。它将input.welcome作为操作值。我不知道我从哪里得到的。我已经看过很多例子了。但是它不是在代码中调用的。您为您的欢迎意图设置的操作值是多少?如果您可以发布API.AI欢迎意图的屏幕截图,这可能也会有所帮助。它将input.welcome作为操作值。我不知道我从哪里得到的。我已经看过很多例子了。但它不是在代码中调用的,明白了!确实如此。我忽略了这一点,因为我没有使用合适的编辑器。我想我需要让TextWrangler连接到我的rpi。谢谢!知道了!确实如此。我忽略了这一点,因为我没有使用合适的编辑器。我想我需要让TextWrangler连接到我的rpi。谢谢!
    if (soc === "on") {
            foundSwitch.setState("on");
            console.log('SWITCHING ON');