Как идентифицировать уникальных пользователей с помощью Diagflow - PullRequest
0 голосов
/ 09 июня 2018

Я пытаюсь создать приложение-помощник и использую облачный сервис firestore для firebase, чтобы отправить ответ обратно в мое приложение, используя webhook в качестве выполнения.Я использовал параметр 'session' в запросе JSON в соответствии с этой документацией и отправлял executeilmentText в качестве ответа пользователю.Но всякий раз, когда пользователь запускает приложение, создается новый сеанс, который мне не нужен.Я просто хочу, просто одну запись для каждого пользователя в моей базе данных, чтобы узнать, как этого добиться с помощью диалогового потока.

В Alexa Skill у нас есть параметр deviceId, с помощью которого мы можем однозначно идентифицировать пользователя независимо от идентификатора сеанса.но есть ли параметр в запросе диалогового потока JSON.Если нет, то как выполнить эту задачу без нее.

В запросе JSON, который я получаю от Dialogflow, есть userID, поэтому я могу использовать userId или использовать userStorage, если параметр userStorage недоступно в запросе JSON.

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] ] } }

EDIT : Спасибо @Prisoner за ответ, но я не могу отправить случайный идентификатор, сгенерированный в ответе и введенный в полезную нагрузку.Ниже приведен код, где я генерирую 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;
        }

1 Ответ

0 голосов
/ 09 июня 2018

У вас есть несколько вариантов, в зависимости от ваших конкретных потребностей.

Простой: userStorage

Google предоставляет объект userStorageкоторый сохраняется в разговорах , когда он может идентифицировать пользователя .Это позволяет вам хранить свой собственный идентификатор, когда вам нужно отслеживать, когда пользователь возвращается.

Самый простой способ сделать это - проверить объект userStorage на наличие идентификатора при вызове вашего webhook.Если он не существует, создайте его, используя что-то вроде UUID v4, и сохраните его в объекте userStorage.

Если вы используете библиотеку actions-on-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
}

Если вы используете библиотеку диалоговых потоков, вы можете использовать вышеуказанное, но сначала вам понадобится эта строка:

let conv = agent.conv();

Если вы используете multivocal библиотека, она выполняет все вышеперечисленное для вас и предоставит идентификатор пользователя в среде по пути User/Id.

Если вы работаете с JSON напрямую, и вы используетеПротокол Dialogflow v2 позволяет получить объект userStorage, изучив originalDetectIntentRequest.payload.user.userStorage в объекте запроса JSON.Вы зададите объект 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),
      // ...
    }
  }
};

Обратите внимание на первую строку кода - если userStorage не существует, используйте пустой объект.Он не будет существовать до тех пор, пока вы не отправите ответ, включающий в себя сохранение чего-либо в нем в первый раз, что произойдет в последних нескольких строках этого кода.

Дополнительно: привязка учетной записи

Вы можете попросить пользователей выполнить вход в свое действие с помощью входа в Google .Это можно сделать, просто используя голосовую связь в самых простых случаях, и это приведет к прерыванию потока только в первый раз.

После этого вашему действию присваивается JWT, содержащий его идентификатор Google, который вы можете использовать в качестве идентификатора.

Если вы используете библиотеку actions-on-google, вы можете получить идентификатор из декодированного JWT со строкой, такой как:

const userId = conv.user.profile.payload.sub;

В многофакторной библиотеке идентификаториз декодированного JWT доступен в среде по пути User/Profile/sub

устарел: идентификатор анонимного пользователя

Здесь вы найдете ответы на StackOverflow, которые ссылаются наID анонимного пользователя.Google устарел этот идентификатор, который не всегда был надежным способом проверки возвращающихся пользователей, и будет удалять его 1 июня 2019 года.

Этот код еще отправляется, но он будет удален с 1 июня 2019 года..

...