import type { APIChannel, APIGuildMember, APIGuildScheduledEvent, APIRole, APIVoiceState, RESTPostAPIGuildScheduledEventJSONBody, } from "discord-api-types/v10"; import { Routes } from "discord-api-types/v10"; import type { DiscordModerationTarget, DiscordReactOpts, DiscordRoleChange, DiscordTimeoutTarget, } from "./send.types.js"; import { resolveDiscordRest } from "./send.shared.js"; export async function fetchMemberInfoDiscord( guildId: string, userId: string, opts: DiscordReactOpts = {}, ): Promise { const rest = resolveDiscordRest(opts); return (await rest.get(Routes.guildMember(guildId, userId))) as APIGuildMember; } export async function fetchRoleInfoDiscord( guildId: string, opts: DiscordReactOpts = {}, ): Promise { const rest = resolveDiscordRest(opts); return (await rest.get(Routes.guildRoles(guildId))) as APIRole[]; } export async function addRoleDiscord(payload: DiscordRoleChange, opts: DiscordReactOpts = {}) { const rest = resolveDiscordRest(opts); await rest.put(Routes.guildMemberRole(payload.guildId, payload.userId, payload.roleId)); return { ok: true }; } export async function removeRoleDiscord(payload: DiscordRoleChange, opts: DiscordReactOpts = {}) { const rest = resolveDiscordRest(opts); await rest.delete(Routes.guildMemberRole(payload.guildId, payload.userId, payload.roleId)); return { ok: true }; } export async function fetchChannelInfoDiscord( channelId: string, opts: DiscordReactOpts = {}, ): Promise { const rest = resolveDiscordRest(opts); return (await rest.get(Routes.channel(channelId))) as APIChannel; } export async function listGuildChannelsDiscord( guildId: string, opts: DiscordReactOpts = {}, ): Promise { const rest = resolveDiscordRest(opts); return (await rest.get(Routes.guildChannels(guildId))) as APIChannel[]; } export async function fetchVoiceStatusDiscord( guildId: string, userId: string, opts: DiscordReactOpts = {}, ): Promise { const rest = resolveDiscordRest(opts); return (await rest.get(Routes.guildVoiceState(guildId, userId))) as APIVoiceState; } export async function listScheduledEventsDiscord( guildId: string, opts: DiscordReactOpts = {}, ): Promise { const rest = resolveDiscordRest(opts); return (await rest.get(Routes.guildScheduledEvents(guildId))) as APIGuildScheduledEvent[]; } export async function createScheduledEventDiscord( guildId: string, payload: RESTPostAPIGuildScheduledEventJSONBody, opts: DiscordReactOpts = {}, ): Promise { const rest = resolveDiscordRest(opts); return (await rest.post(Routes.guildScheduledEvents(guildId), { body: payload, })) as APIGuildScheduledEvent; } export async function timeoutMemberDiscord( payload: DiscordTimeoutTarget, opts: DiscordReactOpts = {}, ): Promise { const rest = resolveDiscordRest(opts); let until = payload.until; if (!until && payload.durationMinutes) { const ms = payload.durationMinutes * 60 * 1000; until = new Date(Date.now() + ms).toISOString(); } return (await rest.patch(Routes.guildMember(payload.guildId, payload.userId), { body: { communication_disabled_until: until ?? null }, headers: payload.reason ? { "X-Audit-Log-Reason": encodeURIComponent(payload.reason) } : undefined, })) as APIGuildMember; } export async function kickMemberDiscord( payload: DiscordModerationTarget, opts: DiscordReactOpts = {}, ) { const rest = resolveDiscordRest(opts); await rest.delete(Routes.guildMember(payload.guildId, payload.userId), { headers: payload.reason ? { "X-Audit-Log-Reason": encodeURIComponent(payload.reason) } : undefined, }); return { ok: true }; } export async function banMemberDiscord( payload: DiscordModerationTarget & { deleteMessageDays?: number }, opts: DiscordReactOpts = {}, ) { const rest = resolveDiscordRest(opts); const deleteMessageDays = typeof payload.deleteMessageDays === "number" && Number.isFinite(payload.deleteMessageDays) ? Math.min(Math.max(Math.floor(payload.deleteMessageDays), 0), 7) : undefined; await rest.put(Routes.guildBan(payload.guildId, payload.userId), { body: deleteMessageDays !== undefined ? { delete_message_days: deleteMessageDays } : undefined, headers: payload.reason ? { "X-Audit-Log-Reason": encodeURIComponent(payload.reason) } : undefined, }); return { ok: true }; } // Channel management functions