mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-27 21:01:03 +08:00
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- ELLIPSIS_HIDDEN -->
----
> [!IMPORTANT]
> This pull request updates the Stack Auth documentation structure,
enhances navigation and layout functionalities, and introduces new
components for improved user experience.
>
> - **Behavior**:
> - Introduces `PlatformRedirect` component in `platform-redirect.tsx`
for redirecting users to their preferred platform.
> - Adds `usePlatformPreference` hook in `use-platform-preference.ts`
for managing platform preferences.
> - Updates `getSmartRedirectUrl()` in `navigation-utils.ts` to use
`getSmartPlatformRedirect()`.
> - **Layout and Navigation**:
> - Enhances sidebar functionality with collapsible sections in
`docs.tsx` and `sidebar-context.tsx`.
> - Adds `DocsSidebarCollapseTrigger` in `docs.tsx` for sidebar
collapse/expand functionality.
> - Updates `SharedHeader` in `shared-header.tsx` to include
platform-aware navigation links.
> - **Documentation Structure**:
> - Updates `meta.json` files in `templates` to reflect new
documentation structure.
> - Renames `overview.mdx` to `index.mdx` in `sdk` and `components`
directories.
> - Adds detailed documentation for `Team`, `TeamUser`, and
`ContactChannel` in respective `.mdx` files.
>
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup>
for 21e55737cb. You can
[customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this
summary. It will automatically update as commits are pushed.</sup>
<!-- ELLIPSIS_HIDDEN -->
---------
Co-authored-by: Stack-Bot <madison@stack-auth.com>
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
112 lines
3.3 KiB
TypeScript
112 lines
3.3 KiB
TypeScript
/**
|
|
* Sends a message to Discord webhook with session tracking
|
|
*/
|
|
export async function sendToDiscordWebhook(data: {
|
|
message: string;
|
|
username?: string;
|
|
metadata?: {
|
|
sessionId?: string;
|
|
messageNumber?: number;
|
|
pathname?: string;
|
|
timestamp?: string;
|
|
userAgent?: string;
|
|
messageType?: string;
|
|
timeOnPage?: number;
|
|
isFollowUp?: boolean;
|
|
};
|
|
}) {
|
|
const webhookUrl = process.env.DISCORD_WEBHOOK_URL;
|
|
|
|
if (!webhookUrl) {
|
|
console.warn('Discord webhook URL not configured');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const { message, username, metadata } = data;
|
|
|
|
// 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 || '');
|
|
const page = metadata?.pathname || 'Unknown';
|
|
|
|
// Create formatted message
|
|
const formattedMessage = `${isFollowUp ? '🔄 **FOLLOW-UP**' : '💬 **NEW CONVERSATION**'}
|
|
**Session:** \`${sessionPrefix}\` **|** **Message #${messageNumber}** **|** ${messageType}
|
|
|
|
**Question:**
|
|
> ${message}
|
|
|
|
**Context:**
|
|
📄 **Page:** ${page}
|
|
⏱️ **Time on Page:** ${timeOnPage}${browserInfo ? `\n🌐 **Browser:** ${browserInfo}` : ''}
|
|
|
|
---`;
|
|
|
|
const response = await fetch(webhookUrl, {
|
|
method: 'POST',
|
|
headers: {
|
|
'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',
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.error('Failed to send message to Discord:', response.statusText);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error sending message to Discord:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format time in seconds to a human-readable format
|
|
*/
|
|
function formatTime(seconds: number): string {
|
|
if (seconds < 60) return `${seconds}s`;
|
|
const minutes = Math.floor(seconds / 60);
|
|
const remainingSeconds = seconds % 60;
|
|
return `${minutes}m ${remainingSeconds}s`;
|
|
}
|
|
|
|
/**
|
|
* Extract browser and OS info from user agent
|
|
*/
|
|
function extractBrowserInfo(userAgent: string): string | null {
|
|
if (!userAgent) return null;
|
|
|
|
// Browser detection patterns (order matters - Chrome must come before Safari)
|
|
const browserPatterns = [
|
|
{ pattern: 'Edge/', name: 'Edge' },
|
|
{ pattern: 'Chrome/', name: 'Chrome' },
|
|
{ pattern: 'Firefox/', name: 'Firefox' },
|
|
{ pattern: 'Safari/', name: 'Safari' },
|
|
];
|
|
|
|
// OS detection patterns
|
|
const osPatterns = [
|
|
{ pattern: 'Windows NT', name: 'Windows' },
|
|
{ pattern: 'Mac OS X', name: 'macOS' },
|
|
{ pattern: 'iPhone', name: 'iOS' },
|
|
{ pattern: 'iPad', name: 'iOS' },
|
|
{ pattern: 'Android', name: 'Android' },
|
|
{ pattern: 'Linux', name: 'Linux' },
|
|
];
|
|
|
|
// Find browser
|
|
const browser = browserPatterns.find(({ pattern }) => userAgent.includes(pattern))?.name || 'Unknown';
|
|
|
|
// Find OS
|
|
const os = osPatterns.find(({ pattern }) => userAgent.includes(pattern))?.name || 'Unknown';
|
|
|
|
return `${browser} on ${os}`;
|
|
}
|