feat(admin): add detailed send log viewer with extended fields

This commit is contained in:
RhenCloud 2026-08-03 04:13:04 +08:00
parent 3a6a2cbbc5
commit dcbe93be91
No known key found for this signature in database
GPG key ID: A574A617378C4E0B
14 changed files with 460 additions and 42 deletions

View file

@ -1,13 +1,18 @@
import { log } from "../../lib/log";
import type { SendResult } from "../types";
const DISCORD_API = "https://discord.com/api/v10";
interface DiscordMessage {
id?: string;
}
export async function sendMessage(
token: string,
channelId: string,
message: unknown,
threadId?: string,
): Promise<{ ok: boolean; error?: string }> {
): Promise<SendResult> {
const url = threadId
? `${DISCORD_API}/channels/${threadId}/messages`
: `${DISCORD_API}/channels/${channelId}/messages`;
@ -35,21 +40,43 @@ export async function sendMessage(
const err = await res.text();
if (res.status >= 500) {
log.error({ status: res.status, err, attempt, channelId }, "Discord API 5xx");
if (attempt === 2) return { ok: false, error: err };
if (attempt === 2)
return {
ok: false,
error: err,
errorCode: "DISCORD_5XX",
status: res.status,
attempts: attempt + 1,
};
await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
continue;
}
log.error({ status: res.status, err, channelId }, "Discord API error");
return { ok: false, error: err };
return {
ok: false,
error: err,
errorCode: "DISCORD_ERROR",
status: res.status,
attempts: attempt + 1,
};
}
return { ok: true };
let messageId: string | undefined;
try {
const data = (await res.json()) as DiscordMessage;
messageId = data.id;
} catch {
// ignore malformed success body
}
return { ok: true, status: res.status, messageId, attempts: attempt + 1 };
} catch (err) {
log.error({ err, attempt, channelId }, "Failed to send message");
if (attempt === 2) return { ok: false, error: String(err) };
if (attempt === 2)
return { ok: false, error: String(err), errorCode: "NETWORK", attempts: attempt + 1 };
await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
}
}
return { ok: false, error: "Max retries exceeded" };
return { ok: false, error: "Max retries exceeded", errorCode: "RETRIES", attempts: 3 };
}

View file

@ -3,6 +3,10 @@ import type { Route, Env, NeutralMessage } from "../types";
export interface SendResult {
ok: boolean;
error?: string;
errorCode?: string;
status?: number;
messageId?: string;
attempts?: number;
}
export interface PlatformDriver {