diff --git a/src/toolkits/toolkits/discord/base.ts b/src/toolkits/toolkits/discord/base.ts index 5283003c..7c63543b 100644 --- a/src/toolkits/toolkits/discord/base.ts +++ b/src/toolkits/toolkits/discord/base.ts @@ -1,6 +1,11 @@ import { z } from "zod"; -import { DiscordTools, listServersTool, getUserInfoTool } from "./tools"; +import { + DiscordTools, + listServersTool, + getUserInfoTool, + getGuildMemberTool, +} from "./tools"; import type { ToolkitConfig } from "@/toolkits/types"; @@ -15,6 +20,7 @@ export const baseDiscordToolkitConfig: ToolkitConfig< tools: { [DiscordTools.ListServers]: listServersTool, [DiscordTools.GetUserInfo]: getUserInfoTool, + [DiscordTools.GetGuildMember]: getGuildMemberTool, }, parameters: discordParameters, }; diff --git a/src/toolkits/toolkits/discord/client.tsx b/src/toolkits/toolkits/discord/client.tsx index 1aa486ab..d0f32d87 100644 --- a/src/toolkits/toolkits/discord/client.tsx +++ b/src/toolkits/toolkits/discord/client.tsx @@ -7,6 +7,7 @@ import { DiscordTools } from "./tools"; import { listServersToolConfigClient, getUserInfoToolConfigClient, + getGuildMemberToolConfigClient, } from "./tools/client"; import { Link } from "../components/link"; @@ -40,5 +41,6 @@ export const discordClientToolkit = createClientToolkit( { [DiscordTools.ListServers]: listServersToolConfigClient, [DiscordTools.GetUserInfo]: getUserInfoToolConfigClient, + [DiscordTools.GetGuildMember]: getGuildMemberToolConfigClient, }, ); diff --git a/src/toolkits/toolkits/discord/server.ts b/src/toolkits/toolkits/discord/server.ts index c3c788be..8db49978 100644 --- a/src/toolkits/toolkits/discord/server.ts +++ b/src/toolkits/toolkits/discord/server.ts @@ -7,6 +7,7 @@ import { DiscordTools } from "./tools"; import { listServersToolConfigServer, getUserInfoToolConfigServer, + getGuildMemberToolConfigServer, } from "./tools/server"; import { api } from "@/trpc/server"; @@ -17,10 +18,12 @@ export const discordToolkitServer = createServerToolkit( - **List Servers**: Get a list of all Discord servers you are a member of - **Get User Info**: Retrieve information about your Discord account +- **Get Guild Member**: Retrieve your member profile, roles, and join date for a specific Discord server **Tool Sequencing Strategies:** 1. **Server Discovery**: Start with List Servers to see all your servers -2. **Profile Analysis**: Use Get User Info to understand your account status and permissions +2. **Server Membership Details**: Use Get Guild Member with a server ID from List Servers to inspect your server-specific member profile +3. **Profile Analysis**: Use Get User Info to understand your account status and permissions **Best Practices:** - Use List Servers to understand your server landscape @@ -46,6 +49,7 @@ export const discordToolkitServer = createServerToolkit( return { [DiscordTools.ListServers]: listServersToolConfigServer(rest), [DiscordTools.GetUserInfo]: getUserInfoToolConfigServer(rest), + [DiscordTools.GetGuildMember]: getGuildMemberToolConfigServer(rest), }; }, ); diff --git a/src/toolkits/toolkits/discord/tools/client.ts b/src/toolkits/toolkits/discord/tools/client.ts index 8d2e9fb1..007307d8 100644 --- a/src/toolkits/toolkits/discord/tools/client.ts +++ b/src/toolkits/toolkits/discord/tools/client.ts @@ -1,2 +1,3 @@ export * from "./list-servers/client"; export * from "./get-user-info/client"; +export * from "./get-guild-member/client"; diff --git a/src/toolkits/toolkits/discord/tools/get-guild-member/base.ts b/src/toolkits/toolkits/discord/tools/get-guild-member/base.ts new file mode 100644 index 00000000..9e1669c0 --- /dev/null +++ b/src/toolkits/toolkits/discord/tools/get-guild-member/base.ts @@ -0,0 +1,16 @@ +import { z } from "zod"; + +import { createBaseTool } from "@/toolkits/create-tool"; + +import type { RESTGetCurrentUserGuildMemberResult } from "discord-api-types/v10"; + +export const getGuildMemberTool = createBaseTool({ + description: + "Get your Discord member profile for a specific server by guild ID", + inputSchema: z.object({ + guildId: z.string().describe("Discord server/guild ID"), + }), + outputSchema: z.object({ + member: z.custom(), + }), +}); diff --git a/src/toolkits/toolkits/discord/tools/get-guild-member/client.tsx b/src/toolkits/toolkits/discord/tools/get-guild-member/client.tsx new file mode 100644 index 00000000..86702bb0 --- /dev/null +++ b/src/toolkits/toolkits/discord/tools/get-guild-member/client.tsx @@ -0,0 +1,45 @@ +import React from "react"; +import { createClientTool } from "@/toolkits/create-tool"; +import { BadgeCheck, CalendarDays, Shield } from "lucide-react"; + +import { getGuildMemberTool } from "./base"; + +export const getGuildMemberToolConfigClient = createClientTool( + getGuildMemberTool, + { + CallComponent: ({ args }) => ( +

+ Getting Discord member info for {args.guildId ?? "..."} +

+ ), + ResultComponent: ({ result: { member } }) => ( +
+

Discord Server Membership

+
+
+ + + {member.nick ?? member.user?.username ?? "Member"} + +
+
+ + + Joined {new Date(member.joined_at).toLocaleDateString()} + +
+
+ + {member.roles.length} roles +
+ {member.premium_since && ( +
+ Boosting since{" "} + {new Date(member.premium_since).toLocaleDateString()} +
+ )} +
+
+ ), + }, +); diff --git a/src/toolkits/toolkits/discord/tools/get-guild-member/server.ts b/src/toolkits/toolkits/discord/tools/get-guild-member/server.ts new file mode 100644 index 00000000..00bf0497 --- /dev/null +++ b/src/toolkits/toolkits/discord/tools/get-guild-member/server.ts @@ -0,0 +1,24 @@ +import { Routes } from "discord-api-types/v10"; + +import { type getGuildMemberTool } from "./base"; + +import type { ServerToolConfig } from "@/toolkits/types"; +import type { RESTGetCurrentUserGuildMemberResult } from "discord-api-types/v10"; +import type { REST } from "@discordjs/rest"; + +export const getGuildMemberToolConfigServer = ( + rest: REST, +): ServerToolConfig< + typeof getGuildMemberTool.inputSchema.shape, + typeof getGuildMemberTool.outputSchema.shape +> => { + return { + callback: async ({ guildId }) => { + return { + member: (await rest.get( + Routes.userGuildMember(guildId), + )) as RESTGetCurrentUserGuildMemberResult, + }; + }, + }; +}; diff --git a/src/toolkits/toolkits/discord/tools/index.ts b/src/toolkits/toolkits/discord/tools/index.ts index 30e1fcef..4b4a3903 100644 --- a/src/toolkits/toolkits/discord/tools/index.ts +++ b/src/toolkits/toolkits/discord/tools/index.ts @@ -1,7 +1,9 @@ export enum DiscordTools { ListServers = "list-servers", GetUserInfo = "get-user-info", + GetGuildMember = "get-guild-member", } export * from "./list-servers/base"; export * from "./get-user-info/base"; +export * from "./get-guild-member/base"; diff --git a/src/toolkits/toolkits/discord/tools/server.ts b/src/toolkits/toolkits/discord/tools/server.ts index 43bc94f0..ab766b6a 100644 --- a/src/toolkits/toolkits/discord/tools/server.ts +++ b/src/toolkits/toolkits/discord/tools/server.ts @@ -1,2 +1,3 @@ export * from "./list-servers/server"; export * from "./get-user-info/server"; +export * from "./get-guild-member/server"; diff --git a/src/toolkits/toolkits/discord/wrapper.tsx b/src/toolkits/toolkits/discord/wrapper.tsx index e9937437..79fbf720 100644 --- a/src/toolkits/toolkits/discord/wrapper.tsx +++ b/src/toolkits/toolkits/discord/wrapper.tsx @@ -16,7 +16,7 @@ import { import type { ClientToolkitWrapper } from "@/toolkits/types"; import { Toolkits } from "../shared"; -const scopes = ["identify", "guilds", "email"]; +const scopes = ["identify", "guilds", "guilds.members.read", "email"]; export const DiscordWrapper: ClientToolkitWrapper = ({ Item }) => { const { data: account, isLoading } =