Firebase 如何让用户确认Dialogflow中的位置和地理坐标?
我正在使用对话流为谷歌助手制作应用程序。我的应用程序使用部署在firebase上的webhook功能。主要问题是如何获取用户位置-我需要将坐标传递给URL。我可以提示消息以获得位置许可,但是如何确认和获取坐标 我是否需要添加任何确认意图?我正在请求默认欢迎意图中的位置许可 代码如下:Firebase 如何让用户确认Dialogflow中的位置和地理坐标?,firebase,webhooks,actions-on-google,dialogflow-es,Firebase,Webhooks,Actions On Google,Dialogflow Es,我正在使用对话流为谷歌助手制作应用程序。我的应用程序使用部署在firebase上的webhook功能。主要问题是如何获取用户位置-我需要将坐标传递给URL。我可以提示消息以获得位置许可,但是如何确认和获取坐标 我是否需要添加任何确认意图?我正在请求默认欢迎意图中的位置许可 代码如下: 'use strict'; process.env.DEBUG = 'actions-on-google:*'; const App = require('actions-on-google').Dialogfl
'use strict';
process.env.DEBUG = 'actions-on-google:*';
const App = require('actions-on-google').DialogflowApp;
const functions = require('firebase-functions');
//----global variables-----
const http = require('https');
var body = "";
var body2="";
var address="";
var latitude="";
var longitude="";
var lati="";
var long="";
//------ADDRESS_ACTION to tell the current address based on current coordinates----
const ADDRESS_ACTION = 'address_action';
//-----DIRECTION_INTENT to output the map guidence through basic card------
const DIRECTION_INTENT = 'direction_action';
//--------during welcome intent, ask the permiisions------
const DIR_PERMISS_CONF= 'intent.welcome';
exports.addressMaker = functions.https.onRequest((request, response) => {
const app = new App({request, response});
console.log('Request headers: ' + JSON.stringify(request.headers));
console.log('Request body: ' + JSON.stringify(request.body));
function welcomeIntentDirection (app)
{
app.askForPermission("Hi! Welcome to !To show address/direction",app.SupportedPermissions.DEVICE_PRECISE_LOCATION);
if (app.isPermissionGranted())
{
// app.tell('You said ' + app.getRawInput());
}
else
{
// app.tell('You said ' + app.getRawInput());
}
}
function makeDirection(app)
{
//-------here we are extraction what user said, we will extract the place name, it is for "direction to PLACE_NAME"-------
var stringRequest=JSON.stringify(request.body);
var jsonRequest=JSON.parse(stringRequest);
var jsonSpeech=jsonRequest.originalRequest.data.inputs[0].rawInputs[0].query;
var arr=jsonSpeech.split("to");
var placeName=arr[1].trim();
//------Current Location--------------
let deviceCoordinates = app.getDeviceLocation().coordinates;
latitude=deviceCoordinates.latitude;
longitude=deviceCoordinates.longitude;
//-----now send this place name to api to get coordinates-----
var req2= http.get("https://api.url-with-PARAMETER-placeName",function(res){
res.on("data", function(chunk2){ body2 += chunk2; });
res.on('end', function()
{
if (res.statusCode === 200)
{
var data2 = JSON.parse(body2);
try
{
lati=data2.geometry.lat;
long=data2.geometry.lng;
}catch(e){app.tell("Invalid or non-existent address");}
}
});
});
//-------------------Here BUILDING the CARD (Rich RESPONSE)-----------------------
app.ask(app.buildRichResponse()
// Create a basic card and add it to the rich response
.addSimpleResponse('Your directions are here:')
.addBasicCard(app.buildBasicCard()
.addButton('Start Guidence', 'https://www.google.com/maps/dir/?api=1&origin='+latitude+','+longitude+'&destination='+lati+','+long+'')
.setImage('https://png.pngtree.com/element_origin_min_pic/16/11/30/a535f05d9d512610e25a036b50da036f.jpg', 'Image alternate text')
.setImageDisplay('CROPPED')
)
);
}
function makeAddress (app)
{
let deviceCoordinates = app.getDeviceLocation().coordinates;
latitude=deviceCoordinates.latitude;
longitude=deviceCoordinates.longitude;
var req=http.get("https://api.url/reverse?coords="+latitude+","+longitude+"",
function(res)
{
res.on("data", function(chunk){ body += chunk; });
res.on('end', function()
{
if (res.statusCode === 200)
{
try
{
var data = JSON.parse(body);
address=data.words;
app.tell('Alright, your address is '+address);
} catch (e) { }
}
else
{
app.tell("Unable to contact to server +"+res.statusCode);
}
});
});
}
// d. build an action map, which maps intent names to functions
let actionMap = new Map();
actionMap.set(DIR_PERMISS_CONF,welcomeIntentDirection);
actionMap.set(ADDRESS_ACTION, makeAddress);
actionMap.set(DIRECTION_INTENT, makeDirection);
app.handleRequest(actionMap);
});
是的,您需要一个意图来处理来自用户的响应。Dialogflow的模型是,用户的所有响应都需要通过一个意图来处理 在这种情况下,这将是您的“确认”意图 您不显示意图的屏幕截图(如果您还有其他问题,请更新问题以将其包括在内),但它需要处理事件
操作\u意图\u权限
。处理此事件时,您不需要任何培训短语
我拥有的一个(意图名称和动作为result.location
)如下所示:
http.get("https://api.url-with-PARAMETER-placeName",function(res){
res.on("data", function(chunk2){ body2 += chunk2; });
res.on('end', function(){
if (res.statusCode === 200){
var data2 = JSON.parse(body2);
try{
lati=data2.geometry.lat;
long=data2.geometry.lng;
app.ask(
app.buildRichResponse()
.addThingsToRichResponse()
);
} catch(e){
app.tell("Invalid or non-existent address");
}
}
});
});
另一方面,在处理程序中,您试图获取用户名,但除非您请求允许,否则此名称不可用。你没有请求许可。如果你想,你可以在询问他们的位置的同时,通过类似的方式请求许可
app.askForPermissions("To show your address", [
app.SupportedPermissions.NAME,
app.SupportedPermissions.DEVICE_PRECISE_LOCATION
]);
根据屏幕截图更新
现在还不清楚你的对话流程是什么,所以我做了一些假设
但根据您的代码,您请求许可是出于欢迎目的。然后用户给予许可,您需要一个接受该回复的意图
我看不出有人愿意接受这个回答
为了接受回复,您需要一个意图来处理事件actions\u Intent\u PERMISSION
,如我在上面的屏幕截图中所示
您似乎也在创建上下文,尽管原因尚不清楚
根据您发布的代码和其他评论更新
代码中有几个问题可能会导致您遇到的一些问题,还有一些其他问题可能会在将来给您带来问题。要回答评论中的一些问题和一些未询问的问题,请执行以下操作:
我启用了聊天功能
这并没有伤害到任何东西,但可能也没有任何帮助。我建议你禁用它,直到你的谈话的核心部分开始工作
我可以得到坐标
好-所以意图是有效的
但是
我看到你将坐标存储在一个全局变量中。这种方法在这种情况下有效(但不完全有效,请参见您的下一个问题),但如果有多人在使用该操作,则无法扩展,因为这些值可能在用户会话之间混淆
换句话说:如果在webhook中使用全局变量,每个人都可以访问这些值。这很糟糕。
您需要的是一种在调用webhook之间存储用户信息的方法。有许多方法可以做到这一点,这些方法都包含在本文中,并且可能涉及到很多方面。但是,通常情况下,您可以将值存储在上下文或app.data
中,它们将作为同一对话的一部分返回给您
我第一次问的时候没有目的地地址
和
当我第二次询问时,它有目的地地址
函数makeDirection()
包含一个异步操作,用于获取目标地址的lat/lon,但是您将在异步块之外发回应答
因此,所发生的情况是,您启动http调用,然后代码继续,并将应答发送给目标为空的用户。在稍后的某个时刻,回调完成并设置了目标,但对于第一次调用来说太晚了。但是,当您第二次调用它时,它会执行相同的例程(启动异步调用,然后在调用完成之前立即发送回一些内容),但是上一次运行的值是设置的,因为您在全局变量中设置了它们
要解决此问题,您需要调用app.ask()
,作为异步回调的一部分。这可能看起来像这样:
http.get("https://api.url-with-PARAMETER-placeName",function(res){
res.on("data", function(chunk2){ body2 += chunk2; });
res.on('end', function(){
if (res.statusCode === 200){
var data2 = JSON.parse(body2);
try{
lati=data2.geometry.lat;
long=data2.geometry.lng;
app.ask(
app.buildRichResponse()
.addThingsToRichResponse()
);
} catch(e){
app.tell("Invalid or non-existent address");
}
}
});
});
获取用户对目的地所说内容的问题
您试图获取用户目的地的代码是。。。奇怪的获取rawInputs
是合法的,但尝试将其拆分以获取特定值并不是最佳做法,尤其是因为用户可能无法准确说出您认为他们将要说的内容。例如,如果他们说“我要去某个地方”会怎么样
更好的方法是让您的方向\u操作
意图使用各种不同的短语,并将其中的“重要”部分(目标)指定给一个参数。然后,在webhook中,您可以只读取参数的值,并将其传递给服务以确定位置
您可能还想看一看最近发布的,类似于设备精确定位助手,但也可以获得用户指定的地址。先生,您可以制作一个“名字通灵”的视频教程吗?我想届时我所有的疑问都会得到澄清。当我对位置权限说“是”时,在请求中它得到了更新,我能够获得位置,但google助手回答“你能再说一遍吗”或“我不明白”。这表明你触发了回退意图,这意味着它不符合任何其他意图。用屏幕截图更新您的问题,说明您认为应该处理的意图,这可能有助于我们进一步帮助您。请稍等,回答已更新。但是(1) 我们不是在你的另一个问题中讨论过异步函数吗?(2) 如果将它们存储在局部变量中,则多个用户可以访问