import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { DiscordActionConfig } from "../../config/config.js"; import { addRoleDiscord, createScheduledEventDiscord, fetchChannelInfoDiscord, fetchMemberInfoDiscord, fetchRoleInfoDiscord, fetchVoiceStatusDiscord, listGuildChannelsDiscord, listGuildEmojisDiscord, listScheduledEventsDiscord, removeRoleDiscord, uploadEmojiDiscord, uploadStickerDiscord, } from "../../discord/send.js"; import { type ActionGate, jsonResult, readStringArrayParam, readStringParam, } from "./common.js"; export async function handleDiscordGuildAction( action: string, params: Record, isActionEnabled: ActionGate, ): Promise> { switch (action) { case "memberInfo": { if (!isActionEnabled("memberInfo")) { throw new Error("Discord member info is disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const userId = readStringParam(params, "userId", { required: true, }); const member = await fetchMemberInfoDiscord(guildId, userId); return jsonResult({ ok: true, member }); } case "roleInfo": { if (!isActionEnabled("roleInfo")) { throw new Error("Discord role info is disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const roles = await fetchRoleInfoDiscord(guildId); return jsonResult({ ok: true, roles }); } case "emojiList": { if (!isActionEnabled("reactions")) { throw new Error("Discord reactions are disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const emojis = await listGuildEmojisDiscord(guildId); return jsonResult({ ok: true, emojis }); } case "emojiUpload": { if (!isActionEnabled("emojiUploads")) { throw new Error("Discord emoji uploads are disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const name = readStringParam(params, "name", { required: true }); const mediaUrl = readStringParam(params, "mediaUrl", { required: true, }); const roleIds = readStringArrayParam(params, "roleIds"); const emoji = await uploadEmojiDiscord({ guildId, name, mediaUrl, roleIds: roleIds?.length ? roleIds : undefined, }); return jsonResult({ ok: true, emoji }); } case "stickerUpload": { if (!isActionEnabled("stickerUploads")) { throw new Error("Discord sticker uploads are disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const name = readStringParam(params, "name", { required: true }); const description = readStringParam(params, "description", { required: true, }); const tags = readStringParam(params, "tags", { required: true }); const mediaUrl = readStringParam(params, "mediaUrl", { required: true, }); const sticker = await uploadStickerDiscord({ guildId, name, description, tags, mediaUrl, }); return jsonResult({ ok: true, sticker }); } case "roleAdd": { if (!isActionEnabled("roles", false)) { throw new Error("Discord role changes are disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const userId = readStringParam(params, "userId", { required: true, }); const roleId = readStringParam(params, "roleId", { required: true }); await addRoleDiscord({ guildId, userId, roleId }); return jsonResult({ ok: true }); } case "roleRemove": { if (!isActionEnabled("roles", false)) { throw new Error("Discord role changes are disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const userId = readStringParam(params, "userId", { required: true, }); const roleId = readStringParam(params, "roleId", { required: true }); await removeRoleDiscord({ guildId, userId, roleId }); return jsonResult({ ok: true }); } case "channelInfo": { if (!isActionEnabled("channelInfo")) { throw new Error("Discord channel info is disabled."); } const channelId = readStringParam(params, "channelId", { required: true, }); const channel = await fetchChannelInfoDiscord(channelId); return jsonResult({ ok: true, channel }); } case "channelList": { if (!isActionEnabled("channelInfo")) { throw new Error("Discord channel info is disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const channels = await listGuildChannelsDiscord(guildId); return jsonResult({ ok: true, channels }); } case "voiceStatus": { if (!isActionEnabled("voiceStatus")) { throw new Error("Discord voice status is disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const userId = readStringParam(params, "userId", { required: true, }); const voice = await fetchVoiceStatusDiscord(guildId, userId); return jsonResult({ ok: true, voice }); } case "eventList": { if (!isActionEnabled("events")) { throw new Error("Discord events are disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const events = await listScheduledEventsDiscord(guildId); return jsonResult({ ok: true, events }); } case "eventCreate": { if (!isActionEnabled("events")) { throw new Error("Discord events are disabled."); } const guildId = readStringParam(params, "guildId", { required: true, }); const name = readStringParam(params, "name", { required: true }); const startTime = readStringParam(params, "startTime", { required: true, }); const endTime = readStringParam(params, "endTime"); const description = readStringParam(params, "description"); const channelId = readStringParam(params, "channelId"); const location = readStringParam(params, "location"); const entityTypeRaw = readStringParam(params, "entityType"); const entityType = entityTypeRaw === "stage" ? 1 : entityTypeRaw === "external" ? 3 : 2; const payload = { name, description, scheduled_start_time: startTime, scheduled_end_time: endTime, entity_type: entityType, channel_id: channelId, entity_metadata: entityType === 3 && location ? { location } : undefined, privacy_level: 2, }; const event = await createScheduledEventDiscord(guildId, payload); return jsonResult({ ok: true, event }); } default: throw new Error(`Unknown action: ${action}`); } }