Prettier format pending files
This commit is contained in:
parent
e9a7c48ca8
commit
17c9fc4cfa
10 changed files with 346 additions and 302 deletions
|
|
@ -3,7 +3,7 @@ import { createClient } from "@supabase/supabase-js";
|
||||||
|
|
||||||
const supabase = createClient(
|
const supabase = createClient(
|
||||||
process.env.SUPABASE_URL || "",
|
process.env.SUPABASE_URL || "",
|
||||||
process.env.SUPABASE_SERVICE_ROLE || ""
|
process.env.SUPABASE_SERVICE_ROLE || "",
|
||||||
);
|
);
|
||||||
|
|
||||||
interface ActivityAuthRequest {
|
interface ActivityAuthRequest {
|
||||||
|
|
@ -21,10 +21,7 @@ interface UserData {
|
||||||
primary_arm: string | null;
|
primary_arm: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function handler(
|
export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||||
req: VercelRequest,
|
|
||||||
res: VercelResponse
|
|
||||||
) {
|
|
||||||
if (req.method !== "POST") {
|
if (req.method !== "POST") {
|
||||||
res.setHeader("Allow", "POST");
|
res.setHeader("Allow", "POST");
|
||||||
return res.status(405).json({ error: "Method not allowed" });
|
return res.status(405).json({ error: "Method not allowed" });
|
||||||
|
|
@ -38,15 +35,20 @@ export default async function handler(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the access token with Discord API
|
// Verify the access token with Discord API
|
||||||
const discordResponse = await fetch("https://discord.com/api/v10/users/@me", {
|
const discordResponse = await fetch(
|
||||||
headers: {
|
"https://discord.com/api/v10/users/@me",
|
||||||
Authorization: `Bearer ${access_token}`,
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${access_token}`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
);
|
||||||
|
|
||||||
if (!discordResponse.ok) {
|
if (!discordResponse.ok) {
|
||||||
if (discordResponse.status === 401) {
|
if (discordResponse.status === 401) {
|
||||||
return res.status(401).json({ error: "Invalid or expired access token" });
|
return res
|
||||||
|
.status(401)
|
||||||
|
.json({ error: "Invalid or expired access token" });
|
||||||
}
|
}
|
||||||
throw new Error(`Discord API error: ${discordResponse.statusText}`);
|
throw new Error(`Discord API error: ${discordResponse.statusText}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,7 @@ const COMMANDS: CommandData[] = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default async function handler(
|
export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||||
req: VercelRequest,
|
|
||||||
res: VercelResponse
|
|
||||||
) {
|
|
||||||
// Verify this is a POST request
|
// Verify this is a POST request
|
||||||
if (req.method !== "POST") {
|
if (req.method !== "POST") {
|
||||||
res.setHeader("Allow", "POST");
|
res.setHeader("Allow", "POST");
|
||||||
|
|
@ -77,18 +74,16 @@ export default async function handler(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const rest = new REST({ version: "10" }).setToken(
|
const rest = new REST({ version: "10" }).setToken(
|
||||||
process.env.DISCORD_BOT_TOKEN!
|
process.env.DISCORD_BOT_TOKEN!,
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(
|
console.log(`📝 Registering ${COMMANDS.length} Discord slash commands...`);
|
||||||
`📝 Registering ${COMMANDS.length} Discord slash commands...`
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try bulk update first
|
// Try bulk update first
|
||||||
const data = await rest.put(
|
const data = await rest.put(
|
||||||
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID!),
|
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID!),
|
||||||
{ body: COMMANDS }
|
{ body: COMMANDS },
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`✅ Successfully registered ${data.length} slash commands`);
|
console.log(`✅ Successfully registered ${data.length} slash commands`);
|
||||||
|
|
@ -102,7 +97,7 @@ export default async function handler(
|
||||||
// Handle Error 50240 (Entry Point conflict)
|
// Handle Error 50240 (Entry Point conflict)
|
||||||
if (bulkError.code === 50240) {
|
if (bulkError.code === 50240) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"⚠️ Error 50240: Entry Point detected. Registering individually..."
|
"⚠️ Error 50240: Entry Point detected. Registering individually...",
|
||||||
);
|
);
|
||||||
|
|
||||||
const results = [];
|
const results = [];
|
||||||
|
|
@ -114,7 +109,7 @@ export default async function handler(
|
||||||
// Try to post individual command
|
// Try to post individual command
|
||||||
const posted = await rest.post(
|
const posted = await rest.post(
|
||||||
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID!),
|
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID!),
|
||||||
{ body: command }
|
{ body: command },
|
||||||
);
|
);
|
||||||
results.push({
|
results.push({
|
||||||
name: command.name,
|
name: command.name,
|
||||||
|
|
@ -141,7 +136,7 @@ export default async function handler(
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`✅ Registration complete: ${successCount} new, ${skipCount} already existed`
|
`✅ Registration complete: ${successCount} new, ${skipCount} already existed`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
|
|
|
||||||
488
client/App.tsx
488
client/App.tsx
|
|
@ -122,247 +122,265 @@ const App = () => (
|
||||||
<Web3Provider>
|
<Web3Provider>
|
||||||
<DiscordProvider>
|
<DiscordProvider>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
<Analytics />
|
<Analytics />
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<SkipAgentController />
|
<SkipAgentController />
|
||||||
<PageTransition>
|
<PageTransition>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Index />} />
|
<Route path="/" element={<Index />} />
|
||||||
<Route path="/onboarding" element={<Onboarding />} />
|
<Route path="/onboarding" element={<Onboarding />} />
|
||||||
<Route path="/dashboard" element={<Dashboard />} />
|
<Route path="/dashboard" element={<Dashboard />} />
|
||||||
<Route path="/realms" element={<Realms />} />
|
<Route path="/realms" element={<Realms />} />
|
||||||
<Route path="/investors" element={<Investors />} />
|
<Route path="/investors" element={<Investors />} />
|
||||||
<Route path="/roadmap" element={<Roadmap />} />
|
<Route path="/roadmap" element={<Roadmap />} />
|
||||||
<Route path="/trust" element={<Trust />} />
|
<Route path="/trust" element={<Trust />} />
|
||||||
<Route path="/press" element={<PressKit />} />
|
<Route path="/press" element={<PressKit />} />
|
||||||
<Route path="/projects" element={<Projects />} />
|
<Route path="/projects" element={<Projects />} />
|
||||||
<Route path="/projects/admin" element={<ProjectsAdmin />} />
|
<Route path="/projects/admin" element={<ProjectsAdmin />} />
|
||||||
<Route path="/directory" element={<Directory />} />
|
<Route path="/directory" element={<Directory />} />
|
||||||
<Route path="/admin" element={<Admin />} />
|
<Route path="/admin" element={<Admin />} />
|
||||||
<Route path="/admin/docs-sync" element={<DocsSync />} />
|
<Route path="/admin/docs-sync" element={<DocsSync />} />
|
||||||
<Route path="/feed" element={<Feed />} />
|
<Route path="/feed" element={<Feed />} />
|
||||||
<Route path="/teams" element={<Teams />} />
|
<Route path="/teams" element={<Teams />} />
|
||||||
<Route path="/squads" element={<Squads />} />
|
<Route path="/squads" element={<Squads />} />
|
||||||
<Route path="/mentee-hub" element={<MenteeHub />} />
|
<Route path="/mentee-hub" element={<MenteeHub />} />
|
||||||
<Route path="/projects/new" element={<ProjectsNew />} />
|
<Route path="/projects/new" element={<ProjectsNew />} />
|
||||||
<Route
|
|
||||||
path="/projects/:projectId/board"
|
|
||||||
element={<ProjectBoard />}
|
|
||||||
/>
|
|
||||||
<Route path="/profile" element={<Profile />} />
|
|
||||||
<Route path="/profile/me" element={<Profile />} />
|
|
||||||
<Route
|
|
||||||
path="/profile/applications"
|
|
||||||
element={<MyApplications />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route path="/developers" element={<DevelopersDirectory />} />
|
|
||||||
<Route
|
|
||||||
path="/developers/me"
|
|
||||||
element={<LegacyPassportRedirect />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/developers/:id"
|
|
||||||
element={<LegacyPassportRedirect />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/profiles"
|
|
||||||
element={<Navigate to="/developers" replace />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/profiles/me"
|
|
||||||
element={<LegacyPassportRedirect />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/profiles/:id"
|
|
||||||
element={<LegacyPassportRedirect />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route
|
|
||||||
path="/passport"
|
|
||||||
element={<Navigate to="/passport/me" replace />}
|
|
||||||
/>
|
|
||||||
<Route path="/passport/me" element={<ProfilePassport />} />
|
|
||||||
<Route
|
|
||||||
path="/passport/:username"
|
|
||||||
element={<ProfilePassport />}
|
|
||||||
/>
|
|
||||||
<Route path="/login" element={<Login />} />
|
|
||||||
<Route path="/signup" element={<SignupRedirect />} />
|
|
||||||
<Route path="/reset-password" element={<ResetPassword />} />
|
|
||||||
<Route path="/roblox-callback" element={<RobloxCallback />} />
|
|
||||||
<Route path="/web3-callback" element={<Web3Callback />} />
|
|
||||||
<Route path="/discord-verify" element={<DiscordVerify />} />
|
|
||||||
|
|
||||||
{/* Creator Network routes */}
|
|
||||||
<Route path="/creators" element={<CreatorDirectory />} />
|
|
||||||
<Route
|
|
||||||
path="/creators/:username"
|
|
||||||
element={<CreatorProfile />}
|
|
||||||
/>
|
|
||||||
<Route path="/opportunities" element={<OpportunitiesHub />} />
|
|
||||||
<Route
|
|
||||||
path="/opportunities/:id"
|
|
||||||
element={<OpportunityDetail />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Service routes */}
|
|
||||||
<Route
|
|
||||||
path="/game-development"
|
|
||||||
element={<GameDevelopment />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/consulting"
|
|
||||||
element={<DevelopmentConsulting />}
|
|
||||||
/>
|
|
||||||
<Route path="/mentorship" element={<MentorshipPrograms />} />
|
|
||||||
<Route path="/engage" element={<Engage />} />
|
|
||||||
<Route
|
|
||||||
path="/pricing"
|
|
||||||
element={<Navigate to="/engage" replace />}
|
|
||||||
/>
|
|
||||||
<Route path="/research" element={<ResearchLabs />} />
|
|
||||||
|
|
||||||
{/* New Arm Landing Pages */}
|
|
||||||
<Route path="/labs" element={<Labs />} />
|
|
||||||
<Route
|
|
||||||
path="/labs/explore-research"
|
|
||||||
element={<LabsExploreResearch />}
|
|
||||||
/>
|
|
||||||
<Route path="/labs/join-team" element={<LabsJoinTeam />} />
|
|
||||||
<Route
|
|
||||||
path="/labs/get-involved"
|
|
||||||
element={<LabsGetInvolved />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route path="/gameforge" element={<GameForge />} />
|
|
||||||
<Route
|
|
||||||
path="/gameforge/start-building"
|
|
||||||
element={<GameForgeStartBuilding />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/gameforge/view-portfolio"
|
|
||||||
element={<GameForgeViewPortfolio />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/gameforge/join-gameforge"
|
|
||||||
element={<GameForgeJoinGameForge />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route path="/corp" element={<Corp />} />
|
|
||||||
<Route
|
|
||||||
path="/corp/schedule-consultation"
|
|
||||||
element={<CorpScheduleConsultation />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/corp/view-case-studies"
|
|
||||||
element={<CorpViewCaseStudies />}
|
|
||||||
/>
|
|
||||||
<Route path="/corp/contact-us" element={<CorpContactUs />} />
|
|
||||||
|
|
||||||
<Route path="/foundation" element={<Foundation />} />
|
|
||||||
<Route
|
|
||||||
path="/foundation/contribute"
|
|
||||||
element={<FoundationContribute />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/foundation/learn-more"
|
|
||||||
element={<FoundationLearnMore />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/foundation/get-involved"
|
|
||||||
element={<FoundationGetInvolved />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Dev-Link routes */}
|
|
||||||
<Route path="/dev-link" element={<DevLink />} />
|
|
||||||
<Route
|
|
||||||
path="/dev-link/waitlist"
|
|
||||||
element={<DevLinkProfiles />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Nexus routes */}
|
|
||||||
<Route path="/nexus" element={<Nexus />} />
|
|
||||||
|
|
||||||
{/* Resource routes */}
|
|
||||||
<Route path="/docs" element={<DocsLayout />}>
|
|
||||||
<Route index element={<DocsOverview />} />
|
|
||||||
<Route path="tutorials" element={<DocsTutorials />} />
|
|
||||||
<Route path="curriculum" element={<DocsCurriculum />} />
|
|
||||||
<Route
|
<Route
|
||||||
path="getting-started"
|
path="/projects/:projectId/board"
|
||||||
element={<DocsGettingStarted />}
|
element={<ProjectBoard />}
|
||||||
|
/>
|
||||||
|
<Route path="/profile" element={<Profile />} />
|
||||||
|
<Route path="/profile/me" element={<Profile />} />
|
||||||
|
<Route
|
||||||
|
path="/profile/applications"
|
||||||
|
element={<MyApplications />}
|
||||||
/>
|
/>
|
||||||
<Route path="platform" element={<DocsPlatform />} />
|
|
||||||
<Route path="api" element={<DocsApiReference />} />
|
|
||||||
<Route path="cli" element={<DocsCli />} />
|
|
||||||
<Route path="examples" element={<DocsExamples />} />
|
|
||||||
<Route path="integrations" element={<DocsIntegrations />} />
|
|
||||||
</Route>
|
|
||||||
<Route path="/tutorials" element={<Tutorials />} />
|
|
||||||
<Route path="/blog" element={<Blog />} />
|
|
||||||
<Route path="/blog/:slug" element={<BlogPost />} />
|
|
||||||
<Route path="/community" element={<Community />} />
|
|
||||||
<Route
|
|
||||||
path="/community/teams"
|
|
||||||
element={<FoundationTeams />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/community/about"
|
|
||||||
element={<FoundationAbout />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/community/mentorship"
|
|
||||||
element={<MentorshipRequest />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/community/mentorship/apply"
|
|
||||||
element={<MentorApply />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/community/mentor/:username"
|
|
||||||
element={<MentorProfile />}
|
|
||||||
/>
|
|
||||||
<Route path="/community/:tabId" element={<Community />} />
|
|
||||||
<Route path="/staff" element={<Staff />} />
|
|
||||||
<Route path="/support" element={<Support />} />
|
|
||||||
<Route path="/status" element={<Status />} />
|
|
||||||
<Route path="/changelog" element={<Changelog />} />
|
|
||||||
|
|
||||||
{/* Informational routes */}
|
<Route
|
||||||
<Route path="/wix" element={<Wix />} />
|
path="/developers"
|
||||||
<Route
|
element={<DevelopersDirectory />}
|
||||||
path="/wix/case-studies"
|
/>
|
||||||
element={<WixCaseStudies />}
|
<Route
|
||||||
/>
|
path="/developers/me"
|
||||||
<Route path="/wix/faq" element={<WixFaq />} />
|
element={<LegacyPassportRedirect />}
|
||||||
<Route path="/about" element={<About />} />
|
/>
|
||||||
<Route path="/contact" element={<Contact />} />
|
<Route
|
||||||
<Route path="/get-started" element={<GetStarted />} />
|
path="/developers/:id"
|
||||||
<Route path="/explore" element={<Explore />} />
|
element={<LegacyPassportRedirect />}
|
||||||
<Route path="/services" element={<Services />} />
|
/>
|
||||||
<Route path="/careers" element={<Careers />} />
|
<Route
|
||||||
|
path="/profiles"
|
||||||
|
element={<Navigate to="/developers" replace />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/profiles/me"
|
||||||
|
element={<LegacyPassportRedirect />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/profiles/:id"
|
||||||
|
element={<LegacyPassportRedirect />}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Legal routes */}
|
<Route
|
||||||
<Route path="/privacy" element={<Privacy />} />
|
path="/passport"
|
||||||
<Route path="/terms" element={<Terms />} />
|
element={<Navigate to="/passport/me" replace />}
|
||||||
|
/>
|
||||||
|
<Route path="/passport/me" element={<ProfilePassport />} />
|
||||||
|
<Route
|
||||||
|
path="/passport/:username"
|
||||||
|
element={<ProfilePassport />}
|
||||||
|
/>
|
||||||
|
<Route path="/login" element={<Login />} />
|
||||||
|
<Route path="/signup" element={<SignupRedirect />} />
|
||||||
|
<Route path="/reset-password" element={<ResetPassword />} />
|
||||||
|
<Route
|
||||||
|
path="/roblox-callback"
|
||||||
|
element={<RobloxCallback />}
|
||||||
|
/>
|
||||||
|
<Route path="/web3-callback" element={<Web3Callback />} />
|
||||||
|
<Route path="/discord-verify" element={<DiscordVerify />} />
|
||||||
|
|
||||||
{/* Discord routes */}
|
{/* Creator Network routes */}
|
||||||
<Route path="/activity" element={<Activity />} />
|
<Route path="/creators" element={<CreatorDirectory />} />
|
||||||
<Route path="/discord" element={<DiscordActivity />} />
|
<Route
|
||||||
<Route
|
path="/creators/:username"
|
||||||
path="/discord/callback"
|
element={<CreatorProfile />}
|
||||||
element={<DiscordOAuthCallback />}
|
/>
|
||||||
/>
|
<Route
|
||||||
|
path="/opportunities"
|
||||||
|
element={<OpportunitiesHub />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/opportunities/:id"
|
||||||
|
element={<OpportunityDetail />}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Explicit 404 route for static hosting fallbacks */}
|
{/* Service routes */}
|
||||||
<Route path="/404" element={<FourOhFourPage />} />
|
<Route
|
||||||
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
path="/game-development"
|
||||||
<Route path="*" element={<FourOhFourPage />} />
|
element={<GameDevelopment />}
|
||||||
</Routes>
|
/>
|
||||||
</PageTransition>
|
<Route
|
||||||
</BrowserRouter>
|
path="/consulting"
|
||||||
|
element={<DevelopmentConsulting />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/mentorship"
|
||||||
|
element={<MentorshipPrograms />}
|
||||||
|
/>
|
||||||
|
<Route path="/engage" element={<Engage />} />
|
||||||
|
<Route
|
||||||
|
path="/pricing"
|
||||||
|
element={<Navigate to="/engage" replace />}
|
||||||
|
/>
|
||||||
|
<Route path="/research" element={<ResearchLabs />} />
|
||||||
|
|
||||||
|
{/* New Arm Landing Pages */}
|
||||||
|
<Route path="/labs" element={<Labs />} />
|
||||||
|
<Route
|
||||||
|
path="/labs/explore-research"
|
||||||
|
element={<LabsExploreResearch />}
|
||||||
|
/>
|
||||||
|
<Route path="/labs/join-team" element={<LabsJoinTeam />} />
|
||||||
|
<Route
|
||||||
|
path="/labs/get-involved"
|
||||||
|
element={<LabsGetInvolved />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Route path="/gameforge" element={<GameForge />} />
|
||||||
|
<Route
|
||||||
|
path="/gameforge/start-building"
|
||||||
|
element={<GameForgeStartBuilding />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/gameforge/view-portfolio"
|
||||||
|
element={<GameForgeViewPortfolio />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/gameforge/join-gameforge"
|
||||||
|
element={<GameForgeJoinGameForge />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Route path="/corp" element={<Corp />} />
|
||||||
|
<Route
|
||||||
|
path="/corp/schedule-consultation"
|
||||||
|
element={<CorpScheduleConsultation />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/corp/view-case-studies"
|
||||||
|
element={<CorpViewCaseStudies />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/corp/contact-us"
|
||||||
|
element={<CorpContactUs />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Route path="/foundation" element={<Foundation />} />
|
||||||
|
<Route
|
||||||
|
path="/foundation/contribute"
|
||||||
|
element={<FoundationContribute />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/foundation/learn-more"
|
||||||
|
element={<FoundationLearnMore />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/foundation/get-involved"
|
||||||
|
element={<FoundationGetInvolved />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Dev-Link routes */}
|
||||||
|
<Route path="/dev-link" element={<DevLink />} />
|
||||||
|
<Route
|
||||||
|
path="/dev-link/waitlist"
|
||||||
|
element={<DevLinkProfiles />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Nexus routes */}
|
||||||
|
<Route path="/nexus" element={<Nexus />} />
|
||||||
|
|
||||||
|
{/* Resource routes */}
|
||||||
|
<Route path="/docs" element={<DocsLayout />}>
|
||||||
|
<Route index element={<DocsOverview />} />
|
||||||
|
<Route path="tutorials" element={<DocsTutorials />} />
|
||||||
|
<Route path="curriculum" element={<DocsCurriculum />} />
|
||||||
|
<Route
|
||||||
|
path="getting-started"
|
||||||
|
element={<DocsGettingStarted />}
|
||||||
|
/>
|
||||||
|
<Route path="platform" element={<DocsPlatform />} />
|
||||||
|
<Route path="api" element={<DocsApiReference />} />
|
||||||
|
<Route path="cli" element={<DocsCli />} />
|
||||||
|
<Route path="examples" element={<DocsExamples />} />
|
||||||
|
<Route
|
||||||
|
path="integrations"
|
||||||
|
element={<DocsIntegrations />}
|
||||||
|
/>
|
||||||
|
</Route>
|
||||||
|
<Route path="/tutorials" element={<Tutorials />} />
|
||||||
|
<Route path="/blog" element={<Blog />} />
|
||||||
|
<Route path="/blog/:slug" element={<BlogPost />} />
|
||||||
|
<Route path="/community" element={<Community />} />
|
||||||
|
<Route
|
||||||
|
path="/community/teams"
|
||||||
|
element={<FoundationTeams />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/community/about"
|
||||||
|
element={<FoundationAbout />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/community/mentorship"
|
||||||
|
element={<MentorshipRequest />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/community/mentorship/apply"
|
||||||
|
element={<MentorApply />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/community/mentor/:username"
|
||||||
|
element={<MentorProfile />}
|
||||||
|
/>
|
||||||
|
<Route path="/community/:tabId" element={<Community />} />
|
||||||
|
<Route path="/staff" element={<Staff />} />
|
||||||
|
<Route path="/support" element={<Support />} />
|
||||||
|
<Route path="/status" element={<Status />} />
|
||||||
|
<Route path="/changelog" element={<Changelog />} />
|
||||||
|
|
||||||
|
{/* Informational routes */}
|
||||||
|
<Route path="/wix" element={<Wix />} />
|
||||||
|
<Route
|
||||||
|
path="/wix/case-studies"
|
||||||
|
element={<WixCaseStudies />}
|
||||||
|
/>
|
||||||
|
<Route path="/wix/faq" element={<WixFaq />} />
|
||||||
|
<Route path="/about" element={<About />} />
|
||||||
|
<Route path="/contact" element={<Contact />} />
|
||||||
|
<Route path="/get-started" element={<GetStarted />} />
|
||||||
|
<Route path="/explore" element={<Explore />} />
|
||||||
|
<Route path="/services" element={<Services />} />
|
||||||
|
<Route path="/careers" element={<Careers />} />
|
||||||
|
|
||||||
|
{/* Legal routes */}
|
||||||
|
<Route path="/privacy" element={<Privacy />} />
|
||||||
|
<Route path="/terms" element={<Terms />} />
|
||||||
|
|
||||||
|
{/* Discord routes */}
|
||||||
|
<Route path="/activity" element={<Activity />} />
|
||||||
|
<Route path="/discord" element={<DiscordActivity />} />
|
||||||
|
<Route
|
||||||
|
path="/discord/callback"
|
||||||
|
element={<DiscordOAuthCallback />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Explicit 404 route for static hosting fallbacks */}
|
||||||
|
<Route path="/404" element={<FourOhFourPage />} />
|
||||||
|
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
||||||
|
<Route path="*" element={<FourOhFourPage />} />
|
||||||
|
</Routes>
|
||||||
|
</PageTransition>
|
||||||
|
</BrowserRouter>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</DiscordProvider>
|
</DiscordProvider>
|
||||||
</Web3Provider>
|
</Web3Provider>
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ export function AdminDiscordManagement() {
|
||||||
setRegisterSuccess(null);
|
setRegisterSuccess(null);
|
||||||
|
|
||||||
const adminToken = prompt(
|
const adminToken = prompt(
|
||||||
"Enter admin registration token (from environment variables):"
|
"Enter admin registration token (from environment variables):",
|
||||||
);
|
);
|
||||||
if (!adminToken) {
|
if (!adminToken) {
|
||||||
setRegisterError("Registration cancelled");
|
setRegisterError("Registration cancelled");
|
||||||
|
|
@ -149,7 +149,7 @@ export function AdminDiscordManagement() {
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
setRegisterSuccess(
|
setRegisterSuccess(
|
||||||
data.message || "Discord commands registered successfully!"
|
data.message || "Discord commands registered successfully!",
|
||||||
);
|
);
|
||||||
setTimeout(() => setRegisterSuccess(null), 5000);
|
setTimeout(() => setRegisterSuccess(null), 5000);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ export const useDiscordActivity = () => {
|
||||||
const context = useContext(DiscordActivityContext);
|
const context = useContext(DiscordActivityContext);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"useDiscordActivity must be used within DiscordActivityProvider"
|
"useDiscordActivity must be used within DiscordActivityProvider",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
|
|
@ -41,9 +41,9 @@ interface DiscordActivityProviderProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DiscordActivityProvider: React.FC<DiscordActivityProviderProps> = ({
|
export const DiscordActivityProvider: React.FC<
|
||||||
children,
|
DiscordActivityProviderProps
|
||||||
}) => {
|
> = ({ children }) => {
|
||||||
const [isActivity, setIsActivity] = useState(false);
|
const [isActivity, setIsActivity] = useState(false);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [user, setUser] = useState<DiscordUser | null>(null);
|
const [user, setUser] = useState<DiscordUser | null>(null);
|
||||||
|
|
@ -64,11 +64,10 @@ export const DiscordActivityProvider: React.FC<DiscordActivityProviderProps> = (
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
// Import the Discord SDK dynamically
|
// Import the Discord SDK dynamically
|
||||||
const { DiscordSDK } = await import(
|
const { DiscordSDK } = await import("@discord/embedded-app-sdk");
|
||||||
"@discord/embedded-app-sdk"
|
|
||||||
);
|
|
||||||
|
|
||||||
const clientId = import.meta.env.VITE_DISCORD_CLIENT_ID || "578971245454950421";
|
const clientId =
|
||||||
|
import.meta.env.VITE_DISCORD_CLIENT_ID || "578971245454950421";
|
||||||
|
|
||||||
const sdk = new DiscordSDK({
|
const sdk = new DiscordSDK({
|
||||||
clientId,
|
clientId,
|
||||||
|
|
@ -119,7 +118,7 @@ export const DiscordActivityProvider: React.FC<DiscordActivityProviderProps> = (
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
access_token: currentUser.access_token || ""
|
access_token: currentUser.access_token || "",
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,9 @@ export default function Activity() {
|
||||||
<code className="bg-blue-800 px-2 py-1 rounded">/profile</code>,{" "}
|
<code className="bg-blue-800 px-2 py-1 rounded">/profile</code>,{" "}
|
||||||
<code className="bg-blue-800 px-2 py-1 rounded">/set-realm</code>,
|
<code className="bg-blue-800 px-2 py-1 rounded">/set-realm</code>,
|
||||||
and{" "}
|
and{" "}
|
||||||
<code className="bg-blue-800 px-2 py-1 rounded">/verify-role</code>{" "}
|
<code className="bg-blue-800 px-2 py-1 rounded">
|
||||||
|
/verify-role
|
||||||
|
</code>{" "}
|
||||||
to manage your account within Discord.
|
to manage your account within Discord.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -114,9 +114,7 @@ client.login(process.env.DISCORD_BOT_TOKEN);
|
||||||
client.once("ready", () => {
|
client.once("ready", () => {
|
||||||
console.log(`✅ Bot logged in as ${client.user.tag}`);
|
console.log(`✅ Bot logged in as ${client.user.tag}`);
|
||||||
console.log(`📡 Listening in ${client.guilds.cache.size} server(s)`);
|
console.log(`📡 Listening in ${client.guilds.cache.size} server(s)`);
|
||||||
console.log(
|
console.log("ℹ️ Commands are registered via: npm run register-commands");
|
||||||
"ℹ️ Commands are registered via: npm run register-commands"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set bot status
|
// Set bot status
|
||||||
client.user.setActivity("/verify to link your AeThex account", {
|
client.user.setActivity("/verify to link your AeThex account", {
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,13 @@ const path = require("path");
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
|
|
||||||
// Validate environment variables
|
// Validate environment variables
|
||||||
const requiredEnvVars = [
|
const requiredEnvVars = ["DISCORD_BOT_TOKEN", "DISCORD_CLIENT_ID"];
|
||||||
"DISCORD_BOT_TOKEN",
|
|
||||||
"DISCORD_CLIENT_ID",
|
|
||||||
];
|
|
||||||
|
|
||||||
const missingVars = requiredEnvVars.filter((envVar) => !process.env[envVar]);
|
const missingVars = requiredEnvVars.filter((envVar) => !process.env[envVar]);
|
||||||
if (missingVars.length > 0) {
|
if (missingVars.length > 0) {
|
||||||
console.error(
|
console.error(
|
||||||
"❌ FATAL ERROR: Missing required environment variables:",
|
"❌ FATAL ERROR: Missing required environment variables:",
|
||||||
missingVars.join(", ")
|
missingVars.join(", "),
|
||||||
);
|
);
|
||||||
console.error("\nPlease set these before running command registration:");
|
console.error("\nPlease set these before running command registration:");
|
||||||
missingVars.forEach((envVar) => {
|
missingVars.forEach((envVar) => {
|
||||||
|
|
@ -43,55 +40,68 @@ for (const file of commandFiles) {
|
||||||
async function registerCommands() {
|
async function registerCommands() {
|
||||||
try {
|
try {
|
||||||
const rest = new REST({ version: "10" }).setToken(
|
const rest = new REST({ version: "10" }).setToken(
|
||||||
process.env.DISCORD_BOT_TOKEN
|
process.env.DISCORD_BOT_TOKEN,
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`\n📝 Registering ${commands.length} slash commands...`);
|
console.log(`\n📝 Registering ${commands.length} slash commands...`);
|
||||||
console.log("⚠️ This will co-exist with Discord's auto-generated Entry Point command.\n");
|
console.log(
|
||||||
|
"⚠️ This will co-exist with Discord's auto-generated Entry Point command.\n",
|
||||||
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await rest.put(
|
const data = await rest.put(
|
||||||
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID),
|
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID),
|
||||||
{ body: commands }
|
{ body: commands },
|
||||||
);
|
);
|
||||||
console.log(`✅ Successfully registered ${data.length} slash commands.`);
|
console.log(`✅ Successfully registered ${data.length} slash commands.`);
|
||||||
console.log("\n🎉 Command registration complete!");
|
console.log("\n🎉 Command registration complete!");
|
||||||
console.log("ℹ️ Your commands are now live in Discord.");
|
console.log("ℹ️ Your commands are now live in Discord.");
|
||||||
console.log("ℹ️ The Entry Point command (for Activities) will be managed by Discord.\n");
|
console.log(
|
||||||
|
"ℹ️ The Entry Point command (for Activities) will be managed by Discord.\n",
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Handle Entry Point command conflict
|
// Handle Entry Point command conflict
|
||||||
if (error.code === 50240) {
|
if (error.code === 50240) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"⚠️ Error 50240: Entry Point command detected (Discord Activity enabled)."
|
"⚠️ Error 50240: Entry Point command detected (Discord Activity enabled).",
|
||||||
);
|
);
|
||||||
console.warn("Registering commands individually...\n");
|
console.warn("Registering commands individually...\n");
|
||||||
|
|
||||||
let successCount = 0;
|
let successCount = 0;
|
||||||
for (const command of commands) {
|
for (const command of commands) {
|
||||||
try {
|
try {
|
||||||
await rest.post(
|
await rest.post(
|
||||||
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID),
|
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID),
|
||||||
{ body: command }
|
{ body: command },
|
||||||
);
|
);
|
||||||
successCount++;
|
successCount++;
|
||||||
} catch (postError) {
|
} catch (postError) {
|
||||||
if (postError.code === 50045) {
|
if (postError.code === 50045) {
|
||||||
console.warn(` ⚠️ ${command.name}: Already registered (skipping)`);
|
console.warn(
|
||||||
|
` ⚠️ ${command.name}: Already registered (skipping)`,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
console.error(` ❌ ${command.name}: ${postError.message}`);
|
console.error(` ❌ ${command.name}: ${postError.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`\n✅ Registered ${successCount} slash commands (individual mode).`);
|
console.log(
|
||||||
|
`\n✅ Registered ${successCount} slash commands (individual mode).`,
|
||||||
|
);
|
||||||
console.log("🎉 Command registration complete!");
|
console.log("🎉 Command registration complete!");
|
||||||
console.log("ℹ️ The Entry Point command will be managed by Discord.\n");
|
console.log(
|
||||||
|
"ℹ️ The Entry Point command will be managed by Discord.\n",
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Fatal error registering commands:", error.message || error);
|
console.error(
|
||||||
|
"❌ Fatal error registering commands:",
|
||||||
|
error.message || error,
|
||||||
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,13 @@ If you can't run `npm` in your development environment, follow this guide to dep
|
||||||
Add these to your deployment platform (Vercel, PebbleHost):
|
Add these to your deployment platform (Vercel, PebbleHost):
|
||||||
|
|
||||||
### Vercel (Frontend)
|
### Vercel (Frontend)
|
||||||
|
|
||||||
```
|
```
|
||||||
VITE_DISCORD_CLIENT_ID=578971245454950421
|
VITE_DISCORD_CLIENT_ID=578971245454950421
|
||||||
```
|
```
|
||||||
|
|
||||||
### PebbleHost (Discord Bot)
|
### PebbleHost (Discord Bot)
|
||||||
|
|
||||||
```
|
```
|
||||||
DISCORD_BOT_TOKEN=<your-token>
|
DISCORD_BOT_TOKEN=<your-token>
|
||||||
DISCORD_CLIENT_ID=578971245454950421
|
DISCORD_CLIENT_ID=578971245454950421
|
||||||
|
|
@ -26,6 +28,7 @@ BOT_PORT=3000
|
||||||
```
|
```
|
||||||
|
|
||||||
### Vercel (Backend - for command registration)
|
### Vercel (Backend - for command registration)
|
||||||
|
|
||||||
```
|
```
|
||||||
DISCORD_BOT_TOKEN=<your-token>
|
DISCORD_BOT_TOKEN=<your-token>
|
||||||
DISCORD_CLIENT_ID=578971245454950421
|
DISCORD_CLIENT_ID=578971245454950421
|
||||||
|
|
@ -68,15 +71,15 @@ You can add a button to `/admin` panel that triggers this endpoint:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
async function registerCommands() {
|
async function registerCommands() {
|
||||||
const response = await fetch('/api/discord/admin-register-commands', {
|
const response = await fetch("/api/discord/admin-register-commands", {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${process.env.DISCORD_ADMIN_REGISTER_TOKEN}`,
|
Authorization: `Bearer ${process.env.DISCORD_ADMIN_REGISTER_TOKEN}`,
|
||||||
'Content-Type': 'application/json',
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
console.log('Registration result:', data);
|
console.log("Registration result:", data);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -131,10 +134,12 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
||||||
### Error 50240: "Cannot remove Entry Point command"
|
### Error 50240: "Cannot remove Entry Point command"
|
||||||
|
|
||||||
**This happens if:**
|
**This happens if:**
|
||||||
|
|
||||||
- You enable Activities, then the bot tries to register commands via bulk update
|
- You enable Activities, then the bot tries to register commands via bulk update
|
||||||
- The bot is trying to overwrite the auto-generated Entry Point command
|
- The bot is trying to overwrite the auto-generated Entry Point command
|
||||||
|
|
||||||
**Solution:**
|
**Solution:**
|
||||||
|
|
||||||
- ✅ Your bot code has been fixed (bot no longer registers on startup)
|
- ✅ Your bot code has been fixed (bot no longer registers on startup)
|
||||||
- Just call the `/api/discord/admin-register-commands` endpoint (Step 3)
|
- Just call the `/api/discord/admin-register-commands` endpoint (Step 3)
|
||||||
- The endpoint handles Error 50240 gracefully
|
- The endpoint handles Error 50240 gracefully
|
||||||
|
|
@ -142,6 +147,7 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
||||||
### Activity not loading in Discord
|
### Activity not loading in Discord
|
||||||
|
|
||||||
**Check:**
|
**Check:**
|
||||||
|
|
||||||
1. Activities enabled in Discord Developer Portal ✅
|
1. Activities enabled in Discord Developer Portal ✅
|
||||||
2. Activity URL is set to `https://aethex.dev/activity` (not an IP) ✅
|
2. Activity URL is set to `https://aethex.dev/activity` (not an IP) ✅
|
||||||
3. Frontend is deployed to Vercel ✅
|
3. Frontend is deployed to Vercel ✅
|
||||||
|
|
@ -151,6 +157,7 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
||||||
### "Unauthorized" error when calling register endpoint
|
### "Unauthorized" error when calling register endpoint
|
||||||
|
|
||||||
**Check:**
|
**Check:**
|
||||||
|
|
||||||
1. `DISCORD_ADMIN_REGISTER_TOKEN` is set in Vercel environment variables
|
1. `DISCORD_ADMIN_REGISTER_TOKEN` is set in Vercel environment variables
|
||||||
2. You're passing the correct token in the `Authorization: Bearer` header
|
2. You're passing the correct token in the `Authorization: Bearer` header
|
||||||
3. The token matches exactly (no extra spaces)
|
3. The token matches exactly (no extra spaces)
|
||||||
|
|
@ -158,6 +165,7 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
||||||
### Bot not responding to commands
|
### Bot not responding to commands
|
||||||
|
|
||||||
**Check:**
|
**Check:**
|
||||||
|
|
||||||
1. Bot is online on PebbleHost (check logs)
|
1. Bot is online on PebbleHost (check logs)
|
||||||
2. Commands are registered (call `/api/discord/admin-register-commands` and check response)
|
2. Commands are registered (call `/api/discord/admin-register-commands` and check response)
|
||||||
3. Response shows commands registered successfully
|
3. Response shows commands registered successfully
|
||||||
|
|
@ -167,13 +175,13 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
||||||
|
|
||||||
## Quick Reference
|
## Quick Reference
|
||||||
|
|
||||||
| What | How |
|
| What | How |
|
||||||
|------|-----|
|
| ----------------- | -------------------------------------------------------------- |
|
||||||
| Enable Activities | Discord Developer Portal → Settings → Activities → Enable |
|
| Enable Activities | Discord Developer Portal → Settings → Activities → Enable |
|
||||||
| Register Commands | POST to `/api/discord/admin-register-commands` with auth token |
|
| Register Commands | POST to `/api/discord/admin-register-commands` with auth token |
|
||||||
| Deploy Bot | Push to PebbleHost, bot starts with `npm start` |
|
| Deploy Bot | Push to PebbleHost, bot starts with `npm start` |
|
||||||
| Deploy Frontend | Push to GitHub, Vercel auto-deploys |
|
| Deploy Frontend | Push to GitHub, Vercel auto-deploys |
|
||||||
| Test Activity | Open Discord, click Activity button, should load |
|
| Test Activity | Open Discord, click Activity button, should load |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -209,6 +217,6 @@ Plus the auto-generated **Entry Point** command (managed by Discord for Activiti
|
||||||
✅ Everything can be deployed via web interfaces
|
✅ Everything can be deployed via web interfaces
|
||||||
✅ Commands registered via API endpoint
|
✅ Commands registered via API endpoint
|
||||||
✅ Error 50240 handled automatically
|
✅ Error 50240 handled automatically
|
||||||
✅ Activity loads instantly in Discord
|
✅ Activity loads instantly in Discord
|
||||||
|
|
||||||
**You're all set!** 🚀
|
**You're all set!** 🚀
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,12 @@ Click this button.
|
||||||
A popup will appear asking for your **admin registration token**.
|
A popup will appear asking for your **admin registration token**.
|
||||||
|
|
||||||
This token is:
|
This token is:
|
||||||
|
|
||||||
- Set in your Vercel environment variables as `DISCORD_ADMIN_REGISTER_TOKEN`
|
- Set in your Vercel environment variables as `DISCORD_ADMIN_REGISTER_TOKEN`
|
||||||
- A random secure string (e.g., `sk-admin-aethex-discord-2024`)
|
- A random secure string (e.g., `sk-admin-aethex-discord-2024`)
|
||||||
|
|
||||||
**Example popup:**
|
**Example popup:**
|
||||||
|
|
||||||
```
|
```
|
||||||
Enter admin registration token (from environment variables):
|
Enter admin registration token (from environment variables):
|
||||||
[_________________________] [OK] [Cancel]
|
[_________________________] [OK] [Cancel]
|
||||||
|
|
@ -40,16 +42,19 @@ The button will show **"Registering..."** with a spinning loader.
|
||||||
Once complete, you'll see one of:
|
Once complete, you'll see one of:
|
||||||
|
|
||||||
**✅ Success:**
|
**✅ Success:**
|
||||||
|
|
||||||
```
|
```
|
||||||
✅ Registered 5 new commands (Entry Point already exists)
|
✅ Registered 5 new commands (Entry Point already exists)
|
||||||
```
|
```
|
||||||
|
|
||||||
**⚠️ Partial Success (Error 50240):**
|
**⚠️ Partial Success (Error 50240):**
|
||||||
|
|
||||||
```
|
```
|
||||||
✅ Registered 5 new commands (Entry Point managed by Discord)
|
✅ Registered 5 new commands (Entry Point managed by Discord)
|
||||||
```
|
```
|
||||||
|
|
||||||
**❌ Error:**
|
**❌ Error:**
|
||||||
|
|
||||||
```
|
```
|
||||||
❌ Invalid or expired access token
|
❌ Invalid or expired access token
|
||||||
```
|
```
|
||||||
|
|
@ -77,6 +82,7 @@ Plus Discord's auto-generated **"Entry Point"** command (for Discord Activities)
|
||||||
**Issue:** Getting this error when registering.
|
**Issue:** Getting this error when registering.
|
||||||
|
|
||||||
**Solution:**
|
**Solution:**
|
||||||
|
|
||||||
1. Check your `DISCORD_ADMIN_REGISTER_TOKEN` environment variable in Vercel
|
1. Check your `DISCORD_ADMIN_REGISTER_TOKEN` environment variable in Vercel
|
||||||
2. Make sure you entered the token exactly as it's set (case-sensitive)
|
2. Make sure you entered the token exactly as it's set (case-sensitive)
|
||||||
3. Verify token doesn't have extra spaces
|
3. Verify token doesn't have extra spaces
|
||||||
|
|
@ -86,6 +92,7 @@ Plus Discord's auto-generated **"Entry Point"** command (for Discord Activities)
|
||||||
**Issue:** Generic error when clicking the button.
|
**Issue:** Generic error when clicking the button.
|
||||||
|
|
||||||
**Check:**
|
**Check:**
|
||||||
|
|
||||||
1. Is your bot deployed on PebbleHost?
|
1. Is your bot deployed on PebbleHost?
|
||||||
2. Are your `DISCORD_BOT_TOKEN` and `DISCORD_CLIENT_ID` env vars set on Vercel (backend)?
|
2. Are your `DISCORD_BOT_TOKEN` and `DISCORD_CLIENT_ID` env vars set on Vercel (backend)?
|
||||||
3. Open browser console (F12) → Network tab → Check the POST request to `/api/discord/admin-register-commands`
|
3. Open browser console (F12) → Network tab → Check the POST request to `/api/discord/admin-register-commands`
|
||||||
|
|
@ -93,6 +100,7 @@ Plus Discord's auto-generated **"Entry Point"** command (for Discord Activities)
|
||||||
### "Entry Point command already exists" (Not an Error)
|
### "Entry Point command already exists" (Not an Error)
|
||||||
|
|
||||||
**This is expected!** When you enable Discord Activities:
|
**This is expected!** When you enable Discord Activities:
|
||||||
|
|
||||||
1. Discord auto-creates an "Entry Point" command
|
1. Discord auto-creates an "Entry Point" command
|
||||||
2. Our script recognizes this and doesn't try to overwrite it
|
2. Our script recognizes this and doesn't try to overwrite it
|
||||||
3. Your bot's 5 commands live alongside it peacefully
|
3. Your bot's 5 commands live alongside it peacefully
|
||||||
|
|
@ -102,6 +110,7 @@ Plus Discord's auto-generated **"Entry Point"** command (for Discord Activities)
|
||||||
## Environment Variables Required
|
## Environment Variables Required
|
||||||
|
|
||||||
**On Vercel (Backend):**
|
**On Vercel (Backend):**
|
||||||
|
|
||||||
```
|
```
|
||||||
DISCORD_BOT_TOKEN=<your-bot-token>
|
DISCORD_BOT_TOKEN=<your-bot-token>
|
||||||
DISCORD_CLIENT_ID=578971245454950421
|
DISCORD_CLIENT_ID=578971245454950421
|
||||||
|
|
@ -109,6 +118,7 @@ DISCORD_ADMIN_REGISTER_TOKEN=sk-admin-aethex-discord-2024
|
||||||
```
|
```
|
||||||
|
|
||||||
**On PebbleHost (Bot):**
|
**On PebbleHost (Bot):**
|
||||||
|
|
||||||
```
|
```
|
||||||
DISCORD_BOT_TOKEN=<your-bot-token>
|
DISCORD_BOT_TOKEN=<your-bot-token>
|
||||||
DISCORD_CLIENT_ID=578971245454950421
|
DISCORD_CLIENT_ID=578971245454950421
|
||||||
|
|
@ -124,6 +134,7 @@ SUPABASE_SERVICE_ROLE=<your-service-role>
|
||||||
If the admin button doesn't work, you can also register commands using:
|
If the admin button doesn't work, you can also register commands using:
|
||||||
|
|
||||||
### curl (if you have PebbleHost console access)
|
### curl (if you have PebbleHost console access)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST https://aethex.dev/api/discord/admin-register-commands \
|
curl -X POST https://aethex.dev/api/discord/admin-register-commands \
|
||||||
-H "Authorization: Bearer YOUR_DISCORD_ADMIN_REGISTER_TOKEN" \
|
-H "Authorization: Bearer YOUR_DISCORD_ADMIN_REGISTER_TOKEN" \
|
||||||
|
|
@ -131,6 +142,7 @@ curl -X POST https://aethex.dev/api/discord/admin-register-commands \
|
||||||
```
|
```
|
||||||
|
|
||||||
### Postman
|
### Postman
|
||||||
|
|
||||||
1. Create POST request to `https://aethex.dev/api/discord/admin-register-commands`
|
1. Create POST request to `https://aethex.dev/api/discord/admin-register-commands`
|
||||||
2. Add header: `Authorization: Bearer YOUR_DISCORD_ADMIN_REGISTER_TOKEN`
|
2. Add header: `Authorization: Bearer YOUR_DISCORD_ADMIN_REGISTER_TOKEN`
|
||||||
3. Click Send
|
3. Click Send
|
||||||
|
|
@ -142,6 +154,6 @@ curl -X POST https://aethex.dev/api/discord/admin-register-commands \
|
||||||
✅ Click "Register Commands" in Admin → Discord tab
|
✅ Click "Register Commands" in Admin → Discord tab
|
||||||
✅ Enter your admin token
|
✅ Enter your admin token
|
||||||
✅ Wait for success confirmation
|
✅ Wait for success confirmation
|
||||||
✅ Commands are now live in Discord
|
✅ Commands are now live in Discord
|
||||||
|
|
||||||
Done! 🎉
|
Done! 🎉
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue