Skip to main content

Overview

The AI Chat Extension SDK provides a comprehensive event system that notifies your extension about user interactions, query classifications, and UI state changes. Events enable you to track user behavior, trigger analytics, and respond to chat interactions.

Registering event listeners

Use the registerEventListener method to subscribe to SDK events:
import {
  getAiChatExtensionSdk,
  AiChatExtensionSdkEventType,
} from '@sleek/ai-chat-extension-sdk';

getAiChatExtensionSdk().registerEventListener((event, tabDetails) => {
  console.log('Event type:', event.type);
  console.log('Event data:', event.data);
  console.log('Tab details:', tabDetails);

  switch (event.type) {
    case AiChatExtensionSdkEventType.QUERY_CLASSIFIED:
      // Handle query classification
      break;
    case AiChatExtensionSdkEventType.CHAT_PANEL_OPENED:
      // Handle panel opened
      break;
    // ... handle other events
  }
});
You can register multiple listeners, and all will be called when an event occurs.

Event structure

All events follow this structure:
interface AiChatExtensionSdkEvent {
  type: AiChatExtensionSdkEventType;
  data: EventData;  // Type varies by event
}

interface TabDetails {
  tabId: number;
  tabUrl: string;
}
  • type: The event type (see available events below)
  • data: Event-specific payload
  • tabDetails: Information about the tab where the event occurred

Chat panel events base payload

All chat panel events include a chatSessionId in their data payload:
type ChatPanelEventBasePayload = {
  chatSessionId: string;
};
This allows you to correlate events within the same chat session.

Available events

QUERY_CLASSIFIED

Emitted when a user’s query has been analyzed and classified. Event type: AiChatExtensionSdkEventType.QUERY_CLASSIFIED Data payload:
{
  origin: string;                   // Where the query was detected (e.g., 'google', 'chatgpt')
  query: string;                    // The query text
  classification: 'shopping' | 'unknown';
  suggestedPrompts?: string[];      // Optional suggested prompts
}
Example:
case AiChatExtensionSdkEventType.QUERY_CLASSIFIED:
  if (event.data.classification === 'shopping') {
    console.log(`Shopping query detected on ${event.data.origin}: "${event.data.query}"`);
    console.log('Suggested prompts:', event.data.suggestedPrompts);

    analytics.track('shopping_query_detected', {
      origin: event.data.origin,
      query: event.data.query,
      promptCount: event.data.suggestedPrompts?.length ?? 0,
    });
  }
  break;

CHAT_BADGE_SHOWN

Emitted when the chat badge becomes visible to the user. Event type: AiChatExtensionSdkEventType.CHAT_BADGE_SHOWN Data payload:
{
  query: string;
  suggestedPrompts?: string[];
}

CHAT_BADGE_CLICKED

Emitted when a user clicks on the chat badge or one of its suggested prompts. Event type: AiChatExtensionSdkEventType.CHAT_BADGE_CLICKED Data payload:
{
  prompt?: string;  // The specific prompt clicked, or undefined if badge itself clicked
}

CHAT_BADGE_CLOSED

Emitted when a user dismisses the chat badge. Event type: AiChatExtensionSdkEventType.CHAT_BADGE_CLOSED Data payload:
{
  suggestedPrompts?: string[];
}

CHAT_PANEL_OPENED

Emitted when the chat panel becomes visible to the user. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_OPENED Data payload:
{
  chatSessionId: string;
  initialMessage?: string;  // The prompt or message that opened the panel
}

CHAT_PANEL_CLOSED

Emitted when the user closes the chat panel. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_CLOSED Data payload:
{
  chatSessionId: string;
}

CHAT_PANEL_MESSAGE_SENT

Emitted when the user sends a message in the chat panel. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_MESSAGE_SENT Data payload:
{
  chatSessionId: string;
}

CHAT_PANEL_PROMPTS_SHOWN

Emitted when suggested prompts are displayed in the chat panel. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_PROMPTS_SHOWN Data payload:
{
  chatSessionId: string;
  prompts: string[];
}

CHAT_PANEL_PROMPT_CLICKED

Emitted when the user clicks a suggested prompt in the chat panel. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_PROMPT_CLICKED Data payload:
{
  chatSessionId: string;
  prompt: string;
}
Emitted when the user clicks a link in a chat message. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_LINK_CLICKED Data payload:
{
  chatSessionId: string;
  url: string;
  merchantName?: string;
  merchantUrl?: string;
}

CHAT_PANEL_TOP_MERCHANTS_SHOWN

Emitted when top merchants are displayed in the chat. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_TOP_MERCHANTS_SHOWN Data payload:
{
  chatSessionId: string;
  merchants: string[];
}

CHAT_PANEL_TOP_MERCHANTS_CLICKED

Emitted when the user clicks on a top merchant. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_TOP_MERCHANTS_CLICKED Data payload:
{
  chatSessionId: string;
  url: string;
  merchantName?: string;
  merchantUrl?: string;
}

CHAT_PANEL_PRODUCTS_SHOWN

Emitted when products are displayed in the chat. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_PRODUCTS_SHOWN Data payload:
{
  chatSessionId: string;
}

CHAT_PANEL_PRODUCTS_CLICKED

Emitted when the user clicks on a product. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_PRODUCTS_CLICKED Data payload:
{
  chatSessionId: string;
  url: string;
  merchantName?: string;
  merchantUrl?: string;
}

CHAT_PANEL_PRODUCTS_PAGE_NEXT_CLICKED

Emitted when the user clicks to view the next page of products. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_PRODUCTS_PAGE_NEXT_CLICKED Data payload:
{
  chatSessionId: string;
}

CHAT_PANEL_PRODUCTS_PAGE_PREVIOUS_CLICKED

Emitted when the user clicks to view the previous page of products. Event type: AiChatExtensionSdkEventType.CHAT_PANEL_PRODUCTS_PAGE_PREVIOUS_CLICKED Data payload:
{
  chatSessionId: string;
}

Event flow examples

Typical shopping query flow

1. User types "best running shoes" on Google Search

2. QUERY_CLASSIFIED
   - origin: 'google'
   - classification: 'shopping'
   - query: 'best running shoes'
   - suggestedPrompts: ['Compare running shoe brands', 'Show me deals', ...]

3. CHAT_BADGE_SHOWN
   - query: 'best running shoes'
   - suggestedPrompts: [...]

4. User clicks "Compare running shoe brands" prompt

5. CHAT_BADGE_CLICKED
   - prompt: 'Compare running shoe brands'

6. CHAT_PANEL_OPENED
   - chatSessionId: 'abc123'
   - initialMessage: 'Compare running shoe brands'

7. CHAT_PANEL_PROMPTS_SHOWN
   - chatSessionId: 'abc123'
   - prompts: ['Show top brands', 'Find deals', ...]

8. User clicks a product link

9. CHAT_PANEL_PRODUCTS_CLICKED
   - chatSessionId: 'abc123'
   - url: 'https://merchant.com/product'
   - merchantName: 'Merchant'

10. User closes panel

11. CHAT_PANEL_CLOSED
   - chatSessionId: 'abc123'

Badge dismissal flow

1. User types "flights to Paris" on Google Search

2. QUERY_CLASSIFIED
   - origin: 'google'
   - classification: 'shopping'
   - query: 'flights to Paris'

3. CHAT_BADGE_SHOWN
   - query: 'flights to Paris'

4. User clicks dismiss/close on badge

5. CHAT_BADGE_CLOSED
   - suggestedPrompts: [...]

Analytics integration example

Here’s a complete example of integrating SDK events with an analytics service:
import {
  getAiChatExtensionSdk,
  AiChatExtensionSdkEventType,
  type AiChatExtensionSdkEvent,
} from '@sleek/ai-chat-extension-sdk';

// Track session durations
const sessionTimers = new Map<string, number>();

// Register event listener
getAiChatExtensionSdk().registerEventListener((event, tabDetails) => {
  const baseProperties = {
    tabId: tabDetails.tabId,
    tabUrl: tabDetails.tabUrl,
    timestamp: Date.now(),
  };

  switch (event.type) {
    case AiChatExtensionSdkEventType.QUERY_CLASSIFIED:
      analytics.track('ai_chat_query_classified', {
        ...baseProperties,
        origin: event.data.origin,
        classification: event.data.classification,
        query: event.data.query,
        isShoppingQuery: event.data.classification === 'shopping',
      });
      break;

    case AiChatExtensionSdkEventType.CHAT_BADGE_SHOWN:
      analytics.track('ai_chat_badge_shown', {
        ...baseProperties,
        query: event.data.query,
        promptCount: event.data.suggestedPrompts?.length ?? 0,
      });
      break;

    case AiChatExtensionSdkEventType.CHAT_BADGE_CLICKED:
      analytics.track('ai_chat_badge_clicked', {
        ...baseProperties,
        clickedPrompt: event.data.prompt,
        clickedSuggestedPrompt: !!event.data.prompt,
      });
      break;

    case AiChatExtensionSdkEventType.CHAT_BADGE_CLOSED:
      analytics.track('ai_chat_badge_dismissed', {
        ...baseProperties,
        promptCount: event.data.suggestedPrompts?.length ?? 0,
      });
      break;

    case AiChatExtensionSdkEventType.CHAT_PANEL_OPENED:
      sessionTimers.set(event.data.chatSessionId, Date.now());

      analytics.track('ai_chat_panel_opened', {
        ...baseProperties,
        chatSessionId: event.data.chatSessionId,
        hasInitialMessage: !!event.data.initialMessage,
        initialMessage: event.data.initialMessage,
      });
      break;

    case AiChatExtensionSdkEventType.CHAT_PANEL_MESSAGE_SENT:
      analytics.track('ai_chat_message_sent', {
        ...baseProperties,
        chatSessionId: event.data.chatSessionId,
      });
      break;

    case AiChatExtensionSdkEventType.CHAT_PANEL_LINK_CLICKED:
      analytics.track('ai_chat_link_clicked', {
        ...baseProperties,
        chatSessionId: event.data.chatSessionId,
        url: event.data.url,
        merchantName: event.data.merchantName,
        merchantUrl: event.data.merchantUrl,
      });
      break;

    case AiChatExtensionSdkEventType.CHAT_PANEL_PRODUCTS_CLICKED:
      analytics.track('ai_chat_product_clicked', {
        ...baseProperties,
        chatSessionId: event.data.chatSessionId,
        url: event.data.url,
        merchantName: event.data.merchantName,
        merchantUrl: event.data.merchantUrl,
      });
      break;

    case AiChatExtensionSdkEventType.CHAT_PANEL_TOP_MERCHANTS_CLICKED:
      analytics.track('ai_chat_merchant_clicked', {
        ...baseProperties,
        chatSessionId: event.data.chatSessionId,
        url: event.data.url,
        merchantName: event.data.merchantName,
        merchantUrl: event.data.merchantUrl,
      });
      break;

    case AiChatExtensionSdkEventType.CHAT_PANEL_CLOSED:
      const startTime = sessionTimers.get(event.data.chatSessionId);
      const duration = startTime ? Date.now() - startTime : 0;

      analytics.track('ai_chat_panel_closed', {
        ...baseProperties,
        chatSessionId: event.data.chatSessionId,
        sessionDurationMs: duration,
        sessionDurationSeconds: Math.floor(duration / 1000),
      });

      sessionTimers.delete(event.data.chatSessionId);
      break;
  }
});

Debugging events

Enable debug mode to see all events logged to the console:
await initializeAiChatExtensionSdk('your-api-key', {
  enableDebug: true,  // Enable debug logging
  // ... other options
});
You can also add a simple debug listener:
getAiChatExtensionSdk().registerEventListener((event, tabDetails) => {
  console.group(`🎯 SDK Event: ${event.type}`);
  console.log('Data:', event.data);
  console.log('Tab:', tabDetails.tabId, tabDetails.tabUrl);
  console.groupEnd();
});

Best practices

1. Track meaningful metrics

Focus on events that provide business value:
  • Conversion funnel: QUERY_CLASSIFIEDCHAT_BADGE_SHOWNCHAT_BADGE_CLICKEDCHAT_PANEL_OPENED
  • Engagement: Session durations, messages sent, products/merchants clicked
  • Monetization: Track CHAT_PANEL_LINK_CLICKED, CHAT_PANEL_PRODUCTS_CLICKED, and CHAT_PANEL_TOP_MERCHANTS_CLICKED
  • Friction points: CHAT_BADGE_CLOSED (dismissals)

2. Handle errors gracefully

Wrap event handlers in try-catch to prevent one handler from breaking others:
getAiChatExtensionSdk().registerEventListener((event, tabDetails) => {
  try {
    // Your event handling logic
    handleEvent(event, tabDetails);
  } catch (error) {
    console.error('Error handling SDK event:', error);
  }
});

3. Avoid blocking operations

Event handlers should be fast and non-blocking. Use async operations carefully:
getAiChatExtensionSdk().registerEventListener((event, tabDetails) => {
  // Good: Fire and forget
  analytics.track(event.type, event.data);

  // Avoid: Blocking async operation
  // await someSlowOperation();
});

4. Use chatSessionId for correlation

Use the chatSessionId field to correlate events within the same chat session:
const sessionMetrics = new Map<string, {
  opened: number;
  messageCount: number;
  linksClicked: number;
}>();

getAiChatExtensionSdk().registerEventListener((event, tabDetails) => {
  if ('chatSessionId' in event.data) {
    const sessionId = event.data.chatSessionId;

    switch (event.type) {
      case AiChatExtensionSdkEventType.CHAT_PANEL_OPENED:
        sessionMetrics.set(sessionId, {
          opened: Date.now(),
          messageCount: 0,
          linksClicked: 0,
        });
        break;

      case AiChatExtensionSdkEventType.CHAT_PANEL_MESSAGE_SENT:
        const metrics = sessionMetrics.get(sessionId);
        if (metrics) metrics.messageCount++;
        break;

      case AiChatExtensionSdkEventType.CHAT_PANEL_LINK_CLICKED:
      case AiChatExtensionSdkEventType.CHAT_PANEL_PRODUCTS_CLICKED:
        const m = sessionMetrics.get(sessionId);
        if (m) m.linksClicked++;
        break;
    }
  }
});