@zhin.js/adapter-discord 7.0.14 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @zhin.js/adapter-discord
2
2
 
3
+ ## 8.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 1fc78bc: Unify native platform Client access behind the literal `adapter` discriminant. Handlers infer both native events and Clients, while command, inbound/outbound middleware, and both Agent tool authoring surfaces expose the exact operation-scoped Client through a lazy `$client` getter. Definitions without `adapter` keep `$client` typed as `unknown`, and runtime dispatch rejects adapter mismatches before resolving the Client. Bundled platform tools now use this single path instead of model-provided endpoint ids and adapter-specific dependency wrappers. Every adapter registers one Client/EventMap contract, and protocol adapters including NapCat, Milky, OneBot and Satori now produce transport-independent Client objects rather than letting Endpoint instances impersonate Clients.
8
+ - Updated dependencies [e9c6a73]
9
+ - Updated dependencies [4e8117c]
10
+ - Updated dependencies [902fa35]
11
+ - Updated dependencies [54bfd6b]
12
+ - Updated dependencies [12025ee]
13
+ - Updated dependencies [09b14d6]
14
+ - Updated dependencies [1fc78bc]
15
+ - @zhin.js/agent@1.1.16
16
+ - @zhin.js/adapter@1.2.1
17
+ - @zhin.js/core@1.5.14
18
+ - @zhin.js/host-http@1.0.13
19
+ - @zhin.js/command@1.0.16
20
+ - @zhin.js/logger@1.0.77
21
+ - zhin.js@6.0.14
22
+ - @zhin.js/feature-kit@1.0.13
23
+ - @zhin.js/permission@1.0.4
24
+
25
+ ## 8.0.0
26
+
27
+ ### Patch Changes
28
+
29
+ - f2c532f: Expose exact per-Endpoint message operations through one validated Adapter capability model, route Core control calls through declared active capabilities, and connect existing recall, edit, reaction, and typing implementations across platform adapters.
30
+ - Updated dependencies [b10d058]
31
+ - Updated dependencies [f2c532f]
32
+ - Updated dependencies [3dbf990]
33
+ - @zhin.js/host-http@1.0.12
34
+ - @zhin.js/adapter@1.2.0
35
+ - @zhin.js/core@1.5.13
36
+ - @zhin.js/agent@1.1.15
37
+ - zhin.js@6.0.13
38
+
3
39
  ## 7.0.14
4
40
 
5
41
  ### Patch Changes
package/README.md CHANGED
@@ -20,7 +20,7 @@ pnpm add @zhin.js/adapter-discord discord.js
20
20
  ## Plugin Runtime
21
21
 
22
22
  - `@zhin.js/adapter` — 约定式 `adapters/discord.ts`(`defineAdapter`)
23
- - `@zhin.js/core` — `messageGatewayToken` 入站/出站
23
+ - `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
24
24
  - `zhin.js` — `plugin.ts`(`definePlugin`)
25
25
  - 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
26
26
  - **无需** `@zhin.js/host-http` / `@zhin.js/host-router`(Gateway 路径)
@@ -86,6 +86,15 @@ plugins:
86
86
  3. 开启 **MESSAGE CONTENT INTENT**
87
87
  4. 通过 OAuth2 URL 邀请 Bot 加入服务器
88
88
 
89
+ ## 故障排查
90
+
91
+ | 现象 | 排查 |
92
+ | --- | --- |
93
+ | Gateway 反复断线 | 检查 Token、网络代理、Gateway Intents 与应用后台配置 |
94
+ | 能上线但收不到正文 | 启用 Message Content Intent,并给 Bot 频道读取权限 |
95
+ | 能收不能发 | 检查 Send Messages、Embed Links 与附件权限 |
96
+ | `connection: interactions` 启动失败 | 当前生产路径使用 Gateway;改回 `gateway` |
97
+
89
98
  ## 许可证
90
99
 
91
100
  MIT License
@@ -3,7 +3,6 @@
3
3
  * Convention entry: discover `adapters/discord.ts` → defineAdapter.
4
4
  */
5
5
  import { defineAdapter } from 'zhin.js/adapter';
6
- import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
7
6
  import { httpHostToken } from '@zhin.js/host-http';
8
7
  import { DiscordGatewayEndpoint, DiscordInteractionsEndpoint, } from "../lib/endpoint.js";
9
8
  import { resolveDiscordConfig, } from "../lib/protocol.js";
@@ -11,7 +10,9 @@ import { discordRuntimeStateToken } from "../lib/discord-runtime-state.js";
11
10
  export { DiscordGatewayEndpoint, DiscordInteractionsEndpoint, } from "../lib/endpoint.js";
12
11
  export default defineAdapter({
13
12
  capabilities: ['inbound', 'outbound'],
14
- operations: ['recall'],
13
+ operations: (context) => context.config.connection === 'interactions'
14
+ ? ['recall']
15
+ : ['recall', 'reaction'],
15
16
  // 媒体 url 直发或由 AttachmentBuilder 物化本地文件上传;message components 原生按钮承载交互段。
16
17
  segments: {
17
18
  outboundMedia: ['url', 'upload'],
@@ -20,8 +21,6 @@ export default defineAdapter({
20
21
  },
21
22
  create(context) {
22
23
  const config = resolveDiscordConfig(context.config);
23
- const gateway = context.use(messageGatewayToken);
24
- const sideEvents = context.use(sideEventGatewayToken);
25
24
  // 注册到插件运行时状态(discord.endpoint list 的"运行中"数据源)
26
25
  context.use(discordRuntimeStateToken).endpoints.set(config.id, {
27
26
  id: config.id,
@@ -30,16 +29,12 @@ export default defineAdapter({
30
29
  if (config.connection === 'interactions') {
31
30
  return new DiscordInteractionsEndpoint({
32
31
  id: context.id,
33
- gateway,
34
- sideEvents,
35
32
  http: context.use(httpHostToken),
36
33
  config,
37
34
  });
38
35
  }
39
36
  return new DiscordGatewayEndpoint({
40
37
  id: context.id,
41
- gateway,
42
- sideEvents,
43
38
  config,
44
39
  });
45
40
  },
@@ -2,7 +2,6 @@
2
2
  * Convention entry: discover `adapters/discord.ts` → defineAdapter.
3
3
  */
4
4
  import { defineAdapter } from 'zhin.js/adapter';
5
- import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
6
5
  import { httpHostToken } from '@zhin.js/host-http';
7
6
  import {
8
7
  DiscordGatewayEndpoint,
@@ -27,7 +26,9 @@ export type {
27
26
 
28
27
  export default defineAdapter<DiscordAdapterConfig>({
29
28
  capabilities: ['inbound', 'outbound'],
30
- operations: ['recall'],
29
+ operations: (context) => context.config.connection === 'interactions'
30
+ ? ['recall']
31
+ : ['recall', 'reaction'],
31
32
  // 媒体 url 直发或由 AttachmentBuilder 物化本地文件上传;message components 原生按钮承载交互段。
32
33
  segments: {
33
34
  outboundMedia: ['url', 'upload'],
@@ -36,8 +37,6 @@ export default defineAdapter<DiscordAdapterConfig>({
36
37
  },
37
38
  create(context) {
38
39
  const config = resolveDiscordConfig(context.config);
39
- const gateway = context.use(messageGatewayToken);
40
- const sideEvents = context.use(sideEventGatewayToken);
41
40
  // 注册到插件运行时状态(discord.endpoint list 的"运行中"数据源)
42
41
  context.use(discordRuntimeStateToken).endpoints.set(config.id, {
43
42
  id: config.id,
@@ -46,16 +45,12 @@ export default defineAdapter<DiscordAdapterConfig>({
46
45
  if (config.connection === 'interactions') {
47
46
  return new DiscordInteractionsEndpoint({
48
47
  id: context.id,
49
- gateway,
50
- sideEvents,
51
48
  http: context.use(httpHostToken),
52
49
  config,
53
50
  });
54
51
  }
55
52
  return new DiscordGatewayEndpoint({
56
53
  id: context.id,
57
- gateway,
58
- sideEvents,
59
54
  config,
60
55
  });
61
56
  },
@@ -1,24 +1,26 @@
1
1
  import { defineAgentTool } from '@zhin.js/agent/tools';
2
2
  import { z } from 'zod';
3
+ import { requireDiscordGatewayClient } from '../../src/client.js';
3
4
  import { platformPermit } from '../../src/platform-permit.js';
4
- import { getDiscordAgentDeps } from '../../src/discord-agent-deps.js';
5
5
 
6
- export default defineAgentTool<{ endpoint_id: string; guild_id: string; user_id: string; role_id: string }>({
6
+ export default defineAgentTool<{ guild_id: string; user_id: string; role_id: string }>({
7
7
  description: '给成员添加 Discord 角色',
8
8
  inputSchema: z.object({
9
- endpoint_id: z.string().describe('Endpoint 名称'),
10
9
  guild_id: z.string().describe('服务器 ID'),
11
10
  user_id: z.string().describe('用户 ID'),
12
11
  role_id: z.string().describe('角色 ID'),
13
12
  }),
14
- platforms: ['discord'],
13
+ adapter: 'discord',
15
14
  tags: ['discord'],
16
15
  permissions: [platformPermit('manage_roles')],
17
- async execute({ endpoint_id, guild_id, user_id, role_id }: { endpoint_id: string; guild_id: string; user_id: string; role_id: string }) {
18
- const endpoint = getDiscordAgentDeps().getGatewayEndpoint(endpoint_id) as {
19
- addRole: (guildId: string, userId: string, roleId: string) => Promise<boolean>;
16
+ async execute({ guild_id, user_id, role_id }: { guild_id: string; user_id: string; role_id: string }, context) {
17
+ const client = requireDiscordGatewayClient(context.$client);
18
+ const guild = await client.guilds.fetch(guild_id);
19
+ const member = await guild.members.fetch(user_id) as {
20
+ roles: { add(id: string): Promise<unknown> };
20
21
  };
21
- const success = await endpoint.addRole(guild_id, user_id, role_id);
22
+ await member.roles.add(role_id);
23
+ const success = true;
22
24
  return { success, message: success ? `已给用户 ${user_id} 添加角色` : '操作失败' };
23
25
  },
24
26
  });
@@ -1,25 +1,28 @@
1
1
  import { defineAgentTool } from '@zhin.js/agent/tools';
2
2
  import { z } from 'zod';
3
+ import { requireDiscordGatewayClient } from '../../src/client.js';
3
4
  import { platformPermit } from '../../src/platform-permit.js';
4
- import { getDiscordAgentDeps } from '../../src/discord-agent-deps.js';
5
5
 
6
- export default defineAgentTool<{ endpoint_id: string; channel_id: string; name: string; message_id?: string; auto_archive_duration?: number }>({
6
+ export default defineAgentTool<{ channel_id: string; name: string; message_id?: string; auto_archive_duration?: number }>({
7
7
  description: '在 Discord 频道中创建帖子/子线程',
8
8
  inputSchema: z.object({
9
- endpoint_id: z.string().describe('Endpoint 名称'),
10
9
  channel_id: z.string().describe('频道 ID'),
11
10
  name: z.string().describe('帖子标题'),
12
11
  message_id: z.string().optional().describe('基于某条消息创建(可选)'),
13
12
  auto_archive_duration: z.number().optional().describe('自动归档时间(分钟:60/1440/4320/10080)'),
14
13
  }),
15
- platforms: ['discord'],
14
+ adapter: 'discord',
16
15
  tags: ['discord'],
17
16
  permissions: [platformPermit('manage_channels')],
18
- async execute({ endpoint_id, channel_id, name, message_id, auto_archive_duration }: { endpoint_id: string; channel_id: string; name: string; message_id?: string; auto_archive_duration?: number }) {
19
- const endpoint = getDiscordAgentDeps().getGatewayEndpoint(endpoint_id) as {
20
- createThread: (channelId: string, threadName: string, messageId?: string, autoArchiveDuration?: number) => Promise<{ id: string }>;
21
- };
22
- const thread = await endpoint.createThread(channel_id, name, message_id, auto_archive_duration);
17
+ async execute({ channel_id, name, message_id, auto_archive_duration }: { channel_id: string; name: string; message_id?: string; auto_archive_duration?: number }, context) {
18
+ const client = requireDiscordGatewayClient(context.$client);
19
+ const channel = await client.channels.fetch(channel_id);
20
+ if (!channel?.threads) throw new Error(`Channel ${channel_id} 不支持创建帖子`);
21
+ const thread = await channel.threads.create({
22
+ name,
23
+ autoArchiveDuration: auto_archive_duration || 1440,
24
+ ...(message_id ? { startMessage: message_id } : {}),
25
+ });
23
26
  return { success: true, thread_id: thread.id, message: `帖子 "${name}" 已创建` };
24
27
  },
25
28
  });
@@ -1,24 +1,33 @@
1
1
  import { defineAgentTool } from '@zhin.js/agent/tools';
2
2
  import { z } from 'zod';
3
- import { getDiscordAgentDeps } from '../../src/discord-agent-deps.js';
3
+ import { requireDiscordGatewayClient } from '../../src/client.js';
4
+ import { ChannelType } from 'discord.js';
4
5
 
5
- export default defineAgentTool<{ endpoint_id: string; channel_id: string; name: string; content: string; tags?: string }>({
6
+ export default defineAgentTool<{ channel_id: string; name: string; content: string; tags?: string }>({
6
7
  description: '在 Discord 论坛频道中创建帖子',
7
8
  inputSchema: z.object({
8
- endpoint_id: z.string().describe('Endpoint 名称'),
9
9
  channel_id: z.string().describe('论坛频道 ID'),
10
10
  name: z.string().describe('帖子标题'),
11
11
  content: z.string().describe('帖子内容'),
12
12
  tags: z.string().optional().describe('标签名,逗号分隔(可选)'),
13
13
  }),
14
- platforms: ['discord'],
14
+ adapter: 'discord',
15
15
  tags: ['discord'],
16
- async execute({ endpoint_id, channel_id, name, content, tags }: { endpoint_id: string; channel_id: string; name: string; content: string; tags?: string }) {
17
- const endpoint = getDiscordAgentDeps().getGatewayEndpoint(endpoint_id) as {
18
- createForumPost: (channelId: string, title: string, body: string, tagNames?: string[]) => Promise<{ id: string }>;
19
- };
16
+ async execute({ channel_id, name, content, tags }: { channel_id: string; name: string; content: string; tags?: string }, context) {
17
+ const client = requireDiscordGatewayClient(context.$client);
20
18
  const tagList = tags ? tags.split(',').map((t: string) => t.trim()) : undefined;
21
- const thread = await endpoint.createForumPost(channel_id, name, content, tagList);
19
+ const channel = await client.channels.fetch(channel_id);
20
+ if (!channel?.threads || channel.type !== ChannelType.GuildForum) {
21
+ throw new Error(`Channel ${channel_id} 不是论坛频道`);
22
+ }
23
+ const tagIds = tagList?.length
24
+ ? channel.availableTags?.filter((tag) => tagList.includes(tag.name)).map((tag) => tag.id)
25
+ : undefined;
26
+ const thread = await channel.threads.create({
27
+ name,
28
+ message: { content },
29
+ ...(tagIds?.length ? { appliedTags: tagIds } : {}),
30
+ });
22
31
  return { success: true, thread_id: thread.id, message: `论坛帖 "${name}" 已创建` };
23
32
  },
24
33
  });
@@ -1,22 +1,34 @@
1
1
  import { defineAgentTool } from '@zhin.js/agent/tools';
2
2
  import { z } from 'zod';
3
+ import { requireDiscordGatewayClient } from '../../src/client.js';
3
4
  import { platformPermit } from '../../src/platform-permit.js';
4
- import { getDiscordAgentDeps } from '../../src/discord-agent-deps.js';
5
5
 
6
- export default defineAgentTool<{ endpoint_id: string; guild_id: string }>({
6
+ export default defineAgentTool<{ guild_id: string }>({
7
7
  description: '获取 Discord 服务器角色列表',
8
8
  inputSchema: z.object({
9
- endpoint_id: z.string().describe('Endpoint 名称'),
10
9
  guild_id: z.string().describe('服务器 ID'),
11
10
  }),
12
- platforms: ['discord'],
11
+ adapter: 'discord',
13
12
  tags: ['discord'],
14
13
  permissions: [platformPermit('manage_roles')],
15
- async execute({ endpoint_id, guild_id }: { endpoint_id: string; guild_id: string }) {
16
- const endpoint = getDiscordAgentDeps().getGatewayEndpoint(endpoint_id) as {
17
- getRoles: (guildId: string) => Promise<unknown[]>;
18
- };
19
- const roles = await endpoint.getRoles(guild_id);
14
+ async execute({ guild_id }: { guild_id: string }, context) {
15
+ const client = requireDiscordGatewayClient(context.$client);
16
+ const guild = await client.guilds.fetch(guild_id);
17
+ await guild.roles.fetch();
18
+ const cache = guild.roles.cache as Map<string, {
19
+ id: string;
20
+ name: string;
21
+ hexColor: string;
22
+ position: number;
23
+ permissions: { bitfield: bigint };
24
+ }>;
25
+ const roles = [...cache.values()].map((role) => ({
26
+ id: role.id,
27
+ name: role.name,
28
+ color: role.hexColor,
29
+ position: role.position,
30
+ permissions: role.permissions.bitfield.toString(),
31
+ }));
20
32
  return { roles, count: roles.length };
21
33
  },
22
34
  });
@@ -1,22 +1,24 @@
1
1
  import { defineAgentTool } from '@zhin.js/agent/tools';
2
2
  import { z } from 'zod';
3
- import { getDiscordAgentDeps } from '../../src/discord-agent-deps.js';
3
+ import { requireDiscordGatewayClient } from '../../src/client.js';
4
4
 
5
- export default defineAgentTool<{ endpoint_id: string; channel_id: string; message_id: string; emoji: string }>({
5
+ export default defineAgentTool<{ channel_id: string; message_id: string; emoji: string }>({
6
6
  description: '对 Discord 消息添加表情反应',
7
7
  inputSchema: z.object({
8
- endpoint_id: z.string().describe('Endpoint 名称'),
9
8
  channel_id: z.string().describe('频道 ID'),
10
9
  message_id: z.string().describe('消息 ID'),
11
10
  emoji: z.string().describe('表情(Unicode 表情或自定义表情如 <:name:id>)'),
12
11
  }),
13
- platforms: ['discord'],
12
+ adapter: 'discord',
14
13
  tags: ['discord'],
15
- async execute({ endpoint_id, channel_id, message_id, emoji }: { endpoint_id: string; channel_id: string; message_id: string; emoji: string }) {
16
- const endpoint = getDiscordAgentDeps().getGatewayEndpoint(endpoint_id) as {
17
- addReaction: (channelId: string, messageId: string, reaction: string) => Promise<void>;
18
- };
19
- await endpoint.addReaction(channel_id, message_id, emoji);
14
+ async execute({ channel_id, message_id, emoji }: { channel_id: string; message_id: string; emoji: string }, context) {
15
+ const client = requireDiscordGatewayClient(context.$client);
16
+ const channel = await client.channels.fetch(channel_id);
17
+ if (!channel?.isTextBased() || !channel.messages) {
18
+ throw new Error(`Channel ${channel_id} 不是文本频道`);
19
+ }
20
+ const message = await channel.messages.fetch(message_id);
21
+ await message.react(emoji);
20
22
  return { success: true, message: `已添加反应 ${emoji}` };
21
23
  },
22
24
  });
@@ -1,24 +1,26 @@
1
1
  import { defineAgentTool } from '@zhin.js/agent/tools';
2
2
  import { z } from 'zod';
3
+ import { requireDiscordGatewayClient } from '../../src/client.js';
3
4
  import { platformPermit } from '../../src/platform-permit.js';
4
- import { getDiscordAgentDeps } from '../../src/discord-agent-deps.js';
5
5
 
6
- export default defineAgentTool<{ endpoint_id: string; guild_id: string; user_id: string; role_id: string }>({
6
+ export default defineAgentTool<{ guild_id: string; user_id: string; role_id: string }>({
7
7
  description: '移除成员的 Discord 角色',
8
8
  inputSchema: z.object({
9
- endpoint_id: z.string().describe('Endpoint 名称'),
10
9
  guild_id: z.string().describe('服务器 ID'),
11
10
  user_id: z.string().describe('用户 ID'),
12
11
  role_id: z.string().describe('角色 ID'),
13
12
  }),
14
- platforms: ['discord'],
13
+ adapter: 'discord',
15
14
  tags: ['discord'],
16
15
  permissions: [platformPermit('manage_roles')],
17
- async execute({ endpoint_id, guild_id, user_id, role_id }: { endpoint_id: string; guild_id: string; user_id: string; role_id: string }) {
18
- const endpoint = getDiscordAgentDeps().getGatewayEndpoint(endpoint_id) as {
19
- removeRole: (guildId: string, userId: string, roleId: string) => Promise<boolean>;
16
+ async execute({ guild_id, user_id, role_id }: { guild_id: string; user_id: string; role_id: string }, context) {
17
+ const client = requireDiscordGatewayClient(context.$client);
18
+ const guild = await client.guilds.fetch(guild_id);
19
+ const member = await guild.members.fetch(user_id) as {
20
+ roles: { remove(id: string): Promise<unknown> };
20
21
  };
21
- const success = await endpoint.removeRole(guild_id, user_id, role_id);
22
+ await member.roles.remove(role_id);
23
+ const success = true;
22
24
  return { success, message: success ? `已移除用户 ${user_id} 的角色` : '操作失败' };
23
25
  },
24
26
  });
@@ -1,11 +1,10 @@
1
1
  import { defineAgentTool } from '@zhin.js/agent/tools';
2
2
  import { z } from 'zod';
3
- import { getDiscordAgentDeps } from '../../src/discord-agent-deps.js';
3
+ import { requireDiscordGatewayClient } from '../../src/client.js';
4
4
 
5
- export default defineAgentTool<{ endpoint_id: string; channel_id: string; title?: string; description?: string; color?: number; url?: string; fields?: string }>({
5
+ export default defineAgentTool<{ channel_id: string; title?: string; description?: string; color?: number; url?: string; fields?: string }>({
6
6
  description: '发送 Discord 富文本嵌入消息(Embed)',
7
7
  inputSchema: z.object({
8
- endpoint_id: z.string().describe('Endpoint 名称'),
9
8
  channel_id: z.string().describe('频道 ID'),
10
9
  title: z.string().optional().describe('Embed 标题'),
11
10
  description: z.string().optional().describe('Embed 描述'),
@@ -13,12 +12,10 @@ export default defineAgentTool<{ endpoint_id: string; channel_id: string; title?
13
12
  url: z.string().optional().describe('标题链接(可选)'),
14
13
  fields: z.string().optional().describe('字段,JSON 格式: [{"name":"k","value":"v","inline":false}]'),
15
14
  }),
16
- platforms: ['discord'],
15
+ adapter: 'discord',
17
16
  tags: ['discord'],
18
- async execute({ endpoint_id, channel_id, title, description, color, url, fields }: { endpoint_id: string; channel_id: string; title?: string; description?: string; color?: number; url?: string; fields?: string }) {
19
- const endpoint = getDiscordAgentDeps().getGatewayEndpoint(endpoint_id) as {
20
- sendEmbed: (channelId: string, embed: Record<string, unknown>) => Promise<{ id: string }>;
21
- };
17
+ async execute({ channel_id, title, description, color, url, fields }: { channel_id: string; title?: string; description?: string; color?: number; url?: string; fields?: string }, context) {
18
+ const client = requireDiscordGatewayClient(context.$client);
22
19
  const embedData: Record<string, unknown> = {};
23
20
  if (title) embedData.title = title;
24
21
  if (description) embedData.description = description;
@@ -31,7 +28,11 @@ export default defineAgentTool<{ endpoint_id: string; channel_id: string; title?
31
28
  return { success: false, message: 'fields 格式错误,应为 JSON 数组' };
32
29
  }
33
30
  }
34
- const msg = await endpoint.sendEmbed(channel_id, embedData);
31
+ const channel = await client.channels.fetch(channel_id);
32
+ if (!channel?.isTextBased() || !channel.send) {
33
+ throw new Error(`Channel ${channel_id} 不是文本频道`);
34
+ }
35
+ const msg = await channel.send({ embeds: [embedData] } as never);
35
36
  return { success: true, message_id: msg.id, message: 'Embed 已发送' };
36
37
  },
37
38
  });
@@ -0,0 +1,16 @@
1
+ import type { DiscordRestClient } from './endpoint.js';
2
+ import type { DiscordClientTransport } from './gateway.js';
3
+ /** Exact Client variants produced by the Gateway and Interactions Endpoints. */
4
+ export type DiscordClient = DiscordClientTransport | DiscordRestClient;
5
+ export type DiscordClientEventMap = Record<string, unknown>;
6
+ /** Narrow an adapter Client for Gateway-only SDK operations. */
7
+ export declare function requireDiscordGatewayClient(client: DiscordClient): DiscordClientTransport;
8
+ declare module '@zhin.js/feature-kit' {
9
+ interface AdapterClientRegistry {
10
+ readonly discord: {
11
+ readonly client: DiscordClient;
12
+ readonly events: DiscordClientEventMap;
13
+ };
14
+ }
15
+ }
16
+ export declare const discordClient: import("@zhin.js/adapter").EndpointClientToken<DiscordClient, DiscordClientEventMap>;
package/lib/client.js ADDED
@@ -0,0 +1,8 @@
1
+ import { defineEndpointClient } from 'zhin.js/adapter';
2
+ /** Narrow an adapter Client for Gateway-only SDK operations. */
3
+ export function requireDiscordGatewayClient(client) {
4
+ if ('guilds' in client && 'channels' in client)
5
+ return client;
6
+ throw new Error('This Discord tool requires a Gateway Endpoint Client');
7
+ }
8
+ export const discordClient = defineEndpointClient('discord');
@@ -1 +1 @@
1
- export declare const discordEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage>>>;
1
+ export declare const discordEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
package/lib/endpoint.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { EndpointContentPort, EndpointControl, EndpointInstance, EndpointManagement, EndpointSendRequest } from 'zhin.js/adapter';
2
- import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
1
+ import { Endpoint } from 'zhin.js/adapter';
2
+ import type { EndpointContentPort, EndpointControl, EndpointManagement, EndpointSendRequest } from 'zhin.js/adapter';
3
3
  import type { HttpHost } from '@zhin.js/host-http';
4
4
  import { type MessageRef } from '@zhin.js/im-contract';
5
5
  import type { CapabilityId } from 'zhin.js';
@@ -8,18 +8,18 @@ import { type DiscordButtonInbound, type DiscordInboundMessage, type ResolvedDis
8
8
  export type { CreateDiscordClient, DiscordClientTransport, } from './gateway.js';
9
9
  export interface DiscordEndpointOptions {
10
10
  readonly id: CapabilityId;
11
- readonly gateway: MessageGateway;
12
- readonly sideEvents?: SideEventGateway;
13
11
  readonly config: ResolvedDiscordGatewayConfig;
14
12
  readonly createClient?: CreateDiscordClient;
15
13
  readonly fetch?: typeof globalThis.fetch;
16
14
  }
17
- export declare class DiscordGatewayEndpoint implements EndpointInstance {
15
+ export declare class DiscordGatewayEndpoint extends Endpoint<DiscordClientTransport> {
18
16
  #private;
19
17
  readonly management: EndpointManagement;
20
18
  readonly control: EndpointControl;
21
19
  readonly content: EndpointContentPort;
22
20
  constructor(options: DiscordEndpointOptions);
21
+ /** The actual discord.js-compatible client used by this connection. */
22
+ get client(): DiscordClientTransport;
23
23
  start(): Promise<void>;
24
24
  open(): void;
25
25
  close(): void;
@@ -30,37 +30,27 @@ export declare class DiscordGatewayEndpoint implements EndpointInstance {
30
30
  admit(msg: DiscordInboundMessage): void;
31
31
  /** Test / internal: admit a button interaction when open. */
32
32
  admitButton(interaction: DiscordButtonInbound): void;
33
- addRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
34
- removeRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
35
- getRoles(guildId: string): Promise<unknown[]>;
36
- createThread(channelId: string, name: string, messageId?: string, autoArchiveDuration?: number): Promise<{
37
- id: string;
38
- }>;
39
- addReaction(channelId: string, messageId: string, emoji: string): Promise<void>;
40
- sendEmbed(channelId: string, embedData: Record<string, unknown>): Promise<{
41
- id: string;
42
- }>;
43
- createForumPost(channelId: string, name: string, content: string, tags?: string[]): Promise<{
44
- id: string;
45
- }>;
46
- kickMember(guildId: string, userId: string, reason?: string): Promise<boolean>;
47
- banMember(guildId: string, userId: string, reason?: string): Promise<boolean>;
48
- unbanMember(guildId: string, userId: string, reason?: string): Promise<boolean>;
49
- timeoutMember(guildId: string, userId: string, duration?: number, reason?: string): Promise<boolean>;
50
- setNickname(guildId: string, userId: string, nickname: string): Promise<boolean>;
51
- getMembers(guildId: string, limit?: number): Promise<unknown[]>;
52
- getGuildInfo(guildId: string): Promise<unknown>;
53
33
  }
54
34
  export interface DiscordInteractionsEndpointOptions {
55
35
  readonly id: CapabilityId;
56
- readonly gateway: MessageGateway;
57
- readonly sideEvents?: SideEventGateway;
58
36
  readonly http: HttpHost;
59
37
  readonly config: ResolvedDiscordInteractionsConfig;
60
38
  readonly fetch?: typeof globalThis.fetch;
61
39
  }
62
- export declare class DiscordInteractionsEndpoint implements EndpointInstance {
40
+ /** Minimal Discord REST client used when Gateway is intentionally disabled. */
41
+ export declare class DiscordRestClient {
42
+ readonly token: string;
43
+ readonly fetch: typeof globalThis.fetch;
44
+ constructor(token: string, fetch?: typeof globalThis.fetch);
45
+ request<T = unknown>(method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE', path: string, body?: unknown): Promise<T>;
46
+ createMessage(channelId: string, body: unknown): Promise<{
47
+ id?: string;
48
+ }>;
49
+ deleteMessage(channelId: string, messageId: string): Promise<void>;
50
+ }
51
+ export declare class DiscordInteractionsEndpoint extends Endpoint<DiscordRestClient> {
63
52
  #private;
53
+ readonly client: DiscordRestClient;
64
54
  readonly control: EndpointControl;
65
55
  readonly content: EndpointContentPort;
66
56
  constructor(options: DiscordInteractionsEndpointOptions);
@@ -73,12 +63,10 @@ export declare class DiscordInteractionsEndpoint implements EndpointInstance {
73
63
  send({ conversation, payload }: EndpointSendRequest): Promise<string>;
74
64
  recallMessage(message: MessageRef): Promise<void>;
75
65
  admit(msg: DiscordInboundMessage): void;
66
+ admitPlatform(event: Record<string, unknown>): void;
76
67
  }
77
68
  /**
78
69
  * DiscordGatewayEndpoint 的 EndpointManagement 语义端口(参照 qq 的工厂模式)。
79
70
  * 数据源为 discord.js SDK 缓存:guilds.cache / guild.channels.cache / guild.members。
80
71
  */
81
- export declare function createDiscordEndpointManagement(endpoint: {
82
- getClient(): DiscordClientTransport;
83
- getMembers(guildId: string): Promise<unknown[]>;
84
- }): EndpointManagement;
72
+ export declare function createDiscordEndpointManagement(requireClient: () => DiscordClientTransport): EndpointManagement;