在Actions on Google中通过粗略位置获取用户国家及消歧的推荐方法
嘿,针对你提出的两个问题,我整理了实际开发中常用的解决方案,结合你的代码示例一起说明:
一、通过粗略位置获取用户国家的推荐方式
当你请求DEVICE_COARSE_LOCATION权限时,getDeviceLocation()确实只会返回zipCode和city,没有直接的国家代码。这里最靠谱的方式是把城市+邮政编码的组合传给地理编码API(比如你已经在用的Google Maps Geocoding API),反向解析出国家信息。
这个思路和你处理精确位置的逻辑类似,只是把经纬度换成了城市+邮编的查询字符串。
二、仅粗略位置权限时的消歧方法
你提到的同名城市/重复邮编问题确实存在,这里有几个实用的消歧手段,按优先级排序:
1. 优先利用用户的区域偏好
Actions on Google会提供用户的locale信息(通过app.getUser().locale获取,格式比如en-US、fr-CA),其中的国家代码部分(比如US、CA)可以帮你缩小查询范围。调用地理编码API时,把这个国家代码作为region参数传入,API会优先返回该区域内的匹配结果,能解决大部分歧义问题。
2. 借助邮政编码的格式特征
不同国家的邮编格式有明显差异:比如美国是5位数字(可扩展为5-4位),加拿大是6位字母数字混合(如A1A 1A1),英国是多段式字母数字组合。你可以先用正则匹配判断邮编格式,初步锁定可能的国家,再结合城市名查询,进一步降低歧义。
3. 用户主动确认(兜底方案)
如果前面的方法还是无法确定唯一国家(极端情况),就设计一个简短的对话让用户确认。比如:
我看到你所在的城市是Springfield,这个名字在多个国家都有,请问你具体在哪个国家呢?
修正后的示例代码
把这些思路整合到你的代码里,大概是这样:
const requestedPermission = app.data.requestedPermission; const permissions = app.SupportedPermissions; const userLocale = app.getUser().locale; // 获取用户的区域偏好 if (requestedPermission === permissions.DEVICE_COARSE_LOCATION) { const { city, zipCode } = app.getDeviceLocation(); // 提取locale中的国家代码,作为地理编码的区域限制 const userCountry = userLocale.split('-')[1]; // 构造查询参数,同时传入region参数缩小范围 const geocodeParams = { address: `${city}, ${zipCode}`, region: userCountry }; // 调用地理编码API获取国家代码 return geocodeToCountryCode(mapsClient, geocodeParams) .then(countryCode => { if (countryCode) { doSomethingBasedOnCountry(countryCode); } else { // 兜底:询问用户确认国家 return app.ask('抱歉,我没法确定你的所在国家,能告诉我你在哪个国家吗?'); } }) .catch(err => { // 处理API调用失败的情况 return app.ask('暂时无法获取你的位置信息,能告诉我你在哪个国家吗?'); }); } if (requestedPermission === permissions.DEVICE_PRECISE_LOCATION) { const { coordinates } = app.getDeviceLocation(); return coordinatesToCountryCode(mapsClient, coordinates.latitude, coordinates.longitude) .then(doSomethingBasedOnCountry); }
小提示
- 调用Google Maps Geocoding API时,
region参数是关键,它会让API优先返回指定区域的结果,准确性更高。 - 一定要处理API调用失败、返回无结果的情况,避免对话流程卡壳。
内容的提问来源于stack exchange,提问作者passy

