diff --git a/src/tools/channel.ts b/src/tools/channel.ts index f2f1e08..75d3e62 100644 --- a/src/tools/channel.ts +++ b/src/tools/channel.ts @@ -5,11 +5,9 @@ import { CreateTextChannelSchema, DeleteChannelSchema, ReadMessagesSchema, - GetServerInfoSchema, CreateCategorySchema, EditCategorySchema, - DeleteCategorySchema, - ListServersSchema + DeleteCategorySchema } from "../schemas.js"; import { handleDiscordError } from "../errorHandler.js"; @@ -261,135 +259,3 @@ export async function readMessagesHandler( return handleDiscordError(error); } } - -// Server information handler -export async function getServerInfoHandler( - args: unknown, - context: ToolContext -): Promise { - const { guildId } = GetServerInfoSchema.parse(args); - try { - if (!context.client.isReady()) { - return { - content: [{ type: "text", text: "Discord client not logged in." }], - isError: true - }; - } - - const guild = await context.client.guilds.fetch(guildId); - if (!guild) { - return { - content: [{ type: "text", text: `Cannot find guild with ID: ${guildId}` }], - isError: true - }; - } - - // Fetch additional server data - await guild.fetch(); - - // Fetch channel information - const channels = await guild.channels.fetch(); - - // Categorize channels by type - const channelsByType = { - text: channels.filter(c => c?.type === ChannelType.GuildText).size, - voice: channels.filter(c => c?.type === ChannelType.GuildVoice).size, - category: channels.filter(c => c?.type === ChannelType.GuildCategory).size, - forum: channels.filter(c => c?.type === ChannelType.GuildForum).size, - announcement: channels.filter(c => c?.type === ChannelType.GuildAnnouncement).size, - stage: channels.filter(c => c?.type === ChannelType.GuildStageVoice).size, - total: channels.size - }; - - // Get detailed information for all channels - const channelDetails = channels.map(channel => { - if (!channel) return null; - - return { - id: channel.id, - name: channel.name, - type: ChannelType[channel.type] || channel.type, - categoryId: channel.parentId, - position: channel.position, - // Only add topic for text channels - topic: 'topic' in channel ? channel.topic : null, - }; - }).filter(c => c !== null); // Filter out null values - - // Group channels by type - const groupedChannels = { - text: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildText] || c.type === ChannelType.GuildText), - voice: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildVoice] || c.type === ChannelType.GuildVoice), - category: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildCategory] || c.type === ChannelType.GuildCategory), - forum: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildForum] || c.type === ChannelType.GuildForum), - announcement: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildAnnouncement] || c.type === ChannelType.GuildAnnouncement), - stage: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildStageVoice] || c.type === ChannelType.GuildStageVoice), - all: channelDetails - }; - - // Get member count - const approximateMemberCount = guild.approximateMemberCount || "unknown"; - - // Format guild information - const guildInfo = { - id: guild.id, - name: guild.name, - description: guild.description, - icon: guild.iconURL(), - owner: guild.ownerId, - createdAt: guild.createdAt, - memberCount: approximateMemberCount, - channels: { - count: channelsByType, - details: groupedChannels - }, - features: guild.features, - premium: { - tier: guild.premiumTier, - subscriptions: guild.premiumSubscriptionCount - } - }; - - return { - content: [{ type: "text", text: JSON.stringify(guildInfo, null, 2) }] - }; - } catch (error) { - return handleDiscordError(error); - } -} - -// List servers handler -export async function listServersHandler( - args: unknown, - context: ToolContext -): Promise { - ListServersSchema.parse(args); - try { - if (!context.client.isReady()) { - return { - content: [{ type: "text", text: "Discord client not logged in." }], - isError: true - }; - } - - const guilds = await context.client.guilds.fetch(); - - if (guilds.size === 0) { - return { - content: [{ type: "text", text: "No servers found. The bot is not a member of any servers." }] - }; - } - - const guildsInfo = guilds.map(guild => ({ - id: guild.id, - name: guild.name, - icon: guild.iconURL() - })); - - return { - content: [{ type: "text", text: JSON.stringify(guildsInfo, null, 2) }] - }; - } catch (error) { - return handleDiscordError(error); - } -} \ No newline at end of file diff --git a/src/tools/server.ts b/src/tools/server.ts index 556421c..aba56ec 100644 --- a/src/tools/server.ts +++ b/src/tools/server.ts @@ -1,5 +1,6 @@ +import { ChannelType } from "discord.js"; import { handleDiscordError } from "../errorHandler.js"; -import { SearchMessagesSchema } from "../schemas.js"; +import { GetServerInfoSchema, ListServersSchema, SearchMessagesSchema } from "../schemas.js"; import { ToolContext, ToolResponse } from "./types.js"; @@ -51,3 +52,137 @@ export async function searchMessagesHandler( return handleDiscordError(error); } } + +// List servers handler +export async function listServersHandler( + args: unknown, + context: ToolContext +): Promise { + ListServersSchema.parse(args); + try { + if (!context.client.isReady()) { + return { + content: [{ type: "text", text: "Discord client not logged in." }], + isError: true + }; + } + + const guilds = await context.client.guilds.fetch(); + + if (guilds.size === 0) { + return { + content: [{ type: "text", text: "No servers found. The bot is not a member of any servers." }] + }; + } + + const guildsInfo = guilds.map(guild => ({ + id: guild.id, + name: guild.name, + icon: guild.iconURL() + })); + + return { + content: [{ type: "text", text: JSON.stringify(guildsInfo, null, 2) }] + }; + } catch (error) { + return handleDiscordError(error); + } +} + +// Server information handler +export async function getServerInfoHandler( + args: unknown, + context: ToolContext +): Promise { + const { guildId } = GetServerInfoSchema.parse(args); + try { + if (!context.client.isReady()) { + return { + content: [{ type: "text", text: "Discord client not logged in." }], + isError: true + }; + } + + const guild = await context.client.guilds.fetch(guildId); + if (!guild) { + return { + content: [{ type: "text", text: `Cannot find guild with ID: ${guildId}` }], + isError: true + }; + } + + // Fetch additional server data + await guild.fetch(); + + // Fetch channel information + const channels = await guild.channels.fetch(); + + // Categorize channels by type + const channelsByType = { + text: channels.filter(c => c?.type === ChannelType.GuildText).size, + voice: channels.filter(c => c?.type === ChannelType.GuildVoice).size, + category: channels.filter(c => c?.type === ChannelType.GuildCategory).size, + forum: channels.filter(c => c?.type === ChannelType.GuildForum).size, + announcement: channels.filter(c => c?.type === ChannelType.GuildAnnouncement).size, + stage: channels.filter(c => c?.type === ChannelType.GuildStageVoice).size, + total: channels.size + }; + + // Get detailed information for all channels + const channelDetails = channels.map(channel => { + if (!channel) return null; + + return { + id: channel.id, + name: channel.name, + type: ChannelType[channel.type] || channel.type, + categoryId: channel.parentId, + position: channel.position, + // Only add topic for text channels + topic: 'topic' in channel ? channel.topic : null, + }; + }).filter(c => c !== null); // Filter out null values + + + // Group channels by type + const groupedChannels = { + text: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildText] || c.type === ChannelType.GuildText), + voice: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildVoice] || c.type === ChannelType.GuildVoice), + category: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildCategory] || c.type === ChannelType.GuildCategory), + forum: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildForum] || c.type === ChannelType.GuildForum), + announcement: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildAnnouncement] || c.type === ChannelType.GuildAnnouncement), + stage: channelDetails.filter(c => c.type === ChannelType[ChannelType.GuildStageVoice] || c.type === ChannelType.GuildStageVoice), + all: channelDetails + }; + + // Get member count + const approximateMemberCount = guild.approximateMemberCount || "unknown"; + + // Format guild information + const guildInfo = { + id: guild.id, + name: guild.name, + description: guild.description, + icon: guild.iconURL(), + owner: guild.ownerId, + createdAt: guild.createdAt, + memberCount: approximateMemberCount, + channels: { + count: channelsByType, + details: groupedChannels + }, + features: guild.features, + premium: { + tier: guild.premiumTier, + subscriptions: guild.premiumSubscriptionCount + } + }; + + return { + content: [{ type: "text", text: JSON.stringify(guildInfo, null, 2) }] + }; + } catch (error) { + return handleDiscordError(error); + } +} + diff --git a/src/tools/tools.ts b/src/tools/tools.ts index 8312fb7..78e74c0 100644 --- a/src/tools/tools.ts +++ b/src/tools/tools.ts @@ -14,13 +14,13 @@ import { createTextChannelHandler, deleteChannelHandler, readMessagesHandler, - getServerInfoHandler, createCategoryHandler, editCategoryHandler, - deleteCategoryHandler, - listServersHandler + deleteCategoryHandler } from './channel.js'; -import { +import { + getServerInfoHandler, + listServersHandler, searchMessagesHandler } from "./server.js"; import {