Google 请求之间未存储 Google 助理位置权限
Google Assistant location permissions not stored between requests
使用 API.AI 和 Google 智能助理,我正在请求获取用户姓名和位置的权限。目的是我可以请求一次许可,后续对我的 Action 的请求将不需要再次请求(因为每次用户与我的 Action 交谈时,这都会导致对话非常生硬)。
我发现我只获得与 actions_intent_PERMISSION
相关的意图中的信息 - 即使我已经授予权限,该信息也不会在其他意图实现中发送. (在下面的示例代码中 - 它最终重新请求所有其他意图的权限。)
我也没有看到在我的操作调用之间维护此权限。因此,每次触发操作时,都会(再次)询问他们是否授予操作权限。
这两种行为看起来都很奇怪。一般而言,应用程序模型不需要我在应用程序调用之间重新授权对资源的权限,甚至在应用程序处于 "running" 时也是如此。甚至网页也会在会话期间保留授权。我做错了什么,还是这是预期的行为?
执行实现的代码(这是 Google Cloud Functions 中的 运行 并且有一些额外的结构通过 Promise 进行这些调用 - 这只是代码)。 res.send(200)
只是向 API.AI 表明它应该使用那里定义的响应,并且可以正常工作。 return Promise.resolve(null);
只是确保不执行其他 fallback/error 条件。
exports.process = function( req, res ){
var app = new ApiAiApp({request:req, response:res});
if( app.isPermissionGranted() ){
res.send( 200 );
return Promise.resolve( null );
} else {
return askPermission( req, res, app );
}
};
var askPermission = function( req, res, app ){
//app.tell('foo');
let namePermission = app.SupportedPermissions.NAME;
let preciseLocationPermission = app.SupportedPermissions.DEVICE_PRECISE_LOCATION;
// Ask for more than one permission. User can authorize all or none.
app.askForPermissions('To address you by name and know your location',
[namePermission, preciseLocationPermission]);
return Promise.resolve( null );
};
处理 actions_intent_PERMISSION
请求的 API.AI 意图:
另一个本应具有 user/location 负载但从未使用该信息调用的 Intent
模拟器的屏幕截图表明它总是请求许可,除非特别授予许可:
初始连接时发送的JSON:
{
"originalRequest": {
"source": "google",
"version": "2",
"data": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "talk to my test app",
"inputType": "KEYBOARD"
}
],
"intent": "actions.intent.MAIN"
}
],
"user": {
"locale": "en-US",
"userId": "APhe68HKWmHGe9cojGOMrX9WKQ0l"
},
"device": {},
"conversation": {
"conversationId": "1499807128489",
"type": "NEW"
}
}
},
"id": "7e301f85-4178-4be6-8b7c-408bad3ef62b",
"timestamp": "2017-07-11T21:05:28.504Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "GOOGLE_ASSISTANT_WELCOME",
"speech": "",
"action": "input.welcome",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "google_assistant_welcome",
"parameters": {},
"lifespan": 0
},
{
"name": "actions_capability_screen_output",
"parameters": {},
"lifespan": 0
},
{
"name": "actions_capability_audio_output",
"parameters": {},
"lifespan": 0
},
{
"name": "google_assistant_input_type_keyboard",
"parameters": {},
"lifespan": 0
}
],
"metadata": {
"intentId": "f31e371a-db9e-4e00-8002-546ec14d40a9",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"nluResponseTime": 2,
"intentName": "Default Welcome Intent"
},
"fulfillment": {
"speech": "I'm not sure, I'm a little confused.",
"messages": [
{
"type": 0,
"speech": "I'm not sure, I'm a little confused."
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1499807128489"
}
JSON在请求许可后发送,我已经同意了。正如预期的那样,originalRequest.data.user
有了名称,originalRequest.data.device
现在有了位置。
{
"originalRequest": {
"source": "google",
"version": "2",
"data": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "yes",
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"rawText": "yes",
"textValue": "true",
"name": "PERMISSION"
}
],
"intent": "actions.intent.PERMISSION"
}
],
"user": {
"profile": {
"displayName": "Allen Firstenberg",
"givenName": "Allen",
"familyName": "Firstenberg"
},
"locale": "en-US",
"userId": "APhe68HKWmHGe9cojGOMrX9WKQ0l"
},
"device": {
"location": {
"coordinates": {
"latitude": 37.4219806,
"longitude": -122.0841979
}
}
},
"conversation": {
"conversationId": "1499807128489",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google_\"]"
}
}
},
"id": "7a75593e-55d0-4962-ad91-564d47e5df13",
"timestamp": "2017-07-11T21:05:43.391Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "actions_intent_PERMISSION",
"speech": "",
"action": "",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "actions_capability_screen_output",
"parameters": {},
"lifespan": 0
},
{
"name": "_actions_on_google_",
"parameters": {},
"lifespan": 99
},
{
"name": "actions_intent_permission",
"parameters": {
"PERMISSION": "true"
},
"lifespan": 0
},
{
"name": "actions_capability_audio_output",
"parameters": {},
"lifespan": 0
},
{
"name": "google_assistant_input_type_keyboard",
"parameters": {},
"lifespan": 0
}
],
"metadata": {
"intentId": "5d154d71-63f1-43a9-9c18-70d78bfd700f",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"nluResponseTime": 1,
"intentName": "Location result"
},
"fulfillment": {
"speech": "you're allowed",
"messages": [
{
"type": 0,
"speech": "you're allowed"
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1499807128489"
}
JSON 在我授予许可(上)后发送,然后发出 "simple test" 短语。请注意,用户和设备字段缺少授予权限的信息,但这是正确的意图。
{
"originalRequest": {
"source": "google",
"version": "2",
"data": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "simple test",
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"rawText": "simple test",
"textValue": "simple test",
"name": "text"
}
],
"intent": "actions.intent.TEXT"
}
],
"user": {
"locale": "en-US",
"userId": "APhe68HKWmHGe9cojGOMrX9WKQ0l"
},
"device": {},
"conversation": {
"conversationId": "1499807128489",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google_\"]"
}
}
},
"id": "f1804e02-bafc-4656-8726-0955bfb4f75d",
"timestamp": "2017-07-11T21:05:55.001Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "simple test",
"speech": "",
"action": "",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "actions_capability_screen_output",
"parameters": {},
"lifespan": 0
},
{
"name": "_actions_on_google_",
"parameters": {},
"lifespan": 98
},
{
"name": "actions_capability_audio_output",
"parameters": {},
"lifespan": 0
},
{
"name": "google_assistant_input_type_keyboard",
"parameters": {},
"lifespan": 0
}
],
"metadata": {
"intentId": "48257e82-3615-4445-8ea2-be21980b7115",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"nluResponseTime": 4,
"intentName": "simple test"
},
"fulfillment": {
"speech": "",
"messages": [
{
"type": 0,
"speech": ""
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1499807128489"
}
在两个会话之间执行此操作会产生相同类型的结果。
这是预期的行为。现在我们建议在您的一端保留用户许可的数据,由用户 ID 键入。要了解我们如何建议这样做,请查看 Name Psychic sample. In that sample, we use Firebase Realtime DB 以在 intents/conversations 中为该用户保留许可数据。
使用 API.AI 和 Google 智能助理,我正在请求获取用户姓名和位置的权限。目的是我可以请求一次许可,后续对我的 Action 的请求将不需要再次请求(因为每次用户与我的 Action 交谈时,这都会导致对话非常生硬)。
我发现我只获得与 actions_intent_PERMISSION
相关的意图中的信息 - 即使我已经授予权限,该信息也不会在其他意图实现中发送. (在下面的示例代码中 - 它最终重新请求所有其他意图的权限。)
我也没有看到在我的操作调用之间维护此权限。因此,每次触发操作时,都会(再次)询问他们是否授予操作权限。
这两种行为看起来都很奇怪。一般而言,应用程序模型不需要我在应用程序调用之间重新授权对资源的权限,甚至在应用程序处于 "running" 时也是如此。甚至网页也会在会话期间保留授权。我做错了什么,还是这是预期的行为?
执行实现的代码(这是 Google Cloud Functions 中的 运行 并且有一些额外的结构通过 Promise 进行这些调用 - 这只是代码)。 res.send(200)
只是向 API.AI 表明它应该使用那里定义的响应,并且可以正常工作。 return Promise.resolve(null);
只是确保不执行其他 fallback/error 条件。
exports.process = function( req, res ){
var app = new ApiAiApp({request:req, response:res});
if( app.isPermissionGranted() ){
res.send( 200 );
return Promise.resolve( null );
} else {
return askPermission( req, res, app );
}
};
var askPermission = function( req, res, app ){
//app.tell('foo');
let namePermission = app.SupportedPermissions.NAME;
let preciseLocationPermission = app.SupportedPermissions.DEVICE_PRECISE_LOCATION;
// Ask for more than one permission. User can authorize all or none.
app.askForPermissions('To address you by name and know your location',
[namePermission, preciseLocationPermission]);
return Promise.resolve( null );
};
处理 actions_intent_PERMISSION
请求的 API.AI 意图:
另一个本应具有 user/location 负载但从未使用该信息调用的 Intent
模拟器的屏幕截图表明它总是请求许可,除非特别授予许可:
初始连接时发送的JSON:
{
"originalRequest": {
"source": "google",
"version": "2",
"data": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "talk to my test app",
"inputType": "KEYBOARD"
}
],
"intent": "actions.intent.MAIN"
}
],
"user": {
"locale": "en-US",
"userId": "APhe68HKWmHGe9cojGOMrX9WKQ0l"
},
"device": {},
"conversation": {
"conversationId": "1499807128489",
"type": "NEW"
}
}
},
"id": "7e301f85-4178-4be6-8b7c-408bad3ef62b",
"timestamp": "2017-07-11T21:05:28.504Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "GOOGLE_ASSISTANT_WELCOME",
"speech": "",
"action": "input.welcome",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "google_assistant_welcome",
"parameters": {},
"lifespan": 0
},
{
"name": "actions_capability_screen_output",
"parameters": {},
"lifespan": 0
},
{
"name": "actions_capability_audio_output",
"parameters": {},
"lifespan": 0
},
{
"name": "google_assistant_input_type_keyboard",
"parameters": {},
"lifespan": 0
}
],
"metadata": {
"intentId": "f31e371a-db9e-4e00-8002-546ec14d40a9",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"nluResponseTime": 2,
"intentName": "Default Welcome Intent"
},
"fulfillment": {
"speech": "I'm not sure, I'm a little confused.",
"messages": [
{
"type": 0,
"speech": "I'm not sure, I'm a little confused."
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1499807128489"
}
JSON在请求许可后发送,我已经同意了。正如预期的那样,originalRequest.data.user
有了名称,originalRequest.data.device
现在有了位置。
{
"originalRequest": {
"source": "google",
"version": "2",
"data": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "yes",
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"rawText": "yes",
"textValue": "true",
"name": "PERMISSION"
}
],
"intent": "actions.intent.PERMISSION"
}
],
"user": {
"profile": {
"displayName": "Allen Firstenberg",
"givenName": "Allen",
"familyName": "Firstenberg"
},
"locale": "en-US",
"userId": "APhe68HKWmHGe9cojGOMrX9WKQ0l"
},
"device": {
"location": {
"coordinates": {
"latitude": 37.4219806,
"longitude": -122.0841979
}
}
},
"conversation": {
"conversationId": "1499807128489",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google_\"]"
}
}
},
"id": "7a75593e-55d0-4962-ad91-564d47e5df13",
"timestamp": "2017-07-11T21:05:43.391Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "actions_intent_PERMISSION",
"speech": "",
"action": "",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "actions_capability_screen_output",
"parameters": {},
"lifespan": 0
},
{
"name": "_actions_on_google_",
"parameters": {},
"lifespan": 99
},
{
"name": "actions_intent_permission",
"parameters": {
"PERMISSION": "true"
},
"lifespan": 0
},
{
"name": "actions_capability_audio_output",
"parameters": {},
"lifespan": 0
},
{
"name": "google_assistant_input_type_keyboard",
"parameters": {},
"lifespan": 0
}
],
"metadata": {
"intentId": "5d154d71-63f1-43a9-9c18-70d78bfd700f",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"nluResponseTime": 1,
"intentName": "Location result"
},
"fulfillment": {
"speech": "you're allowed",
"messages": [
{
"type": 0,
"speech": "you're allowed"
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1499807128489"
}
JSON 在我授予许可(上)后发送,然后发出 "simple test" 短语。请注意,用户和设备字段缺少授予权限的信息,但这是正确的意图。
{
"originalRequest": {
"source": "google",
"version": "2",
"data": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "simple test",
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"rawText": "simple test",
"textValue": "simple test",
"name": "text"
}
],
"intent": "actions.intent.TEXT"
}
],
"user": {
"locale": "en-US",
"userId": "APhe68HKWmHGe9cojGOMrX9WKQ0l"
},
"device": {},
"conversation": {
"conversationId": "1499807128489",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google_\"]"
}
}
},
"id": "f1804e02-bafc-4656-8726-0955bfb4f75d",
"timestamp": "2017-07-11T21:05:55.001Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "simple test",
"speech": "",
"action": "",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "actions_capability_screen_output",
"parameters": {},
"lifespan": 0
},
{
"name": "_actions_on_google_",
"parameters": {},
"lifespan": 98
},
{
"name": "actions_capability_audio_output",
"parameters": {},
"lifespan": 0
},
{
"name": "google_assistant_input_type_keyboard",
"parameters": {},
"lifespan": 0
}
],
"metadata": {
"intentId": "48257e82-3615-4445-8ea2-be21980b7115",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"nluResponseTime": 4,
"intentName": "simple test"
},
"fulfillment": {
"speech": "",
"messages": [
{
"type": 0,
"speech": ""
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1499807128489"
}
在两个会话之间执行此操作会产生相同类型的结果。
这是预期的行为。现在我们建议在您的一端保留用户许可的数据,由用户 ID 键入。要了解我们如何建议这样做,请查看 Name Psychic sample. In that sample, we use Firebase Realtime DB 以在 intents/conversations 中为该用户保留许可数据。