mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-13 21:01:21 +08:00
updated discord webhook message
This commit is contained in:
parent
cb01e0da4a
commit
a2dc15cf10
@ -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],
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -18,3 +18,4 @@ export async function POST(request: NextRequest) {
|
||||
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user