fix(discord): add token-based fallback for application ID resolution
When the Discord API call to /oauth2/applications/@me fails (timeout, network error), the bot fails to start with "Failed to resolve Discord application id". Add a fallback that extracts the application ID by base64-decoding the first segment of the bot token, keeping it as a string to avoid precision loss for snowflake IDs exceeding Number.MAX_SAFE_INTEGER (2^53 - 1). Fixes #29608 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Peter Steinberger
parent
7f4d1b7531
commit
4b2e35ab95
@@ -165,11 +165,44 @@ export async function probeDiscord(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the application (bot user) ID from a Discord bot token by
|
||||
* base64-decoding the first segment. Discord tokens have the format:
|
||||
* base64(user_id) . timestamp . hmac
|
||||
* The decoded first segment is the numeric snowflake ID as a plain string,
|
||||
* so we keep it as a string to avoid precision loss for IDs that exceed
|
||||
* Number.MAX_SAFE_INTEGER.
|
||||
*/
|
||||
export function parseApplicationIdFromToken(token: string): string | undefined {
|
||||
const normalized = normalizeDiscordToken(token);
|
||||
if (!normalized) {
|
||||
return undefined;
|
||||
}
|
||||
const firstDot = normalized.indexOf(".");
|
||||
if (firstDot <= 0) {
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
const decoded = Buffer.from(normalized.slice(0, firstDot), "base64").toString("utf-8");
|
||||
if (/^\d+$/.test(decoded)) {
|
||||
return decoded;
|
||||
}
|
||||
return undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchDiscordApplicationId(
|
||||
token: string,
|
||||
timeoutMs: number,
|
||||
fetcher: typeof fetch = fetch,
|
||||
): Promise<string | undefined> {
|
||||
const json = await fetchDiscordApplicationMe(token, timeoutMs, fetcher);
|
||||
return json?.id ?? undefined;
|
||||
if (json?.id) {
|
||||
return json.id;
|
||||
}
|
||||
// Fallback: extract the application ID directly from the token to handle
|
||||
// cases where the API call fails (timeout, network error, etc.).
|
||||
return parseApplicationIdFromToken(token);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user