Malformed Response:从 dialogflow web hook 获取响应时出现 Webhook 错误
Malformed Ressponse: Webhook error on getting response from dialogflow web hook
我正在使用 AWS CloudAPI 调用 AWS Lambda 存储库以完成 Google(AoG) 上的操作。使用 actions-on-google NodeJS 客户端一切正常,除了从 AoG 模拟器调用时出现错误,生成“...目前没有响应。请尽快重试”
node.jsAWS Lambda代码如下,
const { dialogflow } = require('actions-on-google'),
AWS = require('aws-sdk');
const app = dialogflow({
debug: true
});
const iotData = new AWS.IotData({
endpoint: '***thing_id***.iot.us-east-1.amazonaws.com'
}),
name = '***thing_name***',
/** The parameters required to retrieve the state of the endpoint */
paramsToGetThing = {
thingName: name
};
/**
* Notify the AWS IoT endpoint on command
* @param {DialogflowConversation} conv DialogflowConversation instance
* @return {void}
*/
app.intent('Notify IoT Intent', (conv) => {
console.log('Inside Notify IoT Intent function');
return new Promise((resolve, reject) => {
iotData.getThingShadow(paramsToGetThing, function (error, data) {
if (error) {
console.log(error, error.stack);
conv.close('Network error! Please try again after some time.');
reject(error);
} else {
const parsing = JSON.parse(data.payload);
console.log('Parsing state is ' + parsing.state.reported.connected);
if (parsing.state.reported.connected) {
console.log('Device is in online state and publish the command');
publishMessageForCommands(conv.action)
.then((response) => {
console.log('Inside publish message delay case');
setTimeout(function () {
console.log('Inside delaycheck after 2 seconds timeout function');
conv.ask(response);
resolve();
}, 2000); // Two seconds delay before speech response
})
.catch((rejectError) => {
conv.close(rejectError);
console.log('Inside CustomIntentHandler error block.');
reject();
});
} else {
console.log('Inside publish message before time out\nDevice is offline state and cannot publish the message to ' + name);
conv.close('The device is offline, please check the device and try again');
reject();
}
}
});
});
});
/**
* Error handler block
* @param {DialogflowConversation} conv DialogflowConversation instance
* @return {void}
*/
app.catch((conv, error) => {
console.error(error);
conv.ask('I encountered a glitch. Can you say that again?');
});
/**
* Default fallback intent
* @param {DialogflowConversation} conv DialogflowConversation instance
* @return {void}
*/
app.fallback((conv) => {
conv.ask(`I couldn't understand. Can you say that again?`);
});
exports.handler = app;
当我深入研究这个问题时,AWS 部分发现是干净的,如下
它也通过了 运行 on dialogflow,
当我们尝试从AoG模拟器测试它时出现问题,
报错信息如下,
{
insertId: "5a4yrqg2e6598n"
labels: {
channel: "preview"
querystream: "GOOGLE_USER"
source: "JSON_RESPONSE_VALIDATION"
}
logName: "projects/***project_name***/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2019-05-13T09:31:33.504048852Z"
resource: {
labels: {
action_id: "actions.intent.TEXT"
project_id: "***project_id***"
version_id: ""
}
type: "assistant_action"
}
severity: "ERROR"
textPayload: "MalformedResponse: Webhook error (206)"
timestamp: "2019-05-13T09:31:33.471947959Z"
trace: "projects/263334370390/traces/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ"
}
正在发送带有 post 数据的请求:
{
insertId: "1inzh7lg2hdrojj"
labels: {
channel: "preview"
querystream: "GOOGLE_USER"
source: "AOG_REQUEST_RESPONSE"
}
logName: "projects/***projecct_name***/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2019-05-13T09:31:33.503838806Z"
resource: {
labels: {
action_id: "actions.intent.TEXT"
project_id: "***project_id***"
version_id: ""
}
type: "assistant_action"
}
severity: "DEBUG"
textPayload: "Sending request with post data: {"user":{"userId":"ABwppHE6s78QlB8ah1DEkuPAxvJvH23BWfHmJOjvn1L7KVUb1DfszUh_aIMyifDw1BfPZsH5Z2T1vmQ63Xu1aw","locale":"en-IN","lastSeen":"2019-05-13T09:23:50Z"},"conversation":{"conversationId":"ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ","type":"ACTIVE","conversationToken":"[]"},"inputs":[{"intent":"actions.intent.TEXT","rawInputs":[{"inputType":"KEYBOARD","query":"notify"}],"arguments":[{"name":"text","rawText":"notify","textValue":"notify"}]}],"surface":{"capabilities":[{"name":"actions.capability.ACCOUNT_LINKING"},{"name":"actions.capability.SCREEN_OUTPUT"},{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.WEB_BROWSER"},{"name":"actions.capability.MEDIA_RESPONSE_AUDIO"}]},"isInSandbox":true,"availableSurfaces":[{"capabilities":[{"name":"actions.capability.WEB_BROWSER"},{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.SCREEN_OUTPUT"}]}],"requestType":"SIMULATOR"}."
timestamp: "2019-05-13T09:31:33.018260116Z"
trace: "projects/263334370390/traces/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ"
}
收到代理的正文响应:
{
insertId: "1inzh7lg2hdrojk"
labels: {
channel: "preview"
querystream: "GOOGLE_USER"
source: "AOG_REQUEST_RESPONSE"
}
logName: "projects/***project_name***/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2019-05-13T09:31:33.503838806Z"
resource: {
labels: {
action_id: "actions.intent.TEXT"
project_id: "***project_id***"
version_id: ""
}
type: "assistant_action"
}
severity: "DEBUG"
textPayload: "Received response from agent with body: HTTP/1.1 200 OK
Server: nginx/1.13.6
Date: Mon, 13 May 2019 09:31:33 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 4441
X-Cloud-Trace-Context: 3de98e1e9a922989893d5778d6cd1232/12117959397276118516;o=0
Google-Actions-API-Version: 2
X-SHARD: shard-2
Via: 1.1 google
Alt-Svc: clear
{"conversationToken":"[]","expectUserResponse":true,"expectedInputs":[{"inputPrompt":{"richInitialPrompt":{"items":[{"simpleResponse":{"textToSpeech":"Done"}}]}},"possibleIntents":[{"intent":"assistant.intent.action.TEXT"}]}],"responseMetadata":{"status":{"code":14,"message":"Webhook error (206)"},"queryMatchInfo":{"queryMatched":true,"intent":"8d15dee5-2250-41fd-a5c3-a5a1bf8b1014"},"delegatedRequest":{"delegatedRequest":"{\n \"responseId\": \"a8fe5f58-23a3-4d72-8f1a-7b1897257fc5\",\n \"queryResult\": {\n \"queryText\": \"notify\",\n \"action\": \"input.Notify\",\n \"parameters\": {\n },\n \"allRequiredParamsPresent\": true,\n \"fulfillmentText\": \"Done\",\n \"fulfillmentMessages\": [{\n \"text\": {\n \"text\": [\"Done\"]\n }\n }],\n \"outputContexts\": [{\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_screen_output\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_account_linking\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_audio_output\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/google_assistant_input_type_keyboard\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_web_browser\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_media_response_audio\"\n }],\n \"intent\": {\n \"name\": \"projects/aog-sample-6c818/agent/intents/8d15dee5-2250-41fd-a5c3-a5a1bf8b1014\",\n \"displayName\": \"Notify IoT Intent\"\n },\n \"intentDetectionConfidence\": 1.0,\n \"languageCode\": \"en-in\"\n },\n \"originalDetectIntentRequest\": {\n \"source\": \"google\",\n \"version\": \"2\",\n \"payload\": {\n \"isInSandbox\": true,\n \"surface\": {\n \"capabilities\": [{\n \"name\": \"actions.capability.ACCOUNT_LINKING\"\n }, {\n \"name\": \"actions.capability.SCREEN_OUTPUT\"\n }, {\n \"name\": \"actions.capability.AUDIO_OUTPUT\"\n }, {\n \"name\": \"actions.capability.WEB_BROWSER\"\n }, {\n \"name\": \"actions.capability.MEDIA_RESPONSE_AUDIO\"\n }]\n },\n \"requestType\": \"SIMULATOR\",\n \"inputs\": [{\n \"rawInputs\": [{\n \"query\": \"notify\",\n \"inputType\": \"KEYBOARD\"\n }],\n \"arguments\": [{\n \"rawText\": \"notify\",\n \"textValue\": \"notify\",\n \"name\": \"text\"\n }],\n \"intent\": \"actions.intent.TEXT\"\n }],\n \"user\": {\n \"lastSeen\": \"2019-05-13T09:23:50Z\",\n \"locale\": \"en-IN\",\n \"userId\": \"ABwppHE6s78QlB8ah1DEkuPAxvJvH23BWfHmJOjvn1L7KVUb1DfszUh_aIMyifDw1BfPZsH5Z2T1vmQ63Xu1aw\"\n },\n \"conversation\": {\n \"conversationId\": \"ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ\",\n \"type\": \"ACTIVE\",\n \"conversationToken\": \"[]\"\n },\n \"availableSurfaces\": [{\n \"capabilities\": [{\n \"name\": \"actions.capability.WEB_BROWSER\"\n }, {\n \"name\": \"actions.capability.AUDIO_OUTPUT\"\n }, {\n \"name\": \"actions.capability.SCREEN_OUTPUT\"\n }]\n }]\n }\n },\n \"session\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ\"\n}"},"delegatedResponse":{"delegatedResponse":"{\"statusCode\":200,\"body\":\"{\\"payload\\":{\\"google\\":{\\"expectUserResponse\\":true,\\"richResponse\\":{\\"items\\":[{\\"simpleResponse\\":{\\"textToSpeech\\":\\"Notified\\"}}]}}}}\",\"headers\":{\"content-type\":\"application/json;charset=utf-8\"}}"}}}."
timestamp: "2019-05-13T09:31:33.471512803Z"
trace: "projects/263334370390/traces/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ"
}
预期的行为是在 AoG 模拟器中获得响应,但我收到了错误。任何帮助将不胜感激。
@丹尼尔,
我在 AWS Lambda 上也遇到了这个问题 运行 dialogFlow。我通过拦截 actions-on-google 响应并仅将正文作为 JSON 响应发送来解决它。下面是我的示例代码。看起来 actions-on-google sdk 想要 return 200 响应,而 dialogFlow 只想要 JSON.
'use strict';
/**
- Lambda functions use a callback function that returns "error and response"
- If there is no error you can usually call the callback function with callback(null,response)
- Many NPM packages handle this callback for you so you dont actually see where the response is sent. By wrapping the lambda handler in another callback function I can see the response that google is sending from my lambda function
*/
exports.handler = (event,context,callback) => {
function googleCallbackInterceptFunction (err, response){
console.log('Google Callback');
console.log(response);
/** ^^ THis logging response shows me that google is wrapping the response in a {body:response, status:200} object. Dialogflow just wants the response so we're going to use the next line vv to pull out the response and just send that*/
response = JSON.parse(response.body);
console.log('Google Callback');
console.log(response);
/** This callback vv is the lambda callback that wraps this entire program. when this callback is fired the lambda sends a response to dialogflow and then terminates itself. Normally the actions-on-google sdk would fire this function but if it does send the wrapped response "{body:response, status:200}" dialogflow is not smart enough to find the response within the body. */
callback(null, response);
}
const {
dialogflow,
Image,
} = require('actions-on-google');
// Create an app instance
const app = dialogflow({
debug: true //THIS IS A CONFIGURATION SETTING BUILT INTO the actions-on-google SDK that WILL LOG THE REQUEST AND RESPONSES (On their own but will not show you that google is also wrapping them in a 200 response object which we dont want)
});
/** 3 basic intents that use the app.intent and conv.ask/conv.close functionality of the actions-on-google sdk. Based on these responses google will send a response that dialogflow can interpret. */
app.intent('Default Welcome Intent', conv => {
console.log('Default welcome intent HIT');
conv.ask('Hi, how is it going?');
conv.ask(`Here's a picture of a cat`);
// conv.ask(new Image({
// url: 'https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/imgs/160204193356-01-cat-500.jpg',
// alt: 'A cat',
// }))
});
// Intent in Dialogflow called `Goodbye`
app.intent('Goodbye', conv => {
conv.close('See you later!')
});
app.intent('Default Fallback Intent', conv => {
conv.ask(`I didn't understand. Can you tell me something else?`)
});
app(event,context,googleCallbackInterceptFunction);//I am initializing the actions-on-google sdk with MY callback function, not the Lambda's. This way I can log the result before the lambda responds and is termindated. MY callback function returns the result to the lambda callback function so the lambda still works as intended.
};
我正在使用 AWS CloudAPI 调用 AWS Lambda 存储库以完成 Google(AoG) 上的操作。使用 actions-on-google NodeJS 客户端一切正常,除了从 AoG 模拟器调用时出现错误,生成“...目前没有响应。请尽快重试”
node.jsAWS Lambda代码如下,
const { dialogflow } = require('actions-on-google'),
AWS = require('aws-sdk');
const app = dialogflow({
debug: true
});
const iotData = new AWS.IotData({
endpoint: '***thing_id***.iot.us-east-1.amazonaws.com'
}),
name = '***thing_name***',
/** The parameters required to retrieve the state of the endpoint */
paramsToGetThing = {
thingName: name
};
/**
* Notify the AWS IoT endpoint on command
* @param {DialogflowConversation} conv DialogflowConversation instance
* @return {void}
*/
app.intent('Notify IoT Intent', (conv) => {
console.log('Inside Notify IoT Intent function');
return new Promise((resolve, reject) => {
iotData.getThingShadow(paramsToGetThing, function (error, data) {
if (error) {
console.log(error, error.stack);
conv.close('Network error! Please try again after some time.');
reject(error);
} else {
const parsing = JSON.parse(data.payload);
console.log('Parsing state is ' + parsing.state.reported.connected);
if (parsing.state.reported.connected) {
console.log('Device is in online state and publish the command');
publishMessageForCommands(conv.action)
.then((response) => {
console.log('Inside publish message delay case');
setTimeout(function () {
console.log('Inside delaycheck after 2 seconds timeout function');
conv.ask(response);
resolve();
}, 2000); // Two seconds delay before speech response
})
.catch((rejectError) => {
conv.close(rejectError);
console.log('Inside CustomIntentHandler error block.');
reject();
});
} else {
console.log('Inside publish message before time out\nDevice is offline state and cannot publish the message to ' + name);
conv.close('The device is offline, please check the device and try again');
reject();
}
}
});
});
});
/**
* Error handler block
* @param {DialogflowConversation} conv DialogflowConversation instance
* @return {void}
*/
app.catch((conv, error) => {
console.error(error);
conv.ask('I encountered a glitch. Can you say that again?');
});
/**
* Default fallback intent
* @param {DialogflowConversation} conv DialogflowConversation instance
* @return {void}
*/
app.fallback((conv) => {
conv.ask(`I couldn't understand. Can you say that again?`);
});
exports.handler = app;
当我深入研究这个问题时,AWS 部分发现是干净的,如下
当我们尝试从AoG模拟器测试它时出现问题,
报错信息如下,
{
insertId: "5a4yrqg2e6598n"
labels: {
channel: "preview"
querystream: "GOOGLE_USER"
source: "JSON_RESPONSE_VALIDATION"
}
logName: "projects/***project_name***/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2019-05-13T09:31:33.504048852Z"
resource: {
labels: {
action_id: "actions.intent.TEXT"
project_id: "***project_id***"
version_id: ""
}
type: "assistant_action"
}
severity: "ERROR"
textPayload: "MalformedResponse: Webhook error (206)"
timestamp: "2019-05-13T09:31:33.471947959Z"
trace: "projects/263334370390/traces/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ"
}
正在发送带有 post 数据的请求:
{
insertId: "1inzh7lg2hdrojj"
labels: {
channel: "preview"
querystream: "GOOGLE_USER"
source: "AOG_REQUEST_RESPONSE"
}
logName: "projects/***projecct_name***/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2019-05-13T09:31:33.503838806Z"
resource: {
labels: {
action_id: "actions.intent.TEXT"
project_id: "***project_id***"
version_id: ""
}
type: "assistant_action"
}
severity: "DEBUG"
textPayload: "Sending request with post data: {"user":{"userId":"ABwppHE6s78QlB8ah1DEkuPAxvJvH23BWfHmJOjvn1L7KVUb1DfszUh_aIMyifDw1BfPZsH5Z2T1vmQ63Xu1aw","locale":"en-IN","lastSeen":"2019-05-13T09:23:50Z"},"conversation":{"conversationId":"ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ","type":"ACTIVE","conversationToken":"[]"},"inputs":[{"intent":"actions.intent.TEXT","rawInputs":[{"inputType":"KEYBOARD","query":"notify"}],"arguments":[{"name":"text","rawText":"notify","textValue":"notify"}]}],"surface":{"capabilities":[{"name":"actions.capability.ACCOUNT_LINKING"},{"name":"actions.capability.SCREEN_OUTPUT"},{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.WEB_BROWSER"},{"name":"actions.capability.MEDIA_RESPONSE_AUDIO"}]},"isInSandbox":true,"availableSurfaces":[{"capabilities":[{"name":"actions.capability.WEB_BROWSER"},{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.SCREEN_OUTPUT"}]}],"requestType":"SIMULATOR"}."
timestamp: "2019-05-13T09:31:33.018260116Z"
trace: "projects/263334370390/traces/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ"
}
收到代理的正文响应:
{
insertId: "1inzh7lg2hdrojk"
labels: {
channel: "preview"
querystream: "GOOGLE_USER"
source: "AOG_REQUEST_RESPONSE"
}
logName: "projects/***project_name***/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2019-05-13T09:31:33.503838806Z"
resource: {
labels: {
action_id: "actions.intent.TEXT"
project_id: "***project_id***"
version_id: ""
}
type: "assistant_action"
}
severity: "DEBUG"
textPayload: "Received response from agent with body: HTTP/1.1 200 OK
Server: nginx/1.13.6
Date: Mon, 13 May 2019 09:31:33 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 4441
X-Cloud-Trace-Context: 3de98e1e9a922989893d5778d6cd1232/12117959397276118516;o=0
Google-Actions-API-Version: 2
X-SHARD: shard-2
Via: 1.1 google
Alt-Svc: clear
{"conversationToken":"[]","expectUserResponse":true,"expectedInputs":[{"inputPrompt":{"richInitialPrompt":{"items":[{"simpleResponse":{"textToSpeech":"Done"}}]}},"possibleIntents":[{"intent":"assistant.intent.action.TEXT"}]}],"responseMetadata":{"status":{"code":14,"message":"Webhook error (206)"},"queryMatchInfo":{"queryMatched":true,"intent":"8d15dee5-2250-41fd-a5c3-a5a1bf8b1014"},"delegatedRequest":{"delegatedRequest":"{\n \"responseId\": \"a8fe5f58-23a3-4d72-8f1a-7b1897257fc5\",\n \"queryResult\": {\n \"queryText\": \"notify\",\n \"action\": \"input.Notify\",\n \"parameters\": {\n },\n \"allRequiredParamsPresent\": true,\n \"fulfillmentText\": \"Done\",\n \"fulfillmentMessages\": [{\n \"text\": {\n \"text\": [\"Done\"]\n }\n }],\n \"outputContexts\": [{\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_screen_output\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_account_linking\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_audio_output\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/google_assistant_input_type_keyboard\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_web_browser\"\n }, {\n \"name\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ/contexts/actions_capability_media_response_audio\"\n }],\n \"intent\": {\n \"name\": \"projects/aog-sample-6c818/agent/intents/8d15dee5-2250-41fd-a5c3-a5a1bf8b1014\",\n \"displayName\": \"Notify IoT Intent\"\n },\n \"intentDetectionConfidence\": 1.0,\n \"languageCode\": \"en-in\"\n },\n \"originalDetectIntentRequest\": {\n \"source\": \"google\",\n \"version\": \"2\",\n \"payload\": {\n \"isInSandbox\": true,\n \"surface\": {\n \"capabilities\": [{\n \"name\": \"actions.capability.ACCOUNT_LINKING\"\n }, {\n \"name\": \"actions.capability.SCREEN_OUTPUT\"\n }, {\n \"name\": \"actions.capability.AUDIO_OUTPUT\"\n }, {\n \"name\": \"actions.capability.WEB_BROWSER\"\n }, {\n \"name\": \"actions.capability.MEDIA_RESPONSE_AUDIO\"\n }]\n },\n \"requestType\": \"SIMULATOR\",\n \"inputs\": [{\n \"rawInputs\": [{\n \"query\": \"notify\",\n \"inputType\": \"KEYBOARD\"\n }],\n \"arguments\": [{\n \"rawText\": \"notify\",\n \"textValue\": \"notify\",\n \"name\": \"text\"\n }],\n \"intent\": \"actions.intent.TEXT\"\n }],\n \"user\": {\n \"lastSeen\": \"2019-05-13T09:23:50Z\",\n \"locale\": \"en-IN\",\n \"userId\": \"ABwppHE6s78QlB8ah1DEkuPAxvJvH23BWfHmJOjvn1L7KVUb1DfszUh_aIMyifDw1BfPZsH5Z2T1vmQ63Xu1aw\"\n },\n \"conversation\": {\n \"conversationId\": \"ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ\",\n \"type\": \"ACTIVE\",\n \"conversationToken\": \"[]\"\n },\n \"availableSurfaces\": [{\n \"capabilities\": [{\n \"name\": \"actions.capability.WEB_BROWSER\"\n }, {\n \"name\": \"actions.capability.AUDIO_OUTPUT\"\n }, {\n \"name\": \"actions.capability.SCREEN_OUTPUT\"\n }]\n }]\n }\n },\n \"session\": \"projects/aog-sample-6c818/agent/sessions/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ\"\n}"},"delegatedResponse":{"delegatedResponse":"{\"statusCode\":200,\"body\":\"{\\"payload\\":{\\"google\\":{\\"expectUserResponse\\":true,\\"richResponse\\":{\\"items\\":[{\\"simpleResponse\\":{\\"textToSpeech\\":\\"Notified\\"}}]}}}}\",\"headers\":{\"content-type\":\"application/json;charset=utf-8\"}}"}}}."
timestamp: "2019-05-13T09:31:33.471512803Z"
trace: "projects/263334370390/traces/ABwppHEjcsRXQzqvNSSYSnGKh-9pWv5_c03_IihzYMPvo7dvPGT_wfuIsvJKt3-BQKXgofT1_FILM_Z8inBiAQ"
}
预期的行为是在 AoG 模拟器中获得响应,但我收到了错误。任何帮助将不胜感激。
@丹尼尔, 我在 AWS Lambda 上也遇到了这个问题 运行 dialogFlow。我通过拦截 actions-on-google 响应并仅将正文作为 JSON 响应发送来解决它。下面是我的示例代码。看起来 actions-on-google sdk 想要 return 200 响应,而 dialogFlow 只想要 JSON.
'use strict';
/**
- Lambda functions use a callback function that returns "error and response"
- If there is no error you can usually call the callback function with callback(null,response)
- Many NPM packages handle this callback for you so you dont actually see where the response is sent. By wrapping the lambda handler in another callback function I can see the response that google is sending from my lambda function
*/
exports.handler = (event,context,callback) => {
function googleCallbackInterceptFunction (err, response){
console.log('Google Callback');
console.log(response);
/** ^^ THis logging response shows me that google is wrapping the response in a {body:response, status:200} object. Dialogflow just wants the response so we're going to use the next line vv to pull out the response and just send that*/
response = JSON.parse(response.body);
console.log('Google Callback');
console.log(response);
/** This callback vv is the lambda callback that wraps this entire program. when this callback is fired the lambda sends a response to dialogflow and then terminates itself. Normally the actions-on-google sdk would fire this function but if it does send the wrapped response "{body:response, status:200}" dialogflow is not smart enough to find the response within the body. */
callback(null, response);
}
const {
dialogflow,
Image,
} = require('actions-on-google');
// Create an app instance
const app = dialogflow({
debug: true //THIS IS A CONFIGURATION SETTING BUILT INTO the actions-on-google SDK that WILL LOG THE REQUEST AND RESPONSES (On their own but will not show you that google is also wrapping them in a 200 response object which we dont want)
});
/** 3 basic intents that use the app.intent and conv.ask/conv.close functionality of the actions-on-google sdk. Based on these responses google will send a response that dialogflow can interpret. */
app.intent('Default Welcome Intent', conv => {
console.log('Default welcome intent HIT');
conv.ask('Hi, how is it going?');
conv.ask(`Here's a picture of a cat`);
// conv.ask(new Image({
// url: 'https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/imgs/160204193356-01-cat-500.jpg',
// alt: 'A cat',
// }))
});
// Intent in Dialogflow called `Goodbye`
app.intent('Goodbye', conv => {
conv.close('See you later!')
});
app.intent('Default Fallback Intent', conv => {
conv.ask(`I didn't understand. Can you tell me something else?`)
});
app(event,context,googleCallbackInterceptFunction);//I am initializing the actions-on-google sdk with MY callback function, not the Lambda's. This way I can log the result before the lambda responds and is termindated. MY callback function returns the result to the lambda callback function so the lambda still works as intended.
};