@zhin.js/adapter-slack 4.0.1 → 4.1.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +77 -160
  3. package/adapters/slack.ts +34 -0
  4. package/{skills/slack/SKILL.md → agent/skills/slack.md} +2 -0
  5. package/agent/tools/add_reaction.ts +26 -0
  6. package/agent/tools/archive_channel.ts +24 -0
  7. package/agent/tools/edit_message.ts +28 -0
  8. package/agent/tools/invite_to_channel.ts +26 -0
  9. package/agent/tools/pin_message.ts +26 -0
  10. package/agent/tools/remove_reaction.ts +26 -0
  11. package/agent/tools/set_purpose.ts +26 -0
  12. package/agent/tools/set_topic.ts +26 -0
  13. package/agent/tools/unarchive.ts +24 -0
  14. package/agent/tools/unpin_message.ts +26 -0
  15. package/agent/tools/user_info.ts +31 -0
  16. package/lib/endpoint.d.ts +133 -94
  17. package/lib/endpoint.js +270 -612
  18. package/lib/index.d.ts +11 -10
  19. package/lib/index.js +11 -252
  20. package/lib/markdown-to-mrkdwn.d.ts +9 -0
  21. package/lib/markdown-to-mrkdwn.js +121 -0
  22. package/lib/mrkdwn-to-markdown.d.ts +4 -0
  23. package/lib/mrkdwn-to-markdown.js +30 -0
  24. package/lib/platform-permit.d.ts +1 -2
  25. package/lib/platform-permit.js +4 -2
  26. package/lib/protocol.d.ts +143 -0
  27. package/lib/protocol.js +225 -0
  28. package/lib/slack-agent-deps.d.ts +28 -0
  29. package/lib/slack-agent-deps.js +30 -0
  30. package/lib/slack-inbound-filter.d.ts +12 -0
  31. package/lib/slack-inbound-filter.js +46 -0
  32. package/lib/slack-message-ref.d.ts +7 -0
  33. package/lib/slack-message-ref.js +17 -0
  34. package/lib/slack-outbound.d.ts +24 -0
  35. package/lib/slack-outbound.js +109 -0
  36. package/lib/slack-reaction.d.ts +1 -0
  37. package/lib/slack-reaction.js +26 -0
  38. package/lib/slack-response-url.d.ts +5 -0
  39. package/lib/slack-response-url.js +16 -0
  40. package/lib/webhook.d.ts +14 -0
  41. package/lib/webhook.js +69 -0
  42. package/package.json +53 -14
  43. package/plugin.ts +13 -0
  44. package/schema.json +38 -0
  45. package/src/endpoint.ts +339 -647
  46. package/src/index.ts +65 -277
  47. package/src/markdown-to-mrkdwn.ts +117 -0
  48. package/src/mrkdwn-to-markdown.ts +29 -0
  49. package/src/platform-permit.ts +1 -2
  50. package/src/protocol.ts +380 -0
  51. package/src/slack-agent-deps.ts +57 -0
  52. package/src/slack-inbound-filter.ts +60 -0
  53. package/src/slack-message-ref.ts +18 -0
  54. package/src/slack-outbound.ts +167 -0
  55. package/src/slack-reaction.ts +23 -0
  56. package/src/slack-response-url.ts +26 -0
  57. package/src/webhook.ts +103 -0
  58. package/lib/adapter.d.ts +0 -19
  59. package/lib/adapter.d.ts.map +0 -1
  60. package/lib/adapter.js +0 -46
  61. package/lib/adapter.js.map +0 -1
  62. package/lib/endpoint.d.ts.map +0 -1
  63. package/lib/endpoint.js.map +0 -1
  64. package/lib/index.d.ts.map +0 -1
  65. package/lib/index.js.map +0 -1
  66. package/lib/platform-permit.d.ts.map +0 -1
  67. package/lib/platform-permit.js.map +0 -1
  68. package/lib/segment-mapper.d.ts +0 -2
  69. package/lib/segment-mapper.d.ts.map +0 -1
  70. package/lib/segment-mapper.js +0 -2
  71. package/lib/segment-mapper.js.map +0 -1
  72. package/lib/types.d.ts +0 -17
  73. package/lib/types.d.ts.map +0 -1
  74. package/lib/types.js +0 -2
  75. package/lib/types.js.map +0 -1
  76. package/plugin.yml +0 -3
  77. package/src/adapter.ts +0 -54
  78. package/src/segment-mapper.ts +0 -1
  79. package/src/types.ts +0 -18
  80. /package/{skills/slack → agent}/PERMITS.md +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,64 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - cc5c94d: 约定式插件运行时迁移(breaking):插件与适配器由 `usePlugin()` / `extends Adapter` 迁移为 `definePlugin` / `defineAdapter` + `plugin.ts` + 约定目录(`adapters/`、`commands/`、`components/`、`tools/` 等)。
8
+
9
+ - 新增约定式运行时包:`@zhin.js/plugin-runtime`、`@zhin.js/adapter`、`@zhin.js/runtime`、`@zhin.js/host-http`(首版 1.0.0 走 init-publish,不在本 changeset 内 bump)。
10
+ - 全部 20 个平台适配器改为约定式 `defineAdapter`,旧 `usePlugin` / `extends Adapter` / `segment-mapper` 生产入口已删除;onebot11 反向 WSS、onebot12 webhook/wss、milky sse/webhook/wss、satori webhook、kook webhook、qq webhook/middleware 等 slice 1 推迟的连接模式已补齐。
11
+ - 游戏 / 工具 / 服务插件同步迁移到约定目录结构。
12
+ - CLI 增加 plugin-runtime host installer(http/database/outbound/schedule/console 等)。
13
+
14
+ 后续加固(同批):
15
+
16
+ - CLI:`zhin runtime start --daemon`(pidfile/崩溃拉起/风暴保护),orphan watchdog 防僵尸进程;legacy `zhin dev` / `zhin start` 已移除(含 `zhin restart`),`zhin stop` 兼容新 daemon。
17
+ - 安全:builtin 工具统一走 `security/policy-facade.ts` 的 `runToolPolicies`(声明式策略表,deny 优先);审计日志 close flush + 背压队列;`splitCompoundCommand` 引号感知、`extractCommandName` 去引号堵绕过。
18
+ - 日志:Logger 双堆栈修复、本地时区、`getLogger` 挂树(`setLevel` 递归生效)、第三方库(log4js/discord)桥接、启动人读总结。
19
+ - 结构:`plugins/games/shared` 迁为 `packages/game-kit`(`@zhin.js/game-kit`);死目录 `plugins/adapters/common` 删除。
20
+ - 脚手架:`create-zhin-app` / `zhin new` / scaffold-wizard 生成物改为 Plugin Runtime 形态(minimal-bot 同构,新配置格式)。
21
+ - Console:endpoint.list 真实名称与 phase、schema:get-all 按 instanceKey 映射、db:\* 接 DatabaseHost。
22
+
23
+ 注:按仓库发布惯例(见 1bb345dd2),本次 breaking 迁移统一使用 patch,避免 zhin.js 5.0 级联。
24
+
25
+ - 447f3e2: 迁移缺口修复(legacy 功能对齐):
26
+
27
+ - html 段出站规范化:经 `@zhin.js/html-renderer` 渲染为 image 段(sandbox 豁免、无渲染器时降级文本),修复真实平台 `[object Object]`。
28
+ - 群聊 @ 触发 AI:适配器入站标注 `metadata.mentioned`(icqq/qq/slack/onebot11/onebot12/napcat/milky/discord/telegram/kook/dingtalk/satori),`matchAiTrigger` 补齐 ignorePrefixes/respondToAt/respondToPrivate/keywords(默认值与 legacy 对齐)。
29
+ - im_transcripts 全量流水恢复写入(chat_history 工具可用);群聊旁听上下文回迁。
30
+ - `ai.trigger.timeout/thinkingMessage/errorTemplate` 生效;masters/trusted 角色解析对齐 legacy。
31
+ - `Message.sender` 统一为用户 ID(onebot11/12、napcat、milky 原误传显示名);quote_id 经 metadata 接入 AI 引用上下文。
32
+
33
+ - Updated dependencies [16ec4e8]
34
+ - Updated dependencies [cc5c94d]
35
+ - Updated dependencies [447f3e2]
36
+ - @zhin.js/core@1.3.5
37
+ - @zhin.js/agent@1.0.4
38
+ - @zhin.js/host-http@1.0.1
39
+ - zhin.js@4.1.3
40
+ - @zhin.js/logger@1.0.75
41
+ - @zhin.js/plugin-runtime@1.0.1
42
+ - @zhin.js/adapter@1.0.1
43
+
44
+ ## 4.1.0
45
+
46
+ ### Minor Changes
47
+
48
+ - 872c583: Slack 适配器 Phase 1/2:mrkdwn 出站、长消息切分、斜杠/按钮 ephemeral 反馈、入站 mrkdwn→Markdown、editMessage 对齐 core。
49
+
50
+ Logger 表格日志与 string-width 列宽;Agent AI Handler 框线表格与 introspection/MCP 导出;Core side-event 归一化;Schedule 时区规划;多适配器 side-event 与 API surface 更新。
51
+
52
+ ### Patch Changes
53
+
54
+ - 872c583: fix: 代码格式优化
55
+ - Updated dependencies [872c583]
56
+ - Updated dependencies [872c583]
57
+ - @zhin.js/agent@1.0.3
58
+ - @zhin.js/host-router@2.0.3
59
+ - @zhin.js/logger@1.0.74
60
+ - zhin.js@4.1.2
61
+
3
62
  ## 4.0.1
4
63
 
5
64
  ### Patch Changes
package/README.md CHANGED
@@ -1,192 +1,109 @@
1
1
  # @zhin.js/adapter-slack
2
2
 
3
- Slack adapter for zhin.js framework.
3
+ Zhin.js Slack 适配器(Plugin Runtime),优先 Socket Mode,也可经 Runtime Host HTTP Events API 收发消息。
4
4
 
5
- ## Installation
5
+ ## 功能
6
+
7
+ - **Socket Mode**(默认):WebSocket 长连接,无需公网 URL
8
+ - **HTTP Events API**:`httpHostToken` POST(签名验证),**非** legacy host-router/Koa
9
+ - 入站经 `messageGatewayToken`;出站 `send({ target, payload })` → `chat.postMessage` / Block Kit
10
+ - 约定式 `defineAdapter` / `definePlugin`(无需 `usePlugin`)
11
+ - Block Kit 按钮、斜杠命令、消息编辑、表情反应等(见 `agent/tools/`)
12
+
13
+ ## 安装
6
14
 
7
15
  ```bash
8
16
  pnpm add @zhin.js/adapter-slack
9
17
  ```
10
18
 
11
- ## Configuration
19
+ ## Plugin Runtime
20
+
21
+ - `@zhin.js/adapter` — 约定式 `adapters/slack.ts`(`defineAdapter`)
22
+ - `@zhin.js/core` — `messageGatewayToken` 入站/出站
23
+ - `@zhin.js/host-http` — 仅 HTTP 模式需要 `httpHostToken` 注册 Events 路由
24
+ - `@zhin.js/plugin-runtime` — `plugin.ts`(`definePlugin`)
25
+ - 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
26
+
27
+ 入站:`gateway.receive({ adapter, target: channelId, content: text, sender, metadata })`
28
+ 出站:`send({ target, payload })` → Web API(`target` 可为 `channel` 或 `channel:thread_ts`)
29
+
30
+ ### 平台权限(platform permit)
12
31
 
13
- 通过 **`socketMode`** 选择连接方式(默认 `true` 时为 Socket Mode)。
32
+ - `plugin.ts` 已注册 checker,Runtime Tool 权限统一经 Core `canAccessTool()`;当前 Slack 入站没有可靠 sender role 时,受限工具按 fail-closed 拒绝,不会静默放行。
14
33
 
15
- ### 模式对比
34
+ ## 模式对比
16
35
 
17
36
  | 模式 | `socketMode` | 适用场景 | 额外字段 |
18
37
  |------|--------------|----------|----------|
19
- | **Socket Mode** | `true`(推荐本地/内网) | 无需公网 URL,WebSocket 长连接 | `appToken`(`xapp-...`) |
20
- | **HTTP Events** | `false` | 生产环境,有公网 HTTPS | `port`(Bolt 监听端口) |
21
-
22
- #### HTTP 模式前置条件
23
-
24
- - Slack App 中配置 **Event Subscriptions** 的 Request URL(须公网 HTTPS 可达)
25
- - 启用对应 Endpoint Events(`message.*`、`app_mention` 等)
26
- - 防火墙 / 反向代理放行 `port`
27
- - **不需要** `@zhin.js/host-router`(由 `@slack/bolt` 自行监听)
28
-
29
- ### Socket Mode (Recommended for Development)
30
-
31
- ```typescript
32
- import { defineConfig } from 'zhin.js'
33
-
34
- export default defineConfig({
35
- endpoints: [
36
- {
37
- name: 'my-slack-bot',
38
- context: 'slack',
39
- token: 'xoxb-your-bot-token',
40
- signingSecret: 'your-signing-secret',
41
- appToken: 'xapp-your-app-token',
42
- socketMode: true
43
- }
44
- ]
45
- })
38
+ | **Socket Mode**(默认) | `true` | 本地/内网,无需公网 URL | `appToken`(`xapp-...`) |
39
+ | **HTTP Events** | `false` | 生产环境有公网 HTTPS | `signingSecret` + Runtime Host |
40
+
41
+ ## 最小配置(Socket Mode)
42
+
43
+ ```yaml
44
+ # zhin.config.yml(Plugin Runtime)
45
+ plugins:
46
+ slack:
47
+ name: my-slack-bot
48
+ token: ${SLACK_BOT_TOKEN}
49
+ appToken: ${SLACK_APP_TOKEN}
50
+ socketMode: true # 默认 true,可省略
46
51
  ```
47
52
 
48
- ### HTTP Mode (For Production with Public URL)
49
-
50
- ```typescript
51
- import { defineConfig } from 'zhin.js'
52
-
53
- export default defineConfig({
54
- endpoints: [
55
- {
56
- name: 'my-slack-bot',
57
- context: 'slack',
58
- token: 'xoxb-your-bot-token',
59
- signingSecret: 'your-signing-secret',
60
- socketMode: false,
61
- port: 3000
62
- }
63
- ]
64
- })
65
- ```
53
+ ## HTTP Events 配置
66
54
 
67
- ## Features
68
-
69
- - ✅ Send and receive text messages
70
- - ✅ Support for rich media (images, files)
71
- - ✅ Message formatting (Slack mrkdwn)
72
- - ✅ Reply to messages and threads
73
- - ✅ Mentions (@user, #channel)
74
- - Links and attachments
75
- - ✅ Socket Mode and HTTP mode
76
- - ✅ Private messages and channels
77
-
78
- ## Setting Up Your Slack App
79
-
80
- 1. Go to [Slack API](https://api.slack.com/apps)
81
- 2. Create a new app
82
- 3. Add Endpoint Token Scopes:
83
- - `chat:write` - Send messages
84
- - `chat:write.public` - Send messages to public channels
85
- - `channels:read` - View basic channel info
86
- - `channels:history` - View messages in channels
87
- - `groups:read` - View basic private channel info
88
- - `groups:history` - View messages in private channels
89
- - `im:read` - View basic direct message info
90
- - `im:history` - View messages in direct messages
91
- - `mpim:read` - View basic group direct message info
92
- - `mpim:history` - View messages in group direct messages
93
- - `users:read` - View user info
94
- - `files:read` - View files
95
- - `files:write` - Upload files
96
- 4. Enable Socket Mode (if using Socket Mode):
97
- - Go to Socket Mode settings
98
- - Enable Socket Mode
99
- - Generate an app-level token with `connections:write` scope
100
- 5. Subscribe to events:
101
- - `message.channels` - Messages in public channels
102
- - `message.groups` - Messages in private channels
103
- - `message.im` - Direct messages
104
- - `message.mpim` - Group direct messages
105
- - `app_mention` - When the bot is mentioned
106
- 6. Install the app to your workspace
107
- 7. Copy the Endpoint User OAuth Token (`xoxb-...`)
108
- 8. Copy the Signing Secret
109
- 9. Copy the App-Level Token (`xapp-...`) if using Socket Mode
110
-
111
- ## Usage Examples
112
-
113
- ### Basic Message Handling
114
-
115
- ```typescript
116
- import { usePlugin, MessageCommand } from 'zhin.js'
117
-
118
- const { addCommand } = usePlugin()
119
-
120
- addCommand(new MessageCommand('hello')
121
- .action(async (message) => {
122
- return 'Hello from Slack!'
123
- })
124
- )
55
+ ```yaml
56
+ plugins:
57
+ slack:
58
+ name: my-slack-bot
59
+ token: ${SLACK_BOT_TOKEN}
60
+ signingSecret: ${SLACK_SIGNING_SECRET}
61
+ socketMode: false
62
+ webhookPath: /slack/events # 可选,默认 /slack/events
125
63
  ```
126
64
 
127
- ### Send Rich Messages
128
-
129
- ```typescript
130
- addCommand(new MessageCommand('info')
131
- .action(async (message) => {
132
- return [
133
- { type: 'text', data: { text: '*Bold* and _italic_ text\n' } },
134
- { type: 'link', data: { url: 'https://slack.com', text: 'Visit Slack' } }
135
- ]
136
- })
137
- )
138
- ```
65
+ 根插件 `zhin.plugins`(或项目图)需引用 `@zhin.js/adapter-slack`(`instanceKey: slack`)。
66
+ HTTP 模式下 Runtime Host(`http`)须已 listen;Slack App 的 Event Subscriptions / Interactivity / Slash Commands Request URL 指向 `https://your-domain/slack/events`。
139
67
 
140
- ### Mention Users
141
-
142
- ```typescript
143
- addCommand(new MessageCommand('mention <userId:text>')
144
- .action(async (message, result) => {
145
- return [
146
- { type: 'at', data: { id: result.params.userId } },
147
- { type: 'text', data: { text: ' Hello!' } }
148
- ]
149
- })
150
- )
151
- ```
68
+ ## 环境变量
152
69
 
153
- ### Reply in Thread
154
-
155
- ```typescript
156
- addCommand(new MessageCommand('thread')
157
- .action(async (message) => {
158
- // Reply in a thread by passing the message timestamp
159
- await message.$reply('This is a threaded reply!', true)
160
- })
161
- )
162
- ```
70
+ | 变量 | 说明 |
71
+ |------|------|
72
+ | `SLACK_BOT_TOKEN` / `SLACK_TOKEN` | Bot User OAuth Token(`xoxb-...`) |
73
+ | `SLACK_APP_TOKEN` | App-Level Token(Socket Mode,`xapp-...`) |
74
+ | `SLACK_SIGNING_SECRET` | Signing Secret(HTTP 模式) |
75
+ | `SLACK_BOT_NAME` | 可选 endpoint 名称 |
163
76
 
164
- ## Slack-Specific Features
77
+ ## 消息格式
165
78
 
166
- ### Slack Formatting
79
+ ### 出站(Markdown → mrkdwn)
167
80
 
168
- Slack uses mrkdwn format:
169
- - `*bold*` for **bold**
170
- - `_italic_` for *italic*
171
- - `~strike~` for ~~strikethrough~~
172
- - `` `code` `` for `code`
173
- - `> quote` for blockquotes
81
+ 通用 Markdown(如 `**粗体**`)会转换为 Slack mrkdwn,并通过 Block Kit `section` 发送。
174
82
 
175
- ### User and Channel Mentions
83
+ ### 入站(mrkdwn Markdown)
176
84
 
177
- The adapter automatically converts:
178
- - `<@U12345678>` to user mentions
179
- - `<#C12345678>` to channel mentions
85
+ | Slack mrkdwn | 通用 Markdown |
86
+ |--------------|---------------|
87
+ | `*bold*` | `**bold**` |
88
+ | `_italic_` | `*italic*` |
89
+ | `~strike~` | `~~strike~~` |
90
+ | `<url\|text>` | `[text](url)` |
180
91
 
181
- ### File Uploads
92
+ ## AI 工具
182
93
 
183
- Upload files using the `file` segment type with a local file path.
94
+ | 类别 | 路径 |
95
+ |------|------|
96
+ | Permit 词汇 | `agent/PERMITS.md` |
97
+ | 平台工具 | `agent/tools/`(邀请、话题、反应、置顶、编辑等) |
98
+ | 技能说明 | `agent/skills/slack.md` |
184
99
 
185
- ## Limitations
100
+ ## 限制
186
101
 
187
- - Message recall requires channel information (not available from message ID alone)
188
- - Some Slack features like interactive components require additional setup
102
+ - 入站 mrkdwn Markdown 为启发式转换
103
+ - Modals / Select menus 暂不支持
104
+ - OAuth 安装流程 — 暂不支持
105
+ - 旧 `usePlugin` / `extends Adapter` / host-router 生产入口已删除
189
106
 
190
- ## License
107
+ ## 许可证
191
108
 
192
109
  MIT
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Convention entry: discover `adapters/slack.ts` → defineAdapter.
3
+ */
4
+ import { defineAdapter } from '@zhin.js/adapter';
5
+ import { messageGatewayToken } from '@zhin.js/core/runtime';
6
+ import { httpHostToken } from '@zhin.js/host-http';
7
+ import { SlackEndpoint } from '../src/endpoint.js';
8
+ import {
9
+ resolveSlackConfig,
10
+ type SlackAdapterConfig,
11
+ } from '../src/protocol.js';
12
+
13
+ export { SlackEndpoint } from '../src/endpoint.js';
14
+ export type { SlackEndpointOptions, SlackSocketLike, SlackWebClientLike } from '../src/endpoint.js';
15
+
16
+ export default defineAdapter<SlackAdapterConfig>({
17
+ capabilities: ['inbound', 'outbound'],
18
+ create(context) {
19
+ const config = resolveSlackConfig(context.config);
20
+ if (config.mode === 'http') {
21
+ return new SlackEndpoint({
22
+ id: context.id,
23
+ gateway: context.use(messageGatewayToken),
24
+ http: context.use(httpHostToken),
25
+ config,
26
+ });
27
+ }
28
+ return new SlackEndpoint({
29
+ id: context.id,
30
+ gateway: context.use(messageGatewayToken),
31
+ config,
32
+ });
33
+ },
34
+ });
@@ -34,6 +34,7 @@ tools:
34
34
  - slack_user_info
35
35
  - slack_set_purpose
36
36
  - slack_unarchive
37
+ - slack_edit_message
37
38
  - slack_kick_member
38
39
  - slack_set_group_name
39
40
  - slack_list_members
@@ -83,6 +84,7 @@ Slack 频道有两个元信息字段:
83
84
  | `slack_unpin_message` | 取消置顶 | — |
84
85
  | `slack_add_reaction` | 添加表情反应 | — |
85
86
  | `slack_remove_reaction` | 移除表情反应 | — |
87
+ | `slack_edit_message` | 编辑消息 | 通过 chat.update 修改已发消息 |
86
88
 
87
89
  ## 易错点
88
90
 
@@ -0,0 +1,26 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
4
+
5
+ export default defineAgentTool<{
6
+ endpoint_id: string;
7
+ channel: string;
8
+ timestamp: string;
9
+ emoji: string;
10
+ }>({
11
+ description: '给 Slack 消息添加表情反应',
12
+ inputSchema: z.object({
13
+ endpoint_id: z.string().describe('Endpoint 名称'),
14
+ channel: z.string().describe('频道 ID'),
15
+ timestamp: z.string().describe('消息时间戳'),
16
+ emoji: z.string().describe('表情名称(不含冒号)'),
17
+ }),
18
+ platforms: ['slack'],
19
+ tags: ['slack'],
20
+ async execute({ endpoint_id, channel, timestamp, emoji }) {
21
+ const { getEndpoint } = getSlackAgentDeps();
22
+ const endpoint = getEndpoint(endpoint_id);
23
+ const success = await endpoint.addReaction(channel, timestamp, emoji);
24
+ return { success, message: success ? `已添加反应 :${emoji}:` : '操作失败' };
25
+ },
26
+ });
@@ -0,0 +1,24 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { platformPermit } from '../../src/platform-permit.js';
4
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
5
+
6
+ export default defineAgentTool<{
7
+ endpoint_id: string;
8
+ channel: string;
9
+ }>({
10
+ description: '归档 Slack 频道',
11
+ inputSchema: z.object({
12
+ endpoint_id: z.string().describe('Endpoint 名称'),
13
+ channel: z.string().describe('频道 ID'),
14
+ }),
15
+ platforms: ['slack'],
16
+ tags: ['slack'],
17
+ permissions: [platformPermit('workspace_admin')],
18
+ async execute({ endpoint_id, channel }) {
19
+ const { getEndpoint } = getSlackAgentDeps();
20
+ const endpoint = getEndpoint(endpoint_id);
21
+ const success = await endpoint.archiveChannel(channel);
22
+ return { success, message: success ? '已归档频道' : '操作失败' };
23
+ },
24
+ });
@@ -0,0 +1,28 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
4
+
5
+ export default defineAgentTool<{
6
+ endpoint_id: string;
7
+ channel: string;
8
+ message_ts: string;
9
+ text: string;
10
+ }>({
11
+ description: '编辑 Slack 消息',
12
+ inputSchema: z.object({
13
+ endpoint_id: z.string().describe('Endpoint 名称'),
14
+ channel: z.string().describe('频道 ID'),
15
+ message_ts: z.string().describe('消息时间戳'),
16
+ text: z.string().describe('新的消息文本'),
17
+ }),
18
+ platforms: ['slack'],
19
+ tags: ['slack'],
20
+ async execute({ endpoint_id, channel, message_ts, text }) {
21
+ const { getEndpoint } = getSlackAgentDeps();
22
+ const endpoint = getEndpoint(endpoint_id);
23
+ await endpoint.editMessage(channel, message_ts, [
24
+ { type: 'text', data: { text } },
25
+ ]);
26
+ return { success: true, message: '消息已编辑' };
27
+ },
28
+ });
@@ -0,0 +1,26 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { platformPermit } from '../../src/platform-permit.js';
4
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
5
+
6
+ export default defineAgentTool<{
7
+ endpoint_id: string;
8
+ channel: string;
9
+ users: string;
10
+ }>({
11
+ description: '邀请用户加入 Slack 频道',
12
+ inputSchema: z.object({
13
+ endpoint_id: z.string().describe('Endpoint 名称'),
14
+ channel: z.string().describe('频道 ID'),
15
+ users: z.string().describe('用户 ID 列表(逗号分隔)'),
16
+ }),
17
+ platforms: ['slack'],
18
+ tags: ['slack'],
19
+ permissions: [platformPermit('channel_manager')],
20
+ async execute({ endpoint_id, channel, users }) {
21
+ const { getEndpoint } = getSlackAgentDeps();
22
+ const endpoint = getEndpoint(endpoint_id);
23
+ const success = await endpoint.inviteToChannel(channel, users.split(','));
24
+ return { success, message: success ? '已邀请用户加入频道' : '操作失败' };
25
+ },
26
+ });
@@ -0,0 +1,26 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { platformPermit } from '../../src/platform-permit.js';
4
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
5
+
6
+ export default defineAgentTool<{
7
+ endpoint_id: string;
8
+ channel: string;
9
+ timestamp: string;
10
+ }>({
11
+ description: '置顶 Slack 消息',
12
+ inputSchema: z.object({
13
+ endpoint_id: z.string().describe('Endpoint 名称'),
14
+ channel: z.string().describe('频道 ID'),
15
+ timestamp: z.string().describe('消息时间戳'),
16
+ }),
17
+ platforms: ['slack'],
18
+ tags: ['slack'],
19
+ permissions: [platformPermit('channel_manager')],
20
+ async execute({ endpoint_id, channel, timestamp }) {
21
+ const { getEndpoint } = getSlackAgentDeps();
22
+ const endpoint = getEndpoint(endpoint_id);
23
+ const success = await endpoint.pinMessage(channel, timestamp);
24
+ return { success, message: success ? '已置顶消息' : '操作失败' };
25
+ },
26
+ });
@@ -0,0 +1,26 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
4
+
5
+ export default defineAgentTool<{
6
+ endpoint_id: string;
7
+ channel_id: string;
8
+ timestamp: string;
9
+ name: string;
10
+ }>({
11
+ description: '移除 Slack 消息上的表情反应',
12
+ inputSchema: z.object({
13
+ endpoint_id: z.string().describe('Endpoint 名称'),
14
+ channel_id: z.string().describe('频道 ID'),
15
+ timestamp: z.string().describe('消息时间戳'),
16
+ name: z.string().describe('表情名称(如 thumbsup、heart)'),
17
+ }),
18
+ platforms: ['slack'],
19
+ tags: ['slack'],
20
+ async execute({ endpoint_id, channel_id, timestamp, name }) {
21
+ const { getEndpoint } = getSlackAgentDeps();
22
+ const endpoint = getEndpoint(endpoint_id);
23
+ const success = await endpoint.removeReaction(channel_id, timestamp, name);
24
+ return { success, message: success ? `已移除反应 :${name}:` : '操作失败' };
25
+ },
26
+ });
@@ -0,0 +1,26 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { platformPermit } from '../../src/platform-permit.js';
4
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
5
+
6
+ export default defineAgentTool<{
7
+ endpoint_id: string;
8
+ channel_id: string;
9
+ purpose: string;
10
+ }>({
11
+ description: '设置 Slack 频道的用途/目的',
12
+ inputSchema: z.object({
13
+ endpoint_id: z.string().describe('Endpoint 名称'),
14
+ channel_id: z.string().describe('频道 ID'),
15
+ purpose: z.string().describe('频道用途描述'),
16
+ }),
17
+ platforms: ['slack'],
18
+ tags: ['slack'],
19
+ permissions: [platformPermit('channel_manager')],
20
+ async execute({ endpoint_id, channel_id, purpose }) {
21
+ const { getEndpoint } = getSlackAgentDeps();
22
+ const endpoint = getEndpoint(endpoint_id);
23
+ const success = await endpoint.setChannelPurpose(channel_id, purpose);
24
+ return { success, message: success ? '频道用途已更新' : '操作失败' };
25
+ },
26
+ });
@@ -0,0 +1,26 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { platformPermit } from '../../src/platform-permit.js';
4
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
5
+
6
+ export default defineAgentTool<{
7
+ endpoint_id: string;
8
+ channel: string;
9
+ topic: string;
10
+ }>({
11
+ description: '设置 Slack 频道话题',
12
+ inputSchema: z.object({
13
+ endpoint_id: z.string().describe('Endpoint 名称'),
14
+ channel: z.string().describe('频道 ID'),
15
+ topic: z.string().describe('新话题'),
16
+ }),
17
+ platforms: ['slack'],
18
+ tags: ['slack'],
19
+ permissions: [platformPermit('channel_manager')],
20
+ async execute({ endpoint_id, channel, topic }) {
21
+ const { getEndpoint } = getSlackAgentDeps();
22
+ const endpoint = getEndpoint(endpoint_id);
23
+ const success = await endpoint.setChannelTopic(channel, topic);
24
+ return { success, message: success ? '已设置频道话题' : '操作失败' };
25
+ },
26
+ });
@@ -0,0 +1,24 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { platformPermit } from '../../src/platform-permit.js';
4
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
5
+
6
+ export default defineAgentTool<{
7
+ endpoint_id: string;
8
+ channel_id: string;
9
+ }>({
10
+ description: '恢复已归档的 Slack 频道',
11
+ inputSchema: z.object({
12
+ endpoint_id: z.string().describe('Endpoint 名称'),
13
+ channel_id: z.string().describe('频道 ID'),
14
+ }),
15
+ platforms: ['slack'],
16
+ tags: ['slack'],
17
+ permissions: [platformPermit('workspace_admin')],
18
+ async execute({ endpoint_id, channel_id }) {
19
+ const { getEndpoint } = getSlackAgentDeps();
20
+ const endpoint = getEndpoint(endpoint_id);
21
+ const success = await endpoint.unarchiveChannel(channel_id);
22
+ return { success, message: success ? '频道已恢复' : '操作失败' };
23
+ },
24
+ });
@@ -0,0 +1,26 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { platformPermit } from '../../src/platform-permit.js';
4
+ import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
5
+
6
+ export default defineAgentTool<{
7
+ endpoint_id: string;
8
+ channel_id: string;
9
+ timestamp: string;
10
+ }>({
11
+ description: '取消 Slack 频道中消息的置顶',
12
+ inputSchema: z.object({
13
+ endpoint_id: z.string().describe('Endpoint 名称'),
14
+ channel_id: z.string().describe('频道 ID'),
15
+ timestamp: z.string().describe('消息时间戳'),
16
+ }),
17
+ platforms: ['slack'],
18
+ tags: ['slack'],
19
+ permissions: [platformPermit('channel_manager')],
20
+ async execute({ endpoint_id, channel_id, timestamp }) {
21
+ const { getEndpoint } = getSlackAgentDeps();
22
+ const endpoint = getEndpoint(endpoint_id);
23
+ const success = await endpoint.unpinMessage(channel_id, timestamp);
24
+ return { success, message: success ? '已取消置顶' : '操作失败' };
25
+ },
26
+ });