![](/img/trans.png)
[英]cMalformedResponse: Webhook error (206) whilst a seemingly valid webhook response - Actions on Google Dialogflow app in Node.js
[英]Google Actions API webhook response on Heroku nodejs
问题:Google Actions是否总是通过在每个用户输入上触发webhook帖子而始终起作用,而我仅需工作逻辑以便每次都解析json并仅在找到我感兴趣的参数时做出反应? 还是有一种方法可以控制Google Actions API所发布的Webhook帖子,以便仅在通过包含相关参数的值来完全填充该操作时才发布它?
#详细信息:我已经在Heroku上部署了这个nodejs应用程序: https : //github.com/quique123/myjsonparser/blob/master/app.js
我将它用作Google Actions API(数字精灵)示例的网络挂钩。 在“数字精灵”中,用户使用“与数字精灵对话”开始游戏。 精灵回应我以为我想一个数字...猜对了。 用户用一个数字回答,然后(并且只有这样)才运行逻辑以将猜测与答案进行比较。
但是我在Google Home的每个帖子请求上都进行了api调用。 换句话说,每次用户与会话api交互时,都会发出webhook帖子。 在此处可以看到,该主体不包含用户输入参数,并且Heroku响应“与数字精灵对话”:
2017-04-30T19:00:31.901297+00:00 app[web.1]: headers: {"host":"myjsonparser.herokuapp.com","connection":"close","accept":"*/*","content-type":"application/json; charset=UTF-8","cache-control":"no-cache","pragma":"no-cache","user-agent":"Java/1.8.0_112","x-request-id":"5a7a2c31-9ce5-4b02-9bac-bcef55ad6818","x-forwarded-for":"54.224.155.160","x-forwarded-proto":"https","x-forwarded-port":"443","via":"1.1 vegur","connect-time":"1","x-request-start":"1493578831899","total-route-time":"0","content-length":"573"}
2017-04-30T19:00:31.901347+00:00 app[web.1]: body: {"id":"5478dfb5-54f3-451d-b975-4f984d1ce3cb","timestamp":"2017-04-30T19:00:31.858Z","lang":"en","result":{"source":"agent","resolvedQuery":"44","speech":"","action":"check_guess","actionIncomplete":false,"parameters":{"check_guess":"44"},"contexts":[],"metadata":{"intentId":"c863e1e2-c850-45d8-9b96-b57e0b1ee77e","webhookUsed":"true","webhookForSlotFillingUsed":"false","intentName":"provide_guess"},"fulfillment":{"speech":"","messages":[{"type":0,"speech":""}]},"score":1},"status":{"code":200,"errorType":"success"},"sessionId":"ff2e0c97-552b-40d3-8f06-32e612476897"}
2017-04-30T19:00:31.903553+00:00 app[web.1]: postSwitch {"id":"sw1","state":"on","name":"Koko's Lamp"}
2017-04-30T19:00:31.907017+00:00 heroku[router]: at=info method=POST path="/API/switches/sw1?password=123456" host=myjsonparser.herokuapp.com request_id=5a7a2c31-9ce5-4b02-9bac-bcef55ad6818 fwd="54.224.155.160" dyno=web.1 connect=1ms service=5ms status=200 bytes=253 protocol=https
而且,当我使用Google Actions API上的数字对其进行测试时,您可以在Heroku的“ 44”响应中看到其中包含check_guess:
2017-04-30T19:00:31.901297+00:00 app[web.1]: headers: {"host":"myjsonparser.herokuapp.com","connection":"close","accept":"*/*","content-type":"application/json; charset=UTF-8","cache-control":"no-cache","pragma":"no-cache","user-agent":"Java/1.8.0_112","x-request-id":"5a7a2c31-9ce5-4b02-9bac-bcef55ad6818","x-forwarded-for":"54.224.155.160","x-forwarded-proto":"https","x-forwarded-port":"443","via":"1.1 vegur","connect-time":"1","x-request-start":"1493578831899","total-route-time":"0","content-length":"573"} 2017-04-30T19:00:31.901347+00:00 app[web.1]: body: {"id":"5478dfb5-54f3-451d-b975-4f984d1ce3cb","timestamp":"2017-04-30T19:00:31.858Z","lang":"en","result":{"source":"agent","resolvedQuery":"44","speech":"","action":"check_guess","actionIncomplete":false,"parameters":{"check_guess":"44"},"contexts":[],"metadata":{"intentId":"c863e1e2-c850-45d8-9b96-b57e0b1ee77e","webhookUsed":"true","webhookForSlotFillingUsed":"false","intentName":"provide_guess"},"fulfillment":{"speech":"","messages":[{"type":0,"speech":""}]},"score":1},"status":{"code":200,"errorType":"success"},"sessionId":"ff2e0c97-552b-40d3-8f06-32e612476897"} 2017-04-30T19:00:31.903553+00:00 app[web.1]: postSwitch {"id":"sw1","state":"on","name":"Koko's Lamp"} 2017-04-30T19:00:31.907017+00:00 heroku[router]: at=info method=POST path="/API/switches/sw1?password=123456" host=myjsonparser.herokuapp.com request_id=5a7a2c31-9ce5-4b02-9bac-bcef55ad6818 fwd="54.224.155.160" dyno=web.1 connect=1ms service=5ms status=200 bytes=253 protocol=https
问题是在两种情况下都发生postSwitch {}。
这是Google Actions始终可以工作的方式,我只需要工作逻辑以便每次都解析json并仅在找到check_guess时作出反应? 还是有一种方法可以控制Google Actions API发出的webhook帖子,以便仅在通过包含参数check_guess的值来完全填充该操作时才发布它?
您只能设置一个webhook(一个静态URL),该Webhook将被API.AI触发的所有操作调用。 尽管您将需要解析JSON(使用node.js,但JSON.parse()并不困难),但您应该使用result.action
字段,而不是试图弄清楚设置了哪些参数。 这将与您在API.AI中设置的“操作”字段相对应。
当然,这假设您已选中了Webhook框以进行操作。 如果没有,您将根本不会接到网络电话。
因此,例如,将起始意图配置如下:
它将将此JSON发送到您的webhook。
{
"originalRequest": {
"source": "google",
"data": {
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
},
"inputs": [
{
"arguments": [],
"intent": "assistant.intent.action.MAIN",
"raw_inputs": [
{
"query": "talk to number genie",
"input_type": 2,
"annotation_sets": []
}
]
}
],
"user": {
"user_id": "kQmX8nX9ovcS9jfb3WKmwLk9YFlHGZH05YGbc8muNI8=",
"permissions": []
},
"device": {
"locale": "en-US"
},
"is_in_sandbox": true,
"conversation": {
"conversation_id": "1493637016599",
"type": 1
}
}
},
"id": "9444bfe4-3c23-487a-84e7-fcbf1708d9e3",
"timestamp": "2017-05-01T11:10:16.694Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "GOOGLE_ASSISTANT_WELCOME",
"speech": "",
"action": "generate_answer",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "game",
"parameters": {},
"lifespan": 5
},
{
"name": "google_assistant_welcome",
"parameters": {},
"lifespan": 0
},
{
"name": "actions_capability_audio_output",
"parameters": {},
"lifespan": 0
}
],
"metadata": {
"intentId": "56da4637-0419-46b2-b851-d7bf726b1b1b",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"intentName": "start_game"
},
"fulfillment": {
"speech": "",
"messages": [
{
"type": 0,
"speech": ""
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1493637016599"
}
虽然Provide_guess意图可能是这样配置的
并将此JSON提供给webhook:
{
"originalRequest": {
"source": "google",
"data": {
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
},
"inputs": [
{
"arguments": [
{
"raw_text": "42",
"text_value": "42",
"name": "text"
}
],
"intent": "assistant.intent.action.TEXT",
"raw_inputs": [
{
"query": "42",
"input_type": 2,
"annotation_sets": []
}
]
}
],
"user": {
"user_id": "kQmX8nX9ovcS9jfb3WKmwLk9YFlHGZH05YGbc8muNI8=",
"permissions": []
},
"device": {
"locale": "en-US"
},
"is_in_sandbox": true,
"conversation": {
"conversation_token": "[\"_actions_on_google_\",\"game\"]",
"conversation_id": "1493637749915",
"type": 2
}
}
},
"id": "09997ef5-5c0f-4c60-a69f-af06d6e4e3f5",
"timestamp": "2017-05-01T11:22:34.377Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "42",
"speech": "",
"action": "check_guess",
"actionIncomplete": false,
"parameters": {
"guess": "42"
},
"contexts": [
{
"name": "game",
"parameters": {
"guess.original": "42",
"guess": "42"
},
"lifespan": 5
},
{
"name": "_actions_on_google_",
"parameters": {
"guessCount": 0,
"printed": "Welcome back to Number Genie. I'm thinking of a number from %s to %s. What's your first guess?",
"guess.original": "42",
"answer": 74,
"guess": "42",
"lastPrompt": "Welcome back to Number Genie. I'm thinking of a number from %s to %s. What's your first guess?",
"steamSoundCount": 0,
"fallbackCount": 0
},
"lifespan": 99
},
{
"name": "actions_capability_audio_output",
"parameters": {
"guess.original": "42",
"guess": "42"
},
"lifespan": 0
}
],
"metadata": {
"intentId": "1e46ffc2-651f-4ac0-a54e-9698feb88880",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"intentName": "provide_guess"
},
"fulfillment": {
"speech": "",
"messages": [
{
"type": 0,
"speech": ""
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1493637749915"
}
在您的代码中,您将在postSwitch()
方法中检查result.action
的值,然后可以基于此操作在您的终端上选择确切的操作checkGuess()
基于注释掉的代码,可以是generateAnswer()
或checkGuess()
) 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.