Skip to content

Chat System Overview

The portfolio includes a bi-directional live chat system that connects website visitors with Anshul via Slack, with an AI chatbot handling initial conversations.

How It Works

  1. Visitor opens chat — the widget connects to the chat worker via WebSocket
  2. Bot mode — Gemini 2.5 Flash answers questions using a knowledge base generated from site content
  3. Escalation — visitor clicks "Talk to Anshul" to switch to live mode
  4. Live mode — a Slack thread is created; messages relay bi-directionally between the widget and Slack
  5. Timeout — sessions close after 30 minutes of inactivity (10 minutes in bot mode)

Components

Frontend (src/components/chat/)

FilePurpose
ChatWidget.tsxMain widget container, resizable panel
ChatPanel.tsxChat panel with input, messages, header
MessageList.tsxMessage rendering with Slack markdown support

Hooks (src/hooks/)

FilePurpose
useChatSession.tsWebSocket connection, message state, session persistence

Worker (chat-worker/src/)

FilePurpose
index.tsHono router — all HTTP endpoints
chat-session.tsDurable Object — WebSocket handling, session state, alarms
ai-engine.tsGemini integration, prompt building, sliding window
ai-types.tsType definitions for AI system
rate-limiter.tsIP-based rate limiting middleware
slack.tsSlack API — thread creation, message posting, signature verification
content-filter.tsMessage content filtering
types.tsShared TypeScript types (SessionState, WS messages, Env)

Session Lifecycle

Visitor opens chat


POST /session (with Turnstile token)
    │  Creates Slack thread
    │  Creates Durable Object
    │  Returns sessionId


GET /ws/:sessionId (WebSocket upgrade)


Bot Mode ──── visitor sends messages ──── Gemini responds

    ▼ (visitor clicks "Talk to Anshul")

Live Mode ── visitor messages → Slack thread
          └─ Slack replies → visitor via WebSocket

    ▼ (30 min inactivity)

Session Ended