Skip to main contentWatson Assistant web chat

Session history (beta)

Learn how to work with session history so that your user's conversations will continue seamlessly across page changes/reloads.

Overview

Session history allows your web chats to maintain conversation history and context when customers refresh the page or change to a different page on the same website. Like everything in beta, not everything will be perfect yet. You should only use this feature in a testing environment until it is generally available, and no longer in beta.

The conversation history lasts until the session times out. This feature only maintains conversations between customers and assistants, not customers and human agents. There are also some new events and methods to be aware of, depending on your customization needs.

Instructions

Once session history is out of beta and generally available, it will be enabled by default. Currently, in version 3.5.0 of web chat, the feature can be setup in minutes with the sessionHistoryBeta flag. Once you have added the feature flag to your embed script, session history in beta will start working automatically. Note: when session history is made generally available this flag will no longer do anything and can be removed from your embed script. For those of you customizing web chat, specifically with the customResponse or our pre:receive event, there are a few new events and methods to be aware of:

First, there are two new events to announce the history beginning to reload and the history completing its reload; these are history:begin and history:end. These events can be used to view the messages that are being reloaded and in the case of history:begin the messages can actually be edited before they are displayed.

Second, there have been changes made to pre:receive. Pre:receive now includes a flag that is enabled by default: event.updateHistory. This flag tells web chat if it should save the original message that existed before changes were made in pre:receive or if it should save the new message that's been created by the edits in pre:receive. If the flag is left as true then the message will be saved with the pre:receive edits and re-rendered on page change/reload exactly as it looked before the page change/reload.

Third, there's now a new instance method available to enable saving of state related to a specific message response: instance.updateHistoryUserDefined(). With the state saved a response can be re-rendered with the same state that it was initially rendered with. For an example of this see the "Example with session history" in the customResponse section.

Below you'll find a deeper dive into using the instance.updateHistoryUserDefined() function with a real world example, generating some custom buttons and persisting their selected state across page reloads.

Example

<!doctype html>
<html lang="en">

<head>
  <style>
    .button--selected {
      background: #4c4c4c !important;
      color: #fff !important;
    }

    .button--disabled {
      opacity: .75 !important;
      cursor: not-allowed !important;
    }
  </style>
</head>

<body>
  <script>
    // Used to create the buttons both on first render and on re-render after page change/refresh.
    function createButtons(event, instance) {
      const element = document.createElement('div')
      element.innerHTML =
        '<div>Choose a button. The selected button should be remembered if you reload the page.</div><br><button id="button1" type="button">Button 1</button><br><button id="button2" type="button" style="margin-bottom: 1rem;">Button 2</button>';
      element.querySelectorAll('button').forEach(function (button) {
        button.addEventListener('click', function saveButtonClick(e) {
          // If a button is clicked lets change the styles so it looks selected.
          button.classList.add("button--selected");
          // If any button was selected then disable all the buttons.
          element.querySelectorAll('button').forEach(function (button) {
            button.classList.add("button--disabled");
            button.disabled = true;
          });
          const sendObject = {
            "input": {
              "message_type": "text",
              "text": button.innerText + ' clicked',
            }
          }
          // Since a button has been selected lets save some state about which button was selected.
          instance.updateHistoryUserDefined(event.data.fullMessage.id, {
            buttonClicked: button.id
          });
          // And lets send the user's choice to Assistant so that dialog can respond.
          instance.send(sendObject);
        });
      });
      // Add the buttons to the element provided by the CustomResponse event.
      event.data.element.appendChild(element);
    }

    // Used to apply styles to the re-rendered buttons so they look like they did before reload.
    function setButtonsState(event) {
      event.data.element && event.data.element.children[0] && event.data.element.children[0].querySelectorAll(
        'button') && event.data.element.children[0].querySelectorAll('button').forEach(function (button) {
        // If the button is the one that we said was selected before page change then style it as selected again.
        if (button.id === event.data.fullMessage.history.user_defined.buttonClicked) {
          button.classList.add("button--selected");
          // If any button was selected then disable all the buttons.
          event.data.element && event.data.element.children[0] && event.data.element.children[0].querySelectorAll(
            'button') && event.data.element.children[0].querySelectorAll('button').forEach(function (button) {
            button.classList.add("button--disabled");
            button.disabled = true;
          })
        }
      })
    }

    window.watsonAssistantChatOptions = {
      integrationID: "YOUR_INTEGRATION_ID",
      region: "YOUR_REGION",
      serviceInstanceID: "YOUR_SERVICE_INSTANCE_ID",
      sessionHistoryBeta: true,
      onLoad: function (instance) {
        // See the "Custom response types" tutorial for more info on how to set up a customResponse handler like this.
        function customHandler(event) {
          if (event.data.message.user_defined && event.data.message.user_defined.template_name === "buttons") {
            createButtons(event, instance)
            if (event.data.fullMessage.history && event.data.fullMessage.history.user_defined && event.data
              .fullMessage.history.user_defined.buttonClicked) {
              setButtonsState(event);
            }
          }
        }
        instance.on({
          type: "customResponse",
          handler: customHandler
        });

        function historyBeginHandler(event) {
          // Loop through the messages returned from history.
          for (let i = 0; i < event.messages.length; i++) {
            // Find the message response that we saved buttonClicked data for.
            if (event.messages[i].history && event.messages[i].history.user_defined && event.messages[i].history
              .user_defined.buttonClicked) {
              // Console log the data that we saved.
              console.log(event.messages[i].history.user_defined.buttonClicked);
            }
          }
        }
        instance.on({
          type: "history:begin",
          handler: historyBeginHandler
        });

        instance.render();
      }
    };
    setTimeout(function () {
      const t = document.createElement('script');
      t.src="https://web-chat.global.assistant.watson.appdomain.cloud/loadWatsonAssistantChat.js";
      document.head.appendChild(t);
    });
  </script>
</body>

</html>

This pre-configured code snippet is just an example of some ways to use the available events and methods to edit messages and save their state for page changes/reloads with session history.

Watson Assistant
Hi! I’m a virtual assistant. How can I help you today?
Get started
Agent
Watson Assistant
Watson Assistant said
This dialog skill is configured to work like the example on this page. It's goal is to demonstrate working with session history, and custom response types. However, it is not a demo of all the functionality available with session history. Please read the instructions on this page for more info.

If you declare "Show me buttons", a user_defined response type will be returned that creates an element with two buttons.
    Watson Assistant said This dialog skill is configured to work like the example on this page. It's goal is to demonstrate working with session history, and custom response types. However, it is not a demo of all the functionality available with session history. Please read the instructions on this page for more info. If you declare "Show me buttons", a user_defined response type will be returned that creates an element with two buttons. Show me buttons.