Storage Keys
Browser Storage
localStorage
| Key | Type | Description |
|---|---|---|
chat-panel-size | string | Chat widget panel size preference ('default' or 'expanded') |
sessionStorage
| Key | Type | Description |
|---|---|---|
chat-messages | JSON | Cached chat messages for session continuity |
chat-session | JSON | Session state ({ state, mode }) for reconnection |
Both keys are cleared when a session ends.
Cloudflare KV (THREAD_MAP)
| Key Pattern | Value | TTL | Description |
|---|---|---|---|
rate:session:{ip} | Count (string) | 3600s | Rate limit counter per IP |
{threadTs} | Session ID (string) | 1800s | Maps Slack thread to DO session |
block:ip:{ip} | Any | None | IP block list entry |
block:email:{email} | Any | None | Email block list entry |
Durable Object Storage
Stored within each ChatSession Durable Object instance:
| Key | Type | Description |
|---|---|---|
session_state | SessionState | Core session data (visitor info, mode, Slack thread) |
last_visitor_message | number | Timestamp of last visitor message (inactivity tracking) |
last_anshul_reply | number | Timestamp of last Anshul reply (away indicator) |
last_unmatched_text | string | Last bot question — forwarded to Slack on escalation |
session_id | string | Session UUID |
conversation_history | ConversationHistory | AI chat history (messages + summary) |
message_count | number | Total messages sent in the session |
SessionState Shape
typescript
interface SessionState {
visitorName: string;
visitorEmail: string;
startPage: string;
slackThreadTs: string;
slackChannelId: string;
lastActivity: number;
mode: 'bot' | 'live';
messageCount?: number;
}ConversationHistory Shape
typescript
interface ConversationHistory {
messages: ChatCompletionMessage[]; // Recent messages (sliding window)
summary: string; // Summary of older messages
messageCount: number; // Total message count
}Cookies
| Name | Type | Domain | Expiry | Description |
|---|---|---|---|---|
__bypass | HttpOnly | chat.anshulbisen.com | 30 days | Rate limit bypass for site owner |