Как использовать диалоговое окно Fulfillment Inline Editor для сохранения имен пользователей и настроений в базе данных в реальном времени?
Я построил действие на Google, используя диалоговое окно для цели выборки опыта. Идея такова: он спрашивает конкретных пользователей об их настроении 3 раза в день. Затем эти пользователи каждую неделю отправляют еженедельный обзор их настроения после того, как исследователи проанализировали его.
Поэтому мне нужно сохранить информацию о каждом пользователе с записями его настроений в базе данных, чтобы исследователи могли впоследствии получить к ним доступ, проанализировать и отправить обратно пользователям.
Я использую выполнение диалогового потока с index.js для подключения к базе данных Firebase, чтобы сохранить записи. Этот агент должен быть интегрирован как действие на Google
В базе данных я получаю имена и настроения пользователей, но они не связаны друг с другом, поэтому я не могу знать, какой пользователь вошел в какое настроение, а также я не могу выполнить проверку userID.
Я был бы очень признателен, если бы кто-нибудь мог помочь мне с функциями, так как я совершенно незнаком с 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);
});
1 ответ
У вас есть несколько проблем в вашем коде и подходе, которые вам нужно будет решить:
- Вам необходимо спроектировать базу данных, чтобы вы могли связать настроение пользователя с его учетной записью. (И, возможно, другую информацию о пользователе, такую как его имя или адрес электронной почты, пока вы на нем.)
- Вам нужна уникальная личность для человека.
- Имя человека не является уникальной личностью. Два человека могут иметь одно и то же имя, или система может слышать это имя каждый раз по-разному, поэтому вам нужно знать, с кем вы разговариваете.
- Вам также необходимо знать их адрес электронной почты и, возможно, другую информацию, чтобы вы могли отправить им отчет в конце недели.
- Вы должны удостовериться, что у вас есть их личность между вызовами к вашему действию во время одного разговора
К счастью, вы делаете одну вещь, которая обычно пропускается - вы делаете свои звонки в базу данных, используя Promises. Так что эта часть работает.
Уникальная личность
Ваш пример кода запрашивает у пользователя его имя, которое звучит так, как будто вы собираетесь использовать в качестве его имени. К сожалению, это плохая идея по нескольким причинам:
Имя не является личностью. Что произойдет, если два человека с одинаковыми именами получат доступ к вашему действию?
Имена легко обнаруживаются, поэтому другие люди могут использовать их и сообщать вводящую в заблуждение информацию. Это не может быть слишком серьезным в вашем случае, но это может иметь последствия для надежности.
Имена могут быть Личной информацией (PII), поэтому на них могут распространяться дополнительные законы о конфиденциальности.
Пользователи могут захотеть закрыть свою учетную запись, и не могут сделать это без "изменения" своего имени.
Кроме того, вам может понадобиться другая личная информация позже, например, адрес электронной почты, и запрос об этом каждый раз может стать проблематичным.
У вас есть несколько способов справиться с этим:
Если вы разрабатываете для Google Assistant, вы также можете использовать Google Sign In for Assistant, который сообщит вам идентификатор пользователя Google, который вы можете использовать в качестве уникального идентификатора. Вы также получите их адрес электронной почты и имя как часть их профиля.
Вы можете запросить эту информацию (имя, адрес электронной почты и т. Д.) И сохранить ее под сгенерированным вами идентификатором пользователя или именем пользователя, которое он предоставляет. Этот идентификатор становится идентификатором. Если вы разрабатываете для Google Assistant, вы можете сохранить этот идентификатор в личном хранилище пользователя - только вы и пользователь имеете доступ к нему или можете удалить его. Если нет, вам может понадобиться использовать базу данных для поиска идентификатора. Подробнее об этом позже.
Возможно, вы захотите использовать варианты на этом более позднем этапе, в зависимости от того, какую информацию вы получаете и как вы хотите, чтобы пользователь каждый раз идентифицировал себя. Но важная часть заключается в том, что им нужно отождествлять себя с чем-то уникальным, и это можно легко запечатлеть.
Использовать личность в одном сеансе
Если вы используете Google Sign In, вам не нужно беспокоиться об этом. Вы получите один и тот же идентификатор для каждого сеанса и для каждого вызова во время сеанса.
Если вы используете личное хранилище пользователя с помощью Google Assistant, это будет частью объекта userStore.
Но если это не так, вам нужно убедиться, что вы получили идентификатор пользователя в самом начале, и сохранить его как часть контекста, чтобы он сохранялся между вызовами вашего webhook. В последующих обработчиках вы можете получить идентификатор из контекста, а затем использовать его для доступа к другой информации.
Вам не нужно хранить его в базе данных на данный момент. Все, что у вас есть, это идентификатор - он станет ключом, который вы будете использовать для получения другой информации. Вам просто нужно запомнить это для последующих частей разговора.
Так в вашем 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
}
};
}
В качестве отступления - ваш обработчик, кажется, пытается определить, говорит ли это пользователь свое имя или подтверждает свое имя. Это, вероятно, лучше обрабатывать как отдельные намерения и отдельные обработчики. Попытка объединить их будет путать вещи.
Структурирование и доступ к вашей базе данных
У нас есть удостоверение личности. У нас есть пользователь, сообщающий данные. Как мы связываем два?
Существует множество способов структурировать данные, и Firebase углубляется в некоторые детали в зависимости от того, как вы собираетесь их использовать, получать к ним доступ и делать их доступными для пользователей или других лиц.
В этом случае кажется довольно простым, что вы хотите хранить записи о пользователе. Каждая запись может использовать свой идентификатор в качестве ключа, а затем содержать некоторую информацию о пользователе, включая его настроение.
Одна приятная вещь в базе данных Firebase заключается в том, что вы можете (в основном) обращаться с ней как с объектом Javascript. Если мы думаем об этом таким образом, это может выглядеть примерно так
{
"user": {
"id1":{...},
"id2":{...},
"id3":{
"moods": [
{"mood":"good"},
{"mood":"tired"}
]
},
"id4":{...}
}
}
И так далее. С помощью Firebase мы будем ссылаться на настроения пользователя "id3" с таким путем, как user/id3/moods
, Если у нас есть идентификатор пользователя в переменной name
мы могли бы использовать следующий код, чтобы получить эту ссылку
var ref = admin.database().ref('user').ref(name).ref('moods');
а затем используйте такой код, чтобы поместить объект с настроением в массив (и вернуть обещание, которое нам нужно сделать):
var obj = {
mood: mood
};
return ref.push( obj ).then( snapshot => {
// Do stuff, including acknowledge to the user you saved it.
});
Имейте в виду, что вы также можете использовать это, чтобы хранить больше информации о каждом пользователе (например, его имя или адрес электронной почты) на уровне пользователя, или больше о настроениях (таких как отметка времени) в объекте настроения.