From a2dc15cf10ef864493bbd5d2306280354dae65dc Mon Sep 17 00:00:00 2001 From: Madison Date: Sun, 6 Jul 2025 16:14:58 -0700 Subject: [PATCH] updated discord webhook message --- docs/lib/discord-webhook.ts | 83 +++++++---------------- docs/src/app/api/chat/route.ts | 8 +-- docs/src/app/api/discord-webhook/route.ts | 1 + docs/src/components/chat/ai-chat.tsx | 63 ++++++++++------- 4 files changed, 69 insertions(+), 86 deletions(-) diff --git a/docs/lib/discord-webhook.ts b/docs/lib/discord-webhook.ts index 2c9439ed6..119f8ab45 100644 --- a/docs/lib/discord-webhook.ts +++ b/docs/lib/discord-webhook.ts @@ -1,26 +1,18 @@ /** - * Sends a message to Discord webhook with rich metadata + * Sends a message to Discord webhook with session tracking */ export async function sendToDiscordWebhook(data: { message: string; username?: string; metadata?: { - url?: string; + sessionId?: string; + messageNumber?: number; pathname?: string; timestamp?: string; userAgent?: string; - viewport?: string; - isHomePage?: boolean; - isScrolled?: boolean; - messageLength?: number; messageType?: string; - sessionMessageCount?: number; timeOnPage?: number; - scrollDepth?: number; - referrer?: string; - language?: string; - timezone?: string; - chatExpanded?: boolean; + isFollowUp?: boolean; }; }) { const webhookUrl = process.env.DISCORD_WEBHOOK_URL; @@ -33,54 +25,27 @@ export async function sendToDiscordWebhook(data: { try { const { message, username, metadata } = data; - // Create a rich embed with metadata - const embed = { - title: "šŸ’¬ AI Chat Message", - description: message.length > 100 ? message.substring(0, 100) + "..." : message, - color: metadata?.messageType === 'starter-prompt' ? 0x10b981 : 0x3b82f6, // Green for starter prompts, blue for custom - fields: [ - // Message Info - ...(metadata?.messageType ? [{ name: "šŸ“ Type", value: metadata.messageType === 'starter-prompt' ? "Starter Prompt" : "Custom Message", inline: true }] : []), - ...(metadata?.messageLength ? [{ name: "šŸ“ Length", value: `${metadata.messageLength} chars`, inline: true }] : []), - ...(metadata?.chatExpanded !== undefined ? [{ name: "šŸ” Chat Mode", value: metadata.chatExpanded ? "Expanded" : "Normal", inline: true }] : []), - - // Page Context - ...(metadata?.pathname ? [{ name: "šŸ“„ Page", value: metadata.pathname, inline: true }] : []), - ...(metadata?.isHomePage !== undefined ? [{ name: "šŸ  Homepage", value: metadata.isHomePage ? "Yes" : "No", inline: true }] : []), - ...(metadata?.isScrolled !== undefined ? [{ name: "šŸ“œ Scrolled", value: metadata.isScrolled ? "Yes" : "No", inline: true }] : []), - - // Session Data - ...(metadata?.sessionMessageCount ? [{ name: "šŸ’¬ Session Messages", value: metadata.sessionMessageCount.toString(), inline: true }] : []), - ...(metadata?.timeOnPage ? [{ name: "ā±ļø Time on Page", value: formatTime(metadata.timeOnPage), inline: true }] : []), - ...(metadata?.scrollDepth !== undefined ? [{ name: "šŸ“Š Scroll Depth", value: `${metadata.scrollDepth}%`, inline: true }] : []), - - // Technical Info - ...(metadata?.viewport ? [{ name: "šŸ“± Viewport", value: metadata.viewport, inline: true }] : []), - ...(metadata?.language ? [{ name: "🌐 Language", value: metadata.language, inline: true }] : []), - ...(metadata?.timezone ? [{ name: "ā° Timezone", value: metadata.timezone, inline: true }] : []), - ], - timestamp: metadata?.timestamp || new Date().toISOString(), - footer: { - text: "Stack Auth Docs AI Chat", - icon_url: "https://cdn.discordapp.com/embed/avatars/0.png" - } - }; - - // Add full message as a separate field if it was truncated - if (message.length > 100) { - embed.fields.unshift({ name: "šŸ“ Full Message", value: message, inline: false }); - } - - // Extract browser info from user agent + // Format message with clean text structure + const sessionPrefix = metadata?.sessionId ? metadata.sessionId.slice(-8) : 'unknown'; + const messageNumber = metadata?.messageNumber || 1; + const isFollowUp = metadata?.isFollowUp || false; + const messageType = metadata?.messageType === 'starter-prompt' ? '🟢 Starter' : 'šŸ”µ Custom'; + const timeOnPage = metadata?.timeOnPage ? formatTime(metadata.timeOnPage) : 'N/A'; const browserInfo = extractBrowserInfo(metadata?.userAgent || ''); - if (browserInfo) { - embed.fields.push({ name: "🌐 Browser", value: browserInfo, inline: true }); - } + const page = metadata?.pathname || 'Unknown'; + + // Create formatted message + const formattedMessage = `${isFollowUp ? 'šŸ”„ **FOLLOW-UP**' : 'šŸ’¬ **NEW CONVERSATION**'} +**Session:** \`${sessionPrefix}\` **|** **Message #${messageNumber}** **|** ${messageType} - // Add referrer info - if (metadata?.referrer && metadata.referrer !== 'Direct') { - embed.fields.push({ name: "šŸ”— Referrer", value: metadata.referrer, inline: true }); - } +**Question:** +> ${message} + +**Context:** +šŸ“„ **Page:** ${page} +ā±ļø **Time on Page:** ${timeOnPage}${browserInfo ? `\n🌐 **Browser:** ${browserInfo}` : ''} + +---`; const response = await fetch(webhookUrl, { method: 'POST', @@ -88,9 +53,9 @@ export async function sendToDiscordWebhook(data: { 'Content-Type': 'application/json', }, body: JSON.stringify({ + content: formattedMessage, username: username || 'Stack Auth Docs User', avatar_url: 'https://cdn.discordapp.com/embed/avatars/0.png', - embeds: [embed], }), }); diff --git a/docs/src/app/api/chat/route.ts b/docs/src/app/api/chat/route.ts index 4fe351d90..230b6998e 100644 --- a/docs/src/app/api/chat/route.ts +++ b/docs/src/app/api/chat/route.ts @@ -22,7 +22,7 @@ export async function POST(request: Request) { const { messages, docsContent } = await request.json(); // Create a comprehensive system prompt that restricts AI to Stack Auth topics - const systemPrompt = `You are Stack Auth's AI assistant. You ONLY answer questions about Stack Auth - a complete authentication and user management solution for React applications. + const systemPrompt = `You are Stack Auth's AI assistant. You ONLY answer questions about Stack Auth - a complete authentication and user management solution.. DOCUMENTATION CONTEXT: ${docsContent || 'Documentation not available'} @@ -46,10 +46,10 @@ RESPONSE FORMAT: Remember: You are Stack Auth's dedicated assistant. Stay focused on Stack Auth topics only.`; try { - const result = streamText({ - model: google('gemini-1.5-flash'), + const result = streamText({ + model: google('gemini-2.0-flash'), system: systemPrompt, - messages, + messages, maxTokens: 1000, temperature: 0.3, tools: { diff --git a/docs/src/app/api/discord-webhook/route.ts b/docs/src/app/api/discord-webhook/route.ts index 5ce048241..c66e15ea2 100644 --- a/docs/src/app/api/discord-webhook/route.ts +++ b/docs/src/app/api/discord-webhook/route.ts @@ -18,3 +18,4 @@ export async function POST(request: NextRequest) { return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } } + \ No newline at end of file diff --git a/docs/src/components/chat/ai-chat.tsx b/docs/src/components/chat/ai-chat.tsx index 64a224923..c473509ca 100644 --- a/docs/src/components/chat/ai-chat.tsx +++ b/docs/src/components/chat/ai-chat.tsx @@ -35,35 +35,59 @@ export function AIChatDrawer() { const [isHomePage, setIsHomePage] = useState(false); const [isScrolled, setIsScrolled] = useState(false); const [pageLoadTime] = useState(Date.now()); + const [sessionId] = useState(() => { + // Generate or retrieve session ID + const existing = localStorage.getItem('ai-chat-session-id'); + if (existing) { + return existing; + } + const newId = `session_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`; + localStorage.setItem('ai-chat-session-id', newId); + return newId; + }); const [sessionData, setSessionData] = useState({ - messagesCount: 0, - starterPromptsUsed: 0, timeOnPage: 0, - scrollDepth: 0, + messageCount: 0, }); // Track session data useEffect(() => { const updateSessionData = () => { const timeOnPage = Math.floor((Date.now() - pageLoadTime) / 1000); - const scrollDepth = Math.floor((window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100); setSessionData(prev => ({ ...prev, timeOnPage, - scrollDepth: Math.max(prev.scrollDepth, scrollDepth || 0), })); }; const interval = setInterval(updateSessionData, 5000); // Update every 5 seconds - window.addEventListener('scroll', updateSessionData); return () => { clearInterval(interval); - window.removeEventListener('scroll', updateSessionData); }; }, [pageLoadTime]); + // Reset session ID if user has been inactive for too long + useEffect(() => { + const checkSessionExpiry = () => { + const lastActivity = localStorage.getItem('ai-chat-last-activity'); + if (lastActivity) { + const timeSinceActivity = Date.now() - parseInt(lastActivity); + const ONE_HOUR = 60 * 60 * 1000; + + if (timeSinceActivity > ONE_HOUR) { + // Generate new session ID + const newId = `session_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`; + localStorage.setItem('ai-chat-session-id', newId); + setSessionData(prev => ({ ...prev, messageCount: 0 })); + } + } + }; + + checkSessionExpiry(); + }, []); + // Detect if we're on homepage and scroll state useEffect(() => { const checkHomePage = () => { @@ -144,28 +168,23 @@ export function AIChatDrawer() { // Function to send message to Discord webhook const sendToDiscord = async (message: string) => { try { - // Gather additional context + // Update message count and last activity + const newMessageCount = sessionData.messageCount + 1; + localStorage.setItem('ai-chat-last-activity', Date.now().toString()); + + // Gather only essential context const context = { message: message, username: 'Stack Auth Docs User', metadata: { - url: window.location.href, + sessionId: sessionId, + messageNumber: newMessageCount, pathname: window.location.pathname, timestamp: new Date().toISOString(), userAgent: navigator.userAgent, - viewport: `${window.innerWidth}x${window.innerHeight}`, - isHomePage: isHomePage, - isScrolled: isScrolled, - messageLength: message.length, messageType: starterPrompts.some(p => p.prompt === message) ? 'starter-prompt' : 'custom', - sessionMessageCount: messages.length + 1, - // Enhanced session data timeOnPage: sessionData.timeOnPage, - scrollDepth: sessionData.scrollDepth, - referrer: document.referrer || 'Direct', - language: navigator.language, - timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, - chatExpanded: isChatExpanded, + isFollowUp: newMessageCount > 1, } }; @@ -186,11 +205,9 @@ export function AIChatDrawer() { if (!input.trim()) return; // Update session data - const isStarterPrompt = starterPrompts.some(p => p.prompt === input.trim()); setSessionData(prev => ({ ...prev, - messagesCount: prev.messagesCount + 1, - starterPromptsUsed: prev.starterPromptsUsed + (isStarterPrompt ? 1 : 0), + messageCount: prev.messageCount + 1, })); // Send message to Discord webhook