在请求之间未存储Google Assistant位置权限 [英] Google Assistant location permissions not stored between requests

查看:82
本文介绍了在请求之间未存储Google Assistant位置权限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用API​​.AI和Google助手来获取用户名和位置的权限。目的是我将能够一次请求许可,以后对我的Action的请求将不再需要再次提出请求(因为这将使用户每次与我的Action交谈时都会进行非常严格的对话)。



我发现我只是将意图中的信息与 actions_intent_PERMISSION 绑定在一起-信息是即使我已经授予了许可,也不会发送其他意图。 (在下面的示例代码中,它最终重新请求了所有其他意图的权限。)



我也没有看到在调用两次之间保持该权限。我的行动。因此,每次触发该操作时,都会(再次)询问他们是否授予该操作许可。



这两种行为似乎都很奇怪。通常,应用程序模型不需要我在应用程序调用之间甚至在应用程序运行期间重新授权对资源的许可。甚至网页也可以在会话期间保留授权。我是在做错什么,还是这是预期的行为?



正在执行代码的代码(该代码正在Google Cloud Functions中运行,并且还有一些其他结构正在通过Promise进行这些调用-这只是代码的相关部分)。 res.send(200)只是向API.AI指示它应该使用在那里定义的响应,并且不会出现问题。 返回Promise.resolve(null); 只是确保不执行其他回退/错误条件。

  
exports.process = function(req,res){
var app = new ApiAiApp({request:req,response:res});

if(app.isPermissionGranted()){
res.send(200);
返回Promise.resolve(null);
} else {
return askPermission(req,res,app);
}
};

var askPermission = function(req,res,app){
//app.tell(’foo’);
let namePermission = app.SupportedPermissions.NAME;
let precisionLocationPermission = app.SupportedPermissions.DEVICE_PRECISE_LOCATION;

//请求多个权限。用户可以授权全部或不授权。
app.askForPermissions(按名称称呼您并知道您的位置,
[namePermission,precisionLocationPermission]);
返回Promise.resolve(null);
};

用于处理 actions_intent_PERMISSION 请求:





模拟器显示的屏幕快照始终会显示许可请求,除非特别授予许可:





初始连接时发送的JSON:

  
{
originalRequest:{
source: google,
v ersion: 2,
data:{
isInSandbox:true,
surface:{
capabilities:[
{
name: actions.capability.AUDIO_OUTPUT
},
{
name: actions.capability.SCREEN_OUTPUT
}
]
},
inputs:[
{
rawInputs:[
{
query:与我的测试应用对话
inputType:键盘
}
],
intent: actions.intent.MAIN
}
],
user:{
locale: en-US,
userId: APhe68HKWmHGe9cojGOMrX9WKQ0l
},
device:{},
对话:{
conversationId: 1499807128489,
type: NEW
}
}
},
id: 7e301f85-4178-4be6-8b7c-408bad3ef62b,
timestamp: 2017-07-11T21:05:28.504Z,
lang: en,
结果:{
源:代理,
resolvedQuery: GOOGLE_ASSISTANT_WELCOME,
sp eech:,
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,
参数:{},
寿命:0
},
{
name: google_assistant_input_type_keyboard,
参数:{},
寿命:0
}
],
元数据:{
intentId: f31e371a-db9e-4e00 -8002-546ec14d40a9,
webhookUsed: true,
webhookForSlotFillingUsed: false,
nluResponseTime:2,2,
intentName:默认Welcome Intent
},
fulfillment:{
speech:我不确定,我有点困惑。,
messages: [
{
类型:0,
语音:我不确定,我有点困惑。
}
]
},
分数:1
},
status:{
code:200,
errorType:成功
},
sessionId: 1499807128489
}

在请求许可并且我已授予它后发送的JSON。如预期的那样, originalRequest.data.user 的名称和 originalRequest.data.device 现在的位置。

  
{
originalRequest:{
source: google,
版本: 2,
数据:{
isInSandbox:true,
表面:{
功能:[
{
name: actions.capability.AUDIO_OUTPUT
},
{
name: actions.capability.SCREEN_OUTPUT
}
]
},
输入:[
{
rawInputs:[
{
查询:是,
inputType:键盘
}
],
参数:[
{
rawText:是,
textValue: true,
name: PERMISSION
}
],
intent: actions.intent.PERMISSION
}
],
user:{
profile:{
displayName: Allen Firstenberg,
givenName:艾伦,
familyName: Firstenberg
},
locale: en-US,
userId: APhe68HKWmHGe9cojGOMrX9WKQ0l
},
device:{
location:{
coordinates:{
latitude:37.4219806,
longitude :-122.0841979
}
}
},
对话:{
conversationId: 1499807128489,
type:活动,
conversationToken: [\ _actions_on_google_\]
}
}
},
id: 7a75593e-55d0- 4962-ad91-564d47e5df13,
timestamp: 2017-07-11T21:05:43.391Z,
lang: en,
result:{
源:代理,
resolvedQuery: actions_intent_PERMISSION,
语音:,
action:,
actionIncomplete:否,
参数:{},
上下文:[
{
名称: actions_capability_screen_output,
parameters: {},
寿命:0
},
{
name: _actions_on_google_,
parameters:{},
lifespan:99
},
{
name: actions_intent_permission ,
parameters:{
PERMISSION: true
},
lifespan:0
},
{
名称: actions_capability_audio_output,
参数:{},
寿命:0
},
{
名称: google_assistant_input_type_keyboard ,
参数:{},
寿命:0
}
],
元数据:{
intentId: 5d154d71-63f1-43a9-9c18-70d78bfd700f,
webhookUsed: true,
webhookForSlotFillingUsed: false,
nluResponseTime:1,
intentName:位置结果
},
fulfillment:{
speech:您被允许,
messages:[
{
type:0,
speech:您被允许
}
]
},
score: 1
},
状态:{
代码:200,
errorType:成功
},
sessionId: 1499807128489
}

在我授予许可(上面)之后发送的JSON,然后发出简单测试短语。请注意,用户和设备字段缺少授予权限的信息,但这是正确的意图。

  
{
originalRequest:{
source: google,
version: 2,
data:{
isInSandbox:true,
surface:{
capabilities:[
{
name: actions.capability.AUDIO_OUTPUT
},
{
name: actions.capability.SCREEN_OUTPUT
}
]
},
inputs:[
{
rawInputs:[
{
query:简单测试,
inputType:键盘
}
],
arguments:[
{
rawText:简单测试,
textValue:简单测试,
name: text
}
],
intent: actions.intent.TEXT
}
],
user:{
locale: zh-CN,
userId: APhe68HKWmHGe9coj GOMrX9WKQ0l
},
device:{},
conversation:{
conversationId: 1499807128489,
type:活动,
conversationToken: [\ _actions_on_google_\]
}
}
},
id: f1804e02-bafc- 4656-8726-0955bfb4f75d,
时间戳: 2017-07-11T21:05:55.001Z,
lang: en,
结果:{
源:代理,
resolvedQuery:简单测试,
语音:,
操作:,
actionIncomplete:否,
parameters:{},
contexts:[
{
name: actions_capability_screen_output,
parameters :{},
寿命:0
},
{
name: _actions_on_google_,
parameters:{},
寿命:98
},
{
name: actions_capability_audio_output,
parameters:{},
lifespan:0
},
{
name: google_assistant_input_type_keyboard,
参数s:{},
寿命:0
}
],
元数据:{
intentId: 48257e82-3615-4445- 8ea2-be21980b7115,
webhookUsed: true,
webhookForSlotFillingUsed: false,
nluResponseTime:4,4,
intentName:简单测试
},
完成:{
语音:,
消息:[
{
type:0 ,
speech:
}
]
},
score:1
},
status: {
code:200,
errorType:成功
},
sessionId: 1499807128489
}

在两个会话之间执行此操作会产生相同的结果。

解决方案

这是预期的行为。目前,我们建议您在用户端保留用户许可的数据,并以用户ID为键。要查看我们建议如何执行此操作,请查看名称Psychic 样本。在该示例中,我们使用 Firebase Realtime DB 持久存储该用户在Intent /对话。


With API.AI and the Google Assistant, I'm requesting permission to get the user's name and location. The intent is that I'll be able to ask for permission once, and subsequent requests to my Action will not need to ask again (since this will make for a very stilted conversation every time the user talks to my Action).

What I am finding is that I'm only getting the information in the intent tied to the actions_intent_PERMISSION - the information isn't sent in other intent fulfillments, even if I've already granted the permission. (In the example code below - it ends up re-requesting permission for all of the other intents.)

I'm also not seeing this permission maintained in between invocations of my Action. So every time the Action is triggered, they're (again) asked if they grant the action permission.

Both behaviors seem odd. Application models, in general, don't require me to re-authorize permission to a resource in between invocations of the application, or even while the application is "running". Even web pages preserve authorization during a session. Am I doing something wrong, or is this the behavior as intended?

Code that is doing the fulfillment (this is running in Google Cloud Functions and there is some additional structure that is making these calls through a Promise - this is just the relevant part of the code). The res.send(200) just indicates to API.AI that it should use the responses that are defined there, and that works without problems. The return Promise.resolve(null); just makes sure that other fallback/error conditions aren't executed.


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 );
};

The API.AI Intent that handles the actions_intent_PERMISSION request:

Another Intent that should have user/location payload, but which never gets called with that info

Screen shot from the Simulator demonstrating it always asks for permission, except when its specifically been granted:

The JSON sent when initially connecting:


{
 "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"
}

The JSON sent after it asks for permission and I've granted it. As expected originalRequest.data.user has the name and originalRequest.data.device now has the location.


{
 "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 sent after I've granted permission (above) and then issued the "simple test" phrase. Note that the user and device fields are missing the information that permission was granted for, but that this is the right intent.


{
 "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"
}

Doing this between two sessions yields the same sort of results.

解决方案

This is expected behavior. Right now we recommend persisting user permissioned data on your end, keyed by the User ID. To see how we might recommend doing this, check out the Name Psychic sample. In that sample, we use Firebase Realtime DB to persist the permissioned data for that user across intents/conversations.

这篇关于在请求之间未存储Google Assistant位置权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆