сохранять уникальные идентификаторы пользователей в диалогах с Dialogflow (ОШИБКА userStorage Не удается установить заголовки после отправки пользователю) - PullRequest
1 голос
/ 20 июня 2020

Я пытаюсь создать приложение Google Home и использую веб-перехватчики с express. js, запущенным на локальном сервере в качестве выполнения. Я хотел бы использовать параметр request.body.originalDetectIntentRequest.payload.user.userStorage из запроса, чтобы идентифицировать пользователя, когда веб-перехватчик отправляет почтовый запрос на мой сервер. UserId, указанный в этом запросе, равен имени файла журнала, который я храню локально для каждого пользователя, где я отслеживаю разные вещи для каждого пользователя.

Я получил идею обрабатывать подобные вещи от более ранняя публикация здесь о переполнении стека . В ответе Заключенного он говорит о важности ответа, который вы должны отправить обратно. Пока все хорошо, я попытался реализовать это в своем коде, отправив ответ после создания нового userId, но я продолжаю получать ту же ошибку:

(node:21236) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:518:11)

Так что, вероятно, это связано с тем, что У меня есть строка agent.handleRequest(intentMap); в конце моего кода, которая будет обрабатывать запрос и отправлять ответ самому пользователю.

Как мне решить эту проблему? Я уже пытался найти решение этой проблемы, но, попробовав разные вещи, я могу придумать только одну вещь, которая заключалась бы в том, чтобы расширить ответ перед его отправкой с переменной payload.google.userStorage, хотя я пробовал ответить .write, но это давало мне ту же ошибку.

Мой код:

  app.post('/', express.json(), (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));
  
  let userStorage = request.body.originalDetectIntentRequest.payload.user.userStorage || JSON.stringify({});
  let userId;
  console.log("userStorage", userStorage);
  userStorage = JSON.parse(userStorage);
  console.log("userStorage_after_parsing", userStorage);
  if (userStorage.hasOwnProperty('userId')) {
      userId = userStorage.userId;
      console.log('user was already defined:' + userId);
  } else {
    let uuid = require('uuid/v4');
    checkNewUser = true;
    userId = uuid();
    userStorage.userId = userId
    console.log(userId);
    response.send({
      'payload': {
        'google': {
          'userStorage': JSON.stringify(userStorage)
        }
      }
    }
    );
//rest of the code
agent.handle(intentMap)

ОБНОВЛЕННЫЙ ВОПРОС:

После ответа заключенного я решил включить код handleWelcome intent, в которое я хотел бы вставить код, чтобы расширить ответ с помощью переменной userStorage:

      function handleWelcome(agent) {
    //code to add userStorage to the response?
    if (checkIfUserVerified() === true) {
      agent.add('Hi.');
      //updateLog('User just said hi.');
      let userObj = readJsonSync(userId + '.json');
      userObj.logs.push('User just started talking to this chatbot ' + getCurrentDateTime());
      fs.writeFileSync(userId + '.json', JSON.stringify(userObj));
    }
    else {
      close('Please make sure you are a verified user before using this version of SMART4MD. To do so, read the SMART4MD Voice assistant manual.');
      agent.setFollowupEvent('GOODBYE');
    }
  } 

1 Ответ

1 голос
/ 20 июня 2020

Обратите внимание на комментарий в цитируемом вами ответе, где

// Make sure you include the userStorage as part of the response

«часть» ответа, а не сам ответ. В вашем коде вы отправляете обратно JSON для отправки пользовательского хранилища до вызова вашего Intent Handler. Как только что-то отправлено, соединение закрывается, поэтому больше ничего не может быть отправлено, включая ответ, который вы хотите. Вот почему вы получаете сообщение об ошибке.

Вы не показываете ни одну из своих функций Intent Handler, поэтому сложно дать вам точный ответ, но общим решением было бы установить идентификатор пользователя в userStorage как часть функции, которую вызывает каждый обработчик.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...