Как использовать диалоговое окно 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.
});

Имейте в виду, что вы также можете использовать это, чтобы хранить больше информации о каждом пользователе (например, его имя или адрес электронной почты) на уровне пользователя, или больше о настроениях (таких как отметка времени) в объекте настроения.

Другие вопросы по тегам