const DISCORD_API_BASE = 'https://discord.com/api/v10'; function getToken(account: string): string { const envKey = `DISCORD_${account.toUpperCase()}_BOT_TOKEN`; return process.env[envKey] ?? ''; } async function discordRequest( token: string, endpoint: string, method: 'GET' | 'POST' = 'GET', body?: unknown ) { const url = `${DISCORD_API_BASE}${endpoint}`; const res = await fetch(url, { method, headers: { 'Authorization': `Bot ${token}`, 'Content-Type': 'application/json', }, body: body ? JSON.stringify(body) : undefined, signal: AbortSignal.timeout(15000), }); if (!res.ok) { const error = await res.text(); throw new Error(`Discord API error (${res.status}): ${error}`); } return res.json(); } export async function getMe(args: { account?: string }): Promise<{ id: string; username: string; bot: boolean; }> { const token = getToken(args.account ?? 'default'); if (!token) { throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN'); } return discordRequest(token, '/users/@me'); } export async function getGuilds(args: { account?: string }): Promise> { const token = getToken(args.account ?? 'default'); if (!token) { throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN'); } return discordRequest(token, '/users/@me/guilds'); } export async function getChannels(args: { guild_id: string; account?: string }): Promise> { const token = getToken(args.account ?? 'default'); if (!token) { throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN'); } return discordRequest(token, `/guilds/${args.guild_id}/channels`); } export async function sendMessage(args: { channel_id: string; content: string; account?: string; }): Promise<{ id: string; channel_id: string }> { const token = getToken(args.account ?? 'default'); if (!token) { throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN'); } return discordRequest(token, `/channels/${args.channel_id}/messages`, 'POST', { content: args.content, }); } export async function getMessages(args: { channel_id: string; limit?: number; account?: string; }): Promise> { const token = getToken(args.account ?? 'default'); if (!token) { throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN'); } const limit = args.limit ?? 10; return discordRequest(token, `/channels/${args.channel_id}/messages?limit=${limit}`); }