You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BotFramework WebChat聊天历史持久化:卡片交互失效求助

How to Preserve WebChat History with Interactive Components After Refresh/Reopen

Great question! The core issue here is that storing raw HTML strips away the event bindings WebChat relies on for interactive elements like Adaptive Cards, buttons, and carousels. Let’s break down the correct approach using DirectLine JS, plus why your HTML storage method falls short and how to address it if you need that path.

You mentioned thinking DirectLine JS only lets you fetch history but not load it into the chat window—this isn’t the case! WebChat is built to work with DirectLine’s activity data to render fully interactive messages. Here’s how to implement it properly:

Step 1: Fetch Conversation History via DirectLine

DirectLine provides a fetchActivities method to retrieve past messages from your conversation. You’ll need your conversation ID (you can grab this when initializing DirectLine or from the DIRECT_LINE/CONNECT_FULFILLED action in WebChat’s store).

Step 2: Initialize WebChat with Historical Activities

Instead of re-sending all messages to the bot, pass the fetched activities directly to WebChat using either the initialMessages prop or dispatch them through the store. This lets WebChat render each message natively, preserving all interactive functionality.

Here’s a code example:

// Initialize DirectLine with your token
const directLine = window.WebChat.createDirectLine({ token: 'YOUR_DIRECTLINE_TOKEN' });

// Fetch conversation history (adjust the count to load as many messages as needed)
directLine.fetchActivities('YOUR_CONVERSATION_ID', undefined, undefined, 100)
  .then(response => {
    const conversationHistory = response.activities;
    
    // Create a WebChat store to manage state, including history
    const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
      // When WebChat connects successfully, load the historical activities
      if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
        conversationHistory.forEach(activity => {
          dispatch({
            type: 'WEB_CHAT/RECEIVE_MESSAGE',
            payload: { activity }
          });
        });
      }
      return next(action);
    });

    // Render WebChat with the store and initial setup
    window.WebChat.renderWebChat({
      directLine,
      store
    }, document.getElementById('webchat'));
  });

Bonus: Save History to LocalStorage for Offline Access

If you want to persist history even if the conversation ID changes, save each incoming activity to localStorage as it arrives, then load it on page refresh:

const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
  // Save incoming activities to localStorage
  if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
    const { activity } = action.payload;
    let savedHistory = JSON.parse(localStorage.getItem('webchatHistory')) || [];
    savedHistory.push(activity);
    localStorage.setItem('webchatHistory', JSON.stringify(savedHistory));
  }
  return next(action);
});

// Load saved history on page load
const initialMessages = JSON.parse(localStorage.getItem('webchatHistory')) || [];

window.WebChat.renderWebChat({
  directLine,
  store,
  initialMessages
}, document.getElementById('webchat'));

This method ensures all Adaptive Cards, buttons, and carousels work exactly as they did before the refresh—WebChat handles the event bindings natively when rendering the activities.

If you’re set on storing HTML instead of activity data, you’ll need to manually reinitialize the interactive components after inserting the HTML into the DOM. This is far more complex because WebChat’s component logic is tightly coupled to its internal state and store.

For Adaptive Cards specifically, you’d need to:

  • Parse the card payload from the stored HTML (extract the adaptive-card element’s payload attribute)
  • Re-render the card using the Adaptive Cards SDK and bind its action handlers to WebChat’s store
  • Repeat this process for every interactive component (Hero Cards, buttons, etc.)

This approach is error-prone and requires duplicating a lot of WebChat’s internal logic, which is why using DirectLine activity data is the better choice.

Summary

The best solution is to use DirectLine JS to fetch and load conversation activities directly into WebChat. By storing activity data (not raw HTML) and letting WebChat render the messages natively, all interactive components will retain their functionality after a page refresh or reopen.

内容的提问来源于stack exchange,提问作者Janardhan Goud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:31:18