Lak*_*pal 5 actions-on-google dialogflow-es
我正在尝试制作一个辅助应用程序,并且正在使用firebase的Cloud Firestore服务将响应作为WebFook的响应发送回我的应用程序。我已经根据此文档在请求JSON中使用了'session'参数,并发送fulfilmentText作为对用户的响应。但是,每当用户启动该应用程序时,都会创建一个我不需要的新会话。我只想为数据库中的每个用户提供一个条目,以便如何使用dialogflow实现该目的。
在Alexa Skill中,我们将deviceId作为参数,通过它我们可以唯一地标识用户,而与会话ID无关,但是dialogflowRequest JSON中是否有任何参数。如果没有,那么没有它怎么实现这个任务。
我从Dialogflow获得的请求JSON中包含一个userID,因此我可以使用userId还是应该与userStorage一起使用,前提是请求JSON中不提供userStorage参数。
request.body.originalDetectIntentRequest { source: 'google', version: '2', payload: { surface: { capabilities: [Object] },
inputs: [ [Object] ],
user:
{ locale: 'en-US',
userId: 'ABwppHG5OfRf2qquWWjI-Uy-MwfiE1DQlCCeoDrGhG8b0fHVg7GsPmaKehtxAcP-_ycf_9IQVtUISgfKhZzawL7spA' },
conversation:
{ conversationId: '1528790005269',
type: 'ACTIVE',
conversationToken: '["generate-number-followup"]' },
availableSurfaces: [ [Object] ] } }
Run Code Online (Sandbox Code Playgroud)
编辑:谢谢@Prisoner的回答,但我无法发送在响应中生成并在有效负载中设置的随机ID。以下是我生成uuid并将其存储在firestore中的代码。我在下面的代码中做错了,由于生成了新的uuid用于返回用户,因此响应显示为在数据库中找不到文档。我想我没有适当地发送uuid。请帮忙。
exports.webhook = functions.https.onRequest((request, response) => {
console.log("request.body.queryResult.parameters", request.body.queryResult.parameters);
console.log("request.body.originalDetectIntentRequest.payload", request.body.originalDetectIntentRequest.payload);
let userStorage = request.body.originalDetectIntentRequest.payload.user.userStorage || {};
let userId;
console.log("userStorage", userStorage);
if (userId in userStorage) {
userId = userStorage.userId;
} else {
var uuid = require('uuid/v4');
userId = uuid();
userStorage.userId = userId
}
console.log("userID", userId);
switch (request.body.queryResult.action) {
case 'FeedbackAction': {
let params = request.body.queryResult.parameters;
firestore.collection('users').doc(userId).set(params)
.then(() => {
response.send({
'fulfillmentText' : `Thank You for visiting our ${params.resortLocation} hotel branch and giving us ${params.rating} and your comment as ${params.comments}.` ,
'payload': {
'google': {
'userStorage': userStorage
}
}
});
return console.log("resort location", params.resortLocation);
})
.catch((e => {
console.log('error: ', e);
response.send({
'fulfillmentText' : `something went wrong when writing to database`,
'payload': {
'google': {
'userStorage': userStorage
}
}
});
}))
break;
}
case 'countFeedbacks':{
var docRef = firestore.collection('users').doc(userId);
docRef.get().then(doc => {
if (doc.exists) {
// console.log("Document data:", doc.data());
var dat = doc.data();
response.send({
'fulfillmentText' : `You have given feedback for ${dat.resortLocation} and rating as ${dat.rating}`,
'payload': {
'google': {
'userStorage': userStorage
}
}
});
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
response.send({
'fulfillmentText' : `No feedback found in our database`,
'payload': {
'google': {
'userStorage': userStorage
}
}
});
}
return console.log("userStorage_then_wala", userStorage);
}).catch((e => {
console.log("Error getting document:", error);
response.send({
'fulfillmentText' : `something went wrong while reading from the database`,
'payload': {
'google': {
'userStorage': userStorage
}
}
})
}));
break;
}
Run Code Online (Sandbox Code Playgroud)
您有两种选择,具体取决于您的实际需求。
简单:userStorage
Google提供了一个userStorage对象,当它可以识别用户时,该对象将在整个会话中保持不变。这使您可以在需要跟踪用户何时返回时存储自己的标识符。
最简单的方法userStorage是在调用Webhook时检查对象的标识符。如果不存在,请使用v4 UUID之类的内容创建一个并将其保存在userStorage对象中。
如果您使用的是Google动作库,则代码可能看起来像这样:
let userId;
// if a value for userID exists un user storage, it's a returning user so we can
// just read the value and use it. If a value for userId does not exist in user storage,
// it's a new user, so we need to generate a new ID and save it in user storage.
if (userId in conv.user.storage) {
userId = conv.user.storage.userId;
} else {
// Uses the "uuid" package. You can get this with "npm install --save uuid"
var uuid = require('uuid/v4');
userId = uuid();
conv.user.storage.userId = userId
}
Run Code Online (Sandbox Code Playgroud)
如果使用dialogflow库,则可以使用上面的库,但是首先需要此行:
let conv = agent.conv();
Run Code Online (Sandbox Code Playgroud)
如果您使用的是多声库,它将为您完成上述所有操作,并将在path下的环境中提供一个UserID User/Id。
如果您直接处理JSON,并且使用的是Dialogflow v2协议,则可以通过检查originalDetectIntentRequest.payload.user.userStorageJSON请求对象来获取userStorage 对象。您将payload.google.userStorage在JSON响应中设置对象。代码类似于上面的代码,可能看起来像这样:
let userStorage = body.originalDetectIntentRequest.payload.user.userStorage || {};
let userId;
// if a value for userID exists un user storage, it's a returning user so we can
// just read the value and use it. If a value for userId does not exist in user storage,
// it's a new user, so we need to generate a new ID and save it in user storage.
if (userId in userStorage) {
userId = userStorage.userId;
} else {
// Uses the "uuid" package. You can get this with "npm install --save uuid"
var uuid = require('uuid/v4');
userId = uuid();
userStorage.userId = userId
}
// ... Do stuff with the userID
// Make sure you include the userStorage as part of the response
var responseBody = {
payload: {
google: {
userStorage: JSON.stringify(userStorage),
// ...
}
}
};
Run Code Online (Sandbox Code Playgroud)
请注意代码的第一行-如果userStorage不存在,请使用一个空对象。在您发送包含第一次在其中存储内容的响应之前,它不会存在,这将在此代码的最后几行中发生。
进阶:帐户连结
您可以要求用户使用Google登录来登录您的操作。仅在最简单的情况下使用语音即可完成此操作,并且只会在第一次时中断流程。
之后,您的操作将获得一个JWT,其中包含其Google ID,您可以将其用作标识符。
如果您使用的是Google Actions-on-Google库,则可以使用以下代码行从解码的JWT中获取ID:
const userId = conv.user.profile.payload.sub;
Run Code Online (Sandbox Code Playgroud)
在多声库中,来自已解码JWT的ID在路径下的环境中可用 User/Profile/sub
弃用:匿名用户ID
您将在StackOverflow上看到一些引用匿名用户ID的答案。Google已弃用该标识符,该标识符并非始终是验证回访用户的可靠方法,并将于2019年6月1日将其删除。
该代码目前仍在发送,但将从2019年6月1日开始将其删除。
| 归档时间: |
|
| 查看次数: |
2286 次 |
| 最近记录: |