Есть ли способ сохранить историю чата в веб-чате MS Bot Framework после перезагрузки страницы / перехода на другую страницу? - PullRequest
0 голосов
/ 10 июля 2019

Я пытаюсь сохранить разговор пользователя с ботом во время перезагрузки страницы и перехода на другие страницы сайта, на который ссылается бот.

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

Данный бот встраивается в веб-страницу, следуя инструкциям из документов: https://docs.microsoft.com/bs-latn-ba/azure/bot-service/bot-service-channel-connect-webchat?view=azure-bot-service-4.0

Я читал другие статьи, в которых для определения истории чата между загрузками страниц использовался разговор, хотя это было для канала DirectLine. А также некоторые другие статьи, в которых предлагалось сохранить разговор в базе данных и передать сообщения обратно в окно чата. Хотя это, кажется, не лучший способ сделать это.

Я попытался передать разговор в iframe, но он не сработал. Есть ли способ сохранить разговор, передав его в iframe?

Это код для отображения чат-бота в iframe:

<iframe src='https://webchat.botframework.com/embed/THECHATBOT?s=YOUR_SECRET_HERE' style='min-width: 400px; width: 100%; min-height: 500px;'></iframe>

Это моя попытка передать разговор в качестве параметра:

<iframe src='https://webchat.botframework.com/embed/THECHATBOT?s=YOUR_SECRET_HERE&conversationId?=THE_CONVERSATIONID_VALUE' style='min-width: 400px; width: 100%; min-height: 500px;'></iframe>

Я ожидаю, что окно чата будет заполнено разговором, который ранее имел пользователь, я получаю, что разговор сбрасывается и история не поддерживается.

1 Ответ

0 голосов
/ 11 июля 2019

Если вы ищете какую-либо настройку веб-чата, я настоятельно рекомендую вам отказаться от использования опции <iframe> канала веб-чата.Это полезно, если вам нужен простой плагинный компонент, но он не предлагает столько вариантов настройки, которые предлагает BotFramework-WebChat .

Если вы планируете использовать реакцию v4на основе веб-чата (на который есть ссылка в приведенной выше ссылке), тогда в следующем примере вам будет предоставлена ​​нужная вам функциональность.

Обратите внимание, для простоты я сохраняю идентификатор сообщения в хранилище сеанса.

Кроме того, я генерирую токен, выполняя вызов API для локальной конечной точки прямой линии.Я добавил код в конце для того же.Вы можете передать свой секрет прямой линии против конечной точки directline/tokens/generate в файле html, однако это крайне нежелательно из соображений безопасности.

Наконец, свойство watermark, используемое вМетод createDirectLine () указывает количество отображаемых прошлых действий (сообщений, карточек и т. д.).

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>WebChat</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
    }

    #webchat {
      height: 100%;
      width: 40%;
    }

    #webchat>* {
      height: 100%;
      width: 100%;
    }
  </style>
  </head>

  <body>
    <div id="webchat" role="main"></div>
    <script type="text/javascript"
      src="https://unpkg.com/markdown-it/dist/markdown-it.min.js"></script>
    <script
      src="https://cdn.botframework.com/botframework-webchat/master/webchat.js"></script>
    <script>
    ( async function () {
      let { token, conversationId } = sessionStorage;

      if (!token) {
        const res = await fetch( 'http://localhost:3500/directline/token', { method: 'POST' } );
        const { token: directLineToken } = await res.json();

        sessionStorage['token'] = directLineToken;
        token = directLineToken;
      }

      if (conversationId) {
        const res = await fetch(`https://directline.botframework.com/v3/directline/conversations/${ conversationId }`, {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${ token }`,
          },
        });

        let { conversationId } = await res.json();
        sessionStorage['conversationId'] = conversationId;
      } 

      const directLine = createDirectLine({
        token,
        webSockets: true,
        watermark: 10
      });

      window.WebChat.renderWebChat( {
        directLine: directLine,
      }, document.getElementById( 'webchat' ) );
      document.querySelector( '#webchat > *' ).focus();
    } )().catch( err => console.error( err ) );
    </script>
  </body>
</html>

Вот код для генерации токена.Я добавил это в конец моего файла index.js в моем боте.Вы также можете запустить это как отдельный проект.

Когда я запускаю свой бот локально, конечная точка становится доступной.Вы должны быть в состоянии сделать что-то подобное, если вы работаете с ботом C #.Используемый здесь порт должен быть тем же самым портом, на который ссылается вышеупомянутый directline/token вызов.

directLineSecret сохраняется и доступен из файла .env.

/**
 * Creates token server
 */
const bodyParser = require('body-parser');
const request = require('request');
const corsMiddleware = require('restify-cors-middleware');

const cors = corsMiddleware({
  origins: ['*']
});

// Create server.
let tokenServer = restify.createServer();
tokenServer.pre(cors.preflight);
tokenServer.use(cors.actual);
tokenServer.use(bodyParser.json({
  extended: false
}));
tokenServer.dl_name = 'DirectLine';
tokenServer.listen(process.env.port || process.env.PORT || 3500, function() {
  console.log(`\n${ tokenServer.dl_name } listening to ${ tokenServer.url }.`);
});

// Listen for incoming requests.
tokenServer.post('/directline/token', (req, res) => {
  // userId must start with `dl_`
  const userId = (req.body && req.body.id) ? req.body.id : `dl_${ Date.now() + Math.random().toString(36) }`;
  const options = {
    method: 'POST',
    uri: 'https://directline.botframework.com/v3/directline/tokens/generate',
    headers: {
      'Authorization': `Bearer ${ process.env.directLineSecret }`
    },
    json: {
      User: {
        Id: userId
      }
    }
  };
  request.post(options, (error, response, body) => {
    if (!error && response.statusCode < 300) {
      res.send({
        token: body.token
      });
    } else {
      res.status(500);
      res.send('Call to retrieve token from DirectLine failed');
    }
  });
});

Надежда на помощь!

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