为了体验采样,我在谷歌上使用dialogflow构建了操作。它的想法是:它每天三次询问特定用户的情绪。经过研究人员的分析,它每周都会向这些用户发送一份关于他们情绪的概述。
因此,我需要将每个用户的信息和他的情绪条目保存在数据库中,以便研究人员稍后可以访问、分析并发送给用户。
我使用带index.js的dialogflow实现来连接到Firebase数据库以保存条目。此代理应集成为谷歌上的操作
在数据库中,我得到了用户的姓名和心情,但它们彼此无关,所以我不知道是哪个用户输入了哪个心情,也无法进行用户ID检查。
如果有人能帮我处理这些函数,我将不胜感激,因为我对node.js或数据库完全不熟悉,但我必须这样做。
这是我的密码。
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
//initialise DB connection
const admin = require('firebase-admin');
admin.initializeApp();
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function saveName(agent) {
const nameParam = agent.parameters.name;
const context = agent.getContext('awaiting_name_confirm');
const name = nameParam || context.parameters.name;
agent.add('Hi ' + name + ' Are you ready to answer my question?' || 'Hi' + name + 'Have you got a moment for me? ' );
//agent.add('Hi' + name + 'Have you got a minute for me? ');
return admin.database().ref('/names').push({name: name}).then((snapshot)=>
{
console.log('database write sucessful: ' + snapshot.ref.toString());
});
}
function saveMood(agent) {
const moodParam = agent.parameters.mood;
const mood = moodParam;
agent.add('That is good! keep it up. Thanks for sharing with me! Bye ');
//agent.add('Hi' + name + 'Have you got a minute for me? ');
return admin.database().ref('/moods').push({mood: mood}).then((snapshot)=>
{
console.log('database write sucessful: ' + snapshot.ref.toString());
});
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Get Name', saveName);
intentMap.set('Confirm Name Yes', saveName);
// intentMap.set('Confirm Name Yes', getName);
intentMap.set('attentiveness', saveMood);
agent.handleRequest(intentMap);
});
您的代码和方法中有一些问题需要解决:
- 您需要设计数据库,以便将用户的情绪与他们的帐户关联起来。(可能还有其他用户信息,比如他们的姓名或电子邮件地址,当你在那里的时候。)
- 你需要一个独一无二的身份。
- 一个人的名字并不是唯一的身份。两个人可能有相同的名字,或者系统每次听到的名字可能不同,所以你需要有一种方法来知道你在和谁说话
- 你还需要知道他们的电子邮件地址和可能的其他信息,这样你就可以在周末向他们发送报告
- 在同一次对话中,你需要确保他们在呼叫你的Action之间的身份
幸运的是,您做了一件通常会错过的事情——使用Promises对数据库进行调用。所以这部分是有效的。
唯一标识
您的示例代码要求用户输入他们的姓名,听起来您打算将其用作他们的身份。不幸的是,这是一个坏主意,原因有几个:
-
这个名字不是一个身份。如果两个同名的人访问您的Action,会发生什么?
-
名字很容易被发现,所以其他人可能会使用它并报告误导性信息。在你的情况下,这可能不太严重,但它仍然会对可信度产生影响。
-
姓名可以是个人身份信息(PII),因此可能受到其他隐私法的保护。
-
用户可能想终止他们的帐户,如果不"更改"他们的名称,就无法终止帐户。
此外,您稍后可能需要其他身份信息,如他们的电子邮件地址,每次询问这些信息可能会变得很麻烦。
你有几种方法来处理这个问题:
-
如果你正在为谷歌助手开发,你也可以使用谷歌助手登录,它会告诉你用户的谷歌标识符,你可以将其用作唯一ID。你还可以将他们的电子邮件地址和姓名作为他们个人资料的一部分。
-
您可以询问这些信息(姓名、电子邮件等),并将其保存到您生成的用户ID或用户提供的用户名中。此ID将成为标识符。如果你是为谷歌助手开发的,你可以将此ID保存在用户的私人存储中-只有你和用户有权访问或删除它。如果没有,你可能需要使用数据库来查找ID。稍后会详细介绍。
-
稍后,您可能希望使用变体,这取决于您获得的信息以及您希望用户每次如何识别自己。但重要的是,他们需要用一些独特的东西来识别自己,你可以很容易地捕捉到这些东西。
在同一会话中使用身份
如果你正在使用谷歌登录,你不必担心这一点。每次会话和会话期间的每次通话都将获得相同的ID。
如果您将用户的私人存储与Google Assistant一起使用,则会将其作为userStore对象的一部分。
但如果你没有,你需要确保你在早期就获得了用户的ID,并将其保存为上下文的一部分,以便在对你的webhook的调用之间保留它。在随后的处理程序中,您可以从上下文中获取ID,然后使用它来访问其他信息。
此时您不需要将其存储在数据库中。您所拥有的只是一个标识符-这将成为您将用于其他信息的密钥。你只需要在谈话的后面部分记住它。
所以在saveName()
函数中,它可能看起来像
function saveName(agent) {
const nameParam = agent.parameters.name;
agent.add('Hi ' + nameParam + ' Are you ready to answer my question?');
agent.setContext({
name: 'user',
lifespan: 99,
parameters: {
id: nameParam
}
};
}
顺便说一句,你的处理程序似乎试图确定这是用户说出自己的名字,还是确认自己的名字。这可能更适合作为单独的意图和单独的处理程序来处理。试图把它们结合起来会使事情变得混乱。
构建和访问数据库
我们有一个ID。我们让用户报告数据。我们如何将两者联系起来?
有很多方法可以构建数据,Firebase会根据您打算如何使用、访问数据以及向用户或其他人提供数据来详细介绍。
在这种情况下,想要存储关于用户的记录似乎非常简单。每个记录都可以使用他们的ID作为密钥,然后包含一些关于用户的信息,包括他们的心情。
Firebase数据库的一个好处是,您可以(主要)将其视为Javascript对象。如果我们这样想,它可能看起来像
{
"user": {
"id1":{...},
"id2":{...},
"id3":{
"moods": [
{"mood":"good"},
{"mood":"tired"}
]
},
"id4":{...}
}
}
等等。使用Firebase,我们将使用user/id3/moods
等路径引用用户"id3"的情绪。如果我们在变量name
中有用户id,我们可能会使用以下代码来获得该引用
var ref = admin.database().ref('user').ref(name).ref('moods');
然后使用这样的代码将带有情绪的对象推送到数组上(并返回我们需要做的Promise):
var obj = {
mood: mood
};
return ref.push( obj ).then( snapshot => {
// Do stuff, including acknowledge to the user you saved it.
});
请记住,您可能还想使用它在用户级别上存储有关每个用户的更多信息(如他们的姓名或电子邮件),或在mood对象中存储有关mood的信息(如时间戳)。