Skip to content

Commit 8b67c80

Browse files
Stewart86claude
andcommitted
feat: replace thread-name session storage with JSON file persistence
Replace the cumbersome system of encoding session IDs in thread names with a clean JSON-based session storage system. This improves UX with cleaner thread names while maintaining persistent session data across Docker restarts. • Add Bun file utilities for JSON operations in /app/data/thread-sessions.json • Implement loadSessions, saveSessions, storeThreadSession, getThreadSession functions • Use clean thread names like "Bobby - Analysis" instead of encoding session IDs • Store session data (ID, title, creation time) persistently in JSON file • Update thread lookup to use thread ID as key instead of parsing names • Leverage Bun's native file.exists(), file.json(), and Bun.write() methods 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 8c55a01 commit 8b67c80

File tree

1 file changed

+55
-25
lines changed

1 file changed

+55
-25
lines changed

index.js

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,50 @@
77

88
import { Client, Events, GatewayIntentBits, ThreadAutoArchiveDuration } from "discord.js";
99
import { spawn } from "bun";
10+
import { join } from "path";
1011

1112
// Environment variables
1213
const DISCORD_TOKEN = process.env.DISCORD_TOKEN;
1314
const GITHUB_REPO = process.env.GITHUB_REPO;
1415

16+
// Session storage configuration
17+
const DATA_DIR = process.env.CLAUDE_CONFIG_DIR || "/app/data";
18+
const SESSIONS_FILE = join(DATA_DIR, "thread-sessions.json");
19+
20+
// Session storage utilities using Bun file methods
21+
async function loadSessions() {
22+
try {
23+
const file = Bun.file(SESSIONS_FILE);
24+
if (await file.exists()) {
25+
return await file.json();
26+
}
27+
return {};
28+
} catch (error) {
29+
console.error("Error loading sessions:", error);
30+
return {};
31+
}
32+
}
33+
34+
async function saveSessions(sessions) {
35+
try {
36+
await Bun.write(SESSIONS_FILE, JSON.stringify(sessions, null, 2));
37+
} catch (error) {
38+
console.error("Error saving sessions:", error);
39+
}
40+
}
41+
42+
async function storeThreadSession(threadId, sessionId, title) {
43+
const sessions = await loadSessions();
44+
sessions[threadId] = { sessionId, title, createdAt: new Date().toISOString() };
45+
await saveSessions(sessions);
46+
console.log(`Stored session: ${threadId} -> ${sessionId} (${title})`);
47+
}
48+
49+
async function getThreadSession(threadId) {
50+
const sessions = await loadSessions();
51+
return sessions[threadId] || null;
52+
}
53+
1554
if (!DISCORD_TOKEN) {
1655
console.error("Error: DISCORD_TOKEN environment variable is not set");
1756
process.exit(1);
@@ -422,14 +461,7 @@ function isNewBobbyCall(message) {
422461
// Check if this is a follow-up in a Bobby thread
423462
function isThreadFollowUp(message) {
424463
return message.channel.isThread() &&
425-
message.channel.name.startsWith('Bobby -');
426-
}
427-
428-
// Extract session ID from thread name
429-
function extractSessionId(threadName) {
430-
// Match new format: "Bobby - Title - session-id"
431-
const match = threadName.match(/Bobby - .+ - ([a-f0-9-]+)$/);
432-
return match ? match[1] : null;
464+
message.channel.name.startsWith('Bobby');
433465
}
434466

435467
// Discord client ready event
@@ -496,9 +528,9 @@ client.on(Events.MessageCreate, async (message) => {
496528
console.log(`New Bobby call: "${query}" from ${message.author.username}`);
497529

498530
try {
499-
// Create a new thread
531+
// Create a new thread with simple naming
500532
const thread = await message.startThread({
501-
name: `Bobby [PENDING]`,
533+
name: `Bobby Analysis`,
502534
autoArchiveDuration: ThreadAutoArchiveDuration.OneDay,
503535
reason: 'Bobby analysis request',
504536
});
@@ -511,21 +543,17 @@ client.on(Events.MessageCreate, async (message) => {
511543
await processWithClaude(query, thread, null);
512544

513545
if (success && sessionId) {
514-
// Update thread name with session ID and title
546+
// Store session data in JSON file instead of thread name
515547
const finalTitle = threadTitle || "Analysis";
516-
const newThreadName = `Bobby - ${finalTitle} - ${sessionId}`;
548+
await storeThreadSession(thread.id, sessionId, finalTitle);
517549

550+
// Update thread name with a clean title
518551
try {
519-
await thread.setName(newThreadName);
520-
console.log(`Updated thread name to: ${newThreadName}`);
552+
await thread.setName(`Bobby - ${finalTitle}`);
553+
console.log(`Updated thread name to: Bobby - ${finalTitle}`);
521554
} catch (renameError) {
522555
console.error("Error renaming thread:", renameError);
523-
// Fallback name if title is too long or other error
524-
try {
525-
await thread.setName(`Bobby - ${sessionId}`);
526-
} catch (fallbackError) {
527-
console.error("Error setting fallback thread name:", fallbackError);
528-
}
556+
// Keep default name if renaming fails
529557
}
530558
}
531559

@@ -549,18 +577,20 @@ client.on(Events.MessageCreate, async (message) => {
549577
return;
550578
}
551579

552-
const sessionId = extractSessionId(message.channel.name);
553-
console.log(`Thread follow-up: "${query}" in session ${sessionId}`);
580+
const sessionData = await getThreadSession(message.channel.id);
581+
console.log(`Thread follow-up: "${query}" in thread ${message.channel.id}`);
554582

555-
if (!sessionId) {
556-
await message.reply("⚠️ Could not find session ID. Please start a new conversation by mentioning Bobby in the main channel.");
583+
if (!sessionData || !sessionData.sessionId) {
584+
await message.reply("⚠️ Could not find session data. Please start a new conversation by mentioning Bobby in the main channel.");
557585
return;
558586
}
559587

588+
console.log(`Using session ID: ${sessionData.sessionId} (${sessionData.title})`);
589+
560590
try {
561591
await message.channel.sendTyping();
562592
const { success, response, isBug } =
563-
await processWithClaude(query, message.channel, sessionId);
593+
await processWithClaude(query, message.channel, sessionData.sessionId);
564594

565595
if (!success) {
566596
await message.channel.send("Sorry, I encountered an error while processing your request.");

0 commit comments

Comments
 (0)