@zhin.js/adapter-slack 4.0.1 → 4.1.0
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 +18 -0
- package/README.md +207 -98
- package/{skills/slack/SKILL.md → agent/skills/slack.md} +2 -0
- package/agent/tools/add_reaction.ts +26 -0
- package/agent/tools/archive_channel.ts +24 -0
- package/agent/tools/edit_message.ts +27 -0
- package/agent/tools/invite_to_channel.ts +26 -0
- package/agent/tools/pin_message.ts +26 -0
- package/agent/tools/remove_reaction.ts +26 -0
- package/agent/tools/set_purpose.ts +26 -0
- package/agent/tools/set_topic.ts +26 -0
- package/agent/tools/unarchive.ts +24 -0
- package/agent/tools/unpin_message.ts +26 -0
- package/agent/tools/user_info.ts +31 -0
- package/lib/agent/tools/add_reaction.js +21 -0
- package/lib/agent/tools/add_reaction.js.map +1 -0
- package/lib/agent/tools/archive_channel.js +21 -0
- package/lib/agent/tools/archive_channel.js.map +1 -0
- package/lib/agent/tools/edit_message.js +22 -0
- package/lib/agent/tools/edit_message.js.map +1 -0
- package/lib/agent/tools/invite_to_channel.js +22 -0
- package/lib/agent/tools/invite_to_channel.js.map +1 -0
- package/lib/agent/tools/pin_message.js +22 -0
- package/lib/agent/tools/pin_message.js.map +1 -0
- package/lib/agent/tools/remove_reaction.js +21 -0
- package/lib/agent/tools/remove_reaction.js.map +1 -0
- package/lib/agent/tools/set_purpose.js +22 -0
- package/lib/agent/tools/set_purpose.js.map +1 -0
- package/lib/agent/tools/set_topic.js +22 -0
- package/lib/agent/tools/set_topic.js.map +1 -0
- package/lib/agent/tools/unarchive.js +21 -0
- package/lib/agent/tools/unarchive.js.map +1 -0
- package/lib/agent/tools/unpin_message.js +22 -0
- package/lib/agent/tools/unpin_message.js.map +1 -0
- package/lib/agent/tools/user_info.js +28 -0
- package/lib/agent/tools/user_info.js.map +1 -0
- package/lib/{adapter.js → src/adapter.js} +19 -3
- package/lib/src/adapter.js.map +1 -0
- package/lib/src/endpoint.js +312 -0
- package/lib/src/endpoint.js.map +1 -0
- package/lib/src/event-dispatcher.js +233 -0
- package/lib/src/event-dispatcher.js.map +1 -0
- package/lib/src/index.js +51 -0
- package/lib/src/index.js.map +1 -0
- package/lib/src/markdown-to-mrkdwn.js +61 -0
- package/lib/src/markdown-to-mrkdwn.js.map +1 -0
- package/lib/src/mrkdwn-to-markdown.js +31 -0
- package/lib/src/mrkdwn-to-markdown.js.map +1 -0
- package/lib/{platform-permit.js → src/platform-permit.js} +3 -0
- package/lib/src/platform-permit.js.map +1 -0
- package/lib/src/segment-mapper.js.map +1 -0
- package/lib/src/signing.js +21 -0
- package/lib/src/signing.js.map +1 -0
- package/lib/src/slack-agent-deps.js +10 -0
- package/lib/src/slack-agent-deps.js.map +1 -0
- package/lib/src/slack-inbound-filter.js +47 -0
- package/lib/src/slack-inbound-filter.js.map +1 -0
- package/lib/src/slack-inbound.js +127 -0
- package/lib/src/slack-inbound.js.map +1 -0
- package/lib/src/slack-message-ref.js +18 -0
- package/lib/src/slack-message-ref.js.map +1 -0
- package/lib/src/slack-outbound.js +223 -0
- package/lib/src/slack-outbound.js.map +1 -0
- package/lib/src/slack-reaction.js +27 -0
- package/lib/src/slack-reaction.js.map +1 -0
- package/lib/src/slack-response-url.js +17 -0
- package/lib/src/slack-response-url.js.map +1 -0
- package/lib/src/slack-side-events.js +64 -0
- package/lib/src/slack-side-events.js.map +1 -0
- package/lib/src/transport-http.js +83 -0
- package/lib/src/transport-http.js.map +1 -0
- package/lib/src/transport-socket.js +68 -0
- package/lib/src/transport-socket.js.map +1 -0
- package/lib/src/types.js +5 -0
- package/lib/src/types.js.map +1 -0
- package/package.json +24 -6
- package/src/adapter.ts +28 -7
- package/src/endpoint.ts +206 -604
- package/src/event-dispatcher.ts +255 -0
- package/src/index.ts +31 -239
- package/src/markdown-to-mrkdwn.ts +58 -0
- package/src/mrkdwn-to-markdown.ts +29 -0
- package/src/platform-permit.ts +1 -2
- package/src/signing.ts +28 -0
- package/src/slack-agent-deps.ts +22 -0
- package/src/slack-inbound-filter.ts +60 -0
- package/src/slack-inbound.ts +140 -0
- package/src/slack-message-ref.ts +18 -0
- package/src/slack-outbound.ts +269 -0
- package/src/slack-reaction.ts +23 -0
- package/src/slack-response-url.ts +26 -0
- package/src/slack-side-events.ts +74 -0
- package/src/transport-http.ts +95 -0
- package/src/transport-socket.ts +77 -0
- package/src/types.ts +99 -4
- package/lib/adapter.d.ts +0 -19
- package/lib/adapter.d.ts.map +0 -1
- package/lib/adapter.js.map +0 -1
- package/lib/endpoint.d.ts +0 -108
- package/lib/endpoint.d.ts.map +0 -1
- package/lib/endpoint.js +0 -677
- package/lib/endpoint.js.map +0 -1
- package/lib/index.d.ts +0 -10
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -252
- package/lib/index.js.map +0 -1
- package/lib/platform-permit.d.ts +0 -17
- package/lib/platform-permit.d.ts.map +0 -1
- package/lib/platform-permit.js.map +0 -1
- package/lib/segment-mapper.d.ts +0 -2
- package/lib/segment-mapper.d.ts.map +0 -1
- package/lib/segment-mapper.js.map +0 -1
- package/lib/types.d.ts +0 -17
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js +0 -2
- package/lib/types.js.map +0 -1
- /package/{skills/slack → agent}/PERMITS.md +0 -0
- /package/lib/{segment-mapper.js → src/segment-mapper.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 872c583: Slack 适配器 Phase 1/2:mrkdwn 出站、长消息切分、斜杠/按钮 ephemeral 反馈、入站 mrkdwn→Markdown、editMessage 对齐 core。
|
|
8
|
+
|
|
9
|
+
Logger 表格日志与 string-width 列宽;Agent AI Handler 框线表格与 introspection/MCP 导出;Core side-event 归一化;Schedule 时区规划;多适配器 side-event 与 API surface 更新。
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 872c583: fix: 代码格式优化
|
|
14
|
+
- Updated dependencies [872c583]
|
|
15
|
+
- Updated dependencies [872c583]
|
|
16
|
+
- @zhin.js/agent@1.0.3
|
|
17
|
+
- @zhin.js/host-router@2.0.3
|
|
18
|
+
- @zhin.js/logger@1.0.74
|
|
19
|
+
- zhin.js@4.1.2
|
|
20
|
+
|
|
3
21
|
## 4.0.1
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,32 +1,27 @@
|
|
|
1
1
|
# @zhin.js/adapter-slack
|
|
2
2
|
|
|
3
|
-
Slack
|
|
3
|
+
Zhin.js 的 Slack 适配器,支持消息收发、Block Kit 交互与 Assistant API。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 安装
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
pnpm add @zhin.js/adapter-slack
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## 配置
|
|
12
12
|
|
|
13
|
-
通过 **`socketMode`**
|
|
13
|
+
通过 **`socketMode`** 选择连接方式。
|
|
14
14
|
|
|
15
15
|
### 模式对比
|
|
16
16
|
|
|
17
17
|
| 模式 | `socketMode` | 适用场景 | 额外字段 |
|
|
18
18
|
|------|--------------|----------|----------|
|
|
19
19
|
| **Socket Mode** | `true`(推荐本地/内网) | 无需公网 URL,WebSocket 长连接 | `appToken`(`xapp-...`) |
|
|
20
|
-
| **HTTP Events** | `false` | 生产环境,有公网 HTTPS |
|
|
20
|
+
| **HTTP Events** | `false` | 生产环境,有公网 HTTPS | 共享 zhin router 端口 8086 |
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
### Socket Mode(推荐开发环境)
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
- 启用对应 Endpoint Events(`message.*`、`app_mention` 等)
|
|
26
|
-
- 防火墙 / 反向代理放行 `port`
|
|
27
|
-
- **不需要** `@zhin.js/host-router`(由 `@slack/bolt` 自行监听)
|
|
28
|
-
|
|
29
|
-
### Socket Mode (Recommended for Development)
|
|
24
|
+
可选 `clientPingTimeout`(毫秒,默认 `15000`)用于调整 Socket Mode 客户端心跳超时,减少误报 pong 警告。
|
|
30
25
|
|
|
31
26
|
```typescript
|
|
32
27
|
import { defineConfig } from 'zhin.js'
|
|
@@ -45,7 +40,9 @@ export default defineConfig({
|
|
|
45
40
|
})
|
|
46
41
|
```
|
|
47
42
|
|
|
48
|
-
### HTTP
|
|
43
|
+
### HTTP 模式(生产环境,使用 zhin Router)
|
|
44
|
+
|
|
45
|
+
HTTP 模式共享 zhin.js 内置的 Koa Router(默认端口 8086),无需额外监听端口。
|
|
49
46
|
|
|
50
47
|
```typescript
|
|
51
48
|
import { defineConfig } from 'zhin.js'
|
|
@@ -57,60 +54,128 @@ export default defineConfig({
|
|
|
57
54
|
context: 'slack',
|
|
58
55
|
token: 'xoxb-your-bot-token',
|
|
59
56
|
signingSecret: 'your-signing-secret',
|
|
60
|
-
socketMode: false
|
|
61
|
-
port: 3000
|
|
57
|
+
socketMode: false
|
|
62
58
|
}
|
|
63
59
|
]
|
|
64
60
|
})
|
|
65
61
|
```
|
|
66
62
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
63
|
+
**HTTP 模式前置条件:**
|
|
64
|
+
|
|
65
|
+
- Slack App 中配置 **Event Subscriptions** 的 Request URL 为 `https://your-domain:8086/slack/events`
|
|
66
|
+
- 配置 **Interactivity & Shortcuts** 的 Request URL 为同一地址
|
|
67
|
+
- 配置 **Slash Commands** 的 Request URL 为同一地址
|
|
68
|
+
- 防火墙 / 反向代理放行端口
|
|
69
|
+
|
|
70
|
+
## 功能特性
|
|
71
|
+
|
|
72
|
+
- 收发文本消息
|
|
73
|
+
- 富媒体(图片、文件),经 `files.uploadV2` 上传
|
|
74
|
+
- 消息格式化(Slack mrkdwn + Block Kit)
|
|
75
|
+
- 回复消息与线程(`thread_ts`)
|
|
76
|
+
- 提及(@用户、#频道)
|
|
77
|
+
- 链接与附件
|
|
78
|
+
- Socket Mode 与 HTTP 模式(共享 zhin router)
|
|
79
|
+
- 私信与频道消息
|
|
80
|
+
- Block Kit 交互按钮(`keyboard` 片段 → 原生 Slack 按钮)
|
|
81
|
+
- 斜杠命令 → zhin Command 映射
|
|
82
|
+
- 消息编辑(`$editMessage` / `chat.update`)
|
|
83
|
+
- Notice 事件映射(`member_joined`、`reaction_added`、`pin_added` 等)
|
|
84
|
+
- Assistant API 支持(`assistant_thread_started` 事件)
|
|
85
|
+
- 出站 Markdown → Slack mrkdwn 自动转换(`**粗体**` → `*粗体*`)
|
|
86
|
+
- 长消息自动分段(超 2900 字符切 section;超 48 blocks 分多条发送)
|
|
87
|
+
- 斜杠命令即时 ephemeral 反馈(「处理中…」);最终回复仍 `chat.postMessage`
|
|
88
|
+
- 按钮点击即时 ephemeral 反馈(「已收到」)
|
|
89
|
+
- 入站 Slack mrkdwn → 通用 Markdown(粗体/斜体/删除线/代码/链接)
|
|
90
|
+
|
|
91
|
+
## 消息格式
|
|
92
|
+
|
|
93
|
+
### 出站(Markdown → mrkdwn)
|
|
94
|
+
|
|
95
|
+
AI 或命令输出的通用 Markdown(如 `**粗体**`、`*斜体*`)会自动转换为 Slack mrkdwn,并通过 Block Kit `section` 块发送,确保在 Slack 客户端正确渲染。
|
|
96
|
+
|
|
97
|
+
### 长消息
|
|
98
|
+
|
|
99
|
+
- 单条 `section` 文本超过约 2900 字符时自动切分为多个 section
|
|
100
|
+
- 单条消息 blocks 超过 48 个时自动拆分为多条 `chat.postMessage`
|
|
101
|
+
|
|
102
|
+
### 入站(mrkdwn → Markdown)
|
|
103
|
+
|
|
104
|
+
用户发送的 Slack mrkdwn 在解析为 `text` 段前会转换为通用 Markdown:
|
|
105
|
+
|
|
106
|
+
| Slack mrkdwn | 通用 Markdown |
|
|
107
|
+
|--------------|---------------|
|
|
108
|
+
| `*bold*` | `**bold**` |
|
|
109
|
+
| `_italic_` | `*italic*` |
|
|
110
|
+
| `~strike~` | `~~strike~~` |
|
|
111
|
+
| `` `code` `` | 保持 |
|
|
112
|
+
| `<url\|text>` | `[text](url)` |
|
|
113
|
+
|
|
114
|
+
`<@U>` / `<#C>` 等特殊段仍由专用解析器处理,不在此转换。该转换为启发式,复杂嵌套格式不保证完美往返。
|
|
115
|
+
|
|
116
|
+
## 交互反馈
|
|
117
|
+
|
|
118
|
+
### 斜杠命令
|
|
119
|
+
|
|
120
|
+
收到斜杠命令后,适配器会立即向触发者发送 ephemeral「处理中…」(仅触发者可见)。命令处理完成后的最终回复仍通过 `chat.postMessage` 发送到频道,与现有 `$reply` 行为一致。
|
|
121
|
+
|
|
122
|
+
### Block Kit 按钮
|
|
123
|
+
|
|
124
|
+
用户点击 `block_actions` 按钮后,适配器会向点击者发送 ephemeral「已收到」。如需在线程中回复,仍通过 `sendMessage`(`thread_ts`)发送。
|
|
125
|
+
|
|
126
|
+
## 创建 Slack App
|
|
127
|
+
|
|
128
|
+
1. 前往 [Slack API](https://api.slack.com/apps)
|
|
129
|
+
2. 创建新应用
|
|
130
|
+
3. 添加 Bot Token Scopes:
|
|
131
|
+
- `chat:write` — 发送消息
|
|
132
|
+
- `chat:write.public` — 向公开频道发送消息
|
|
133
|
+
- `channels:read` — 查看频道基本信息
|
|
134
|
+
- `channels:history` — 查看频道消息历史
|
|
135
|
+
- `channels:manage` — 管理频道
|
|
136
|
+
- `groups:read` — 查看私有频道基本信息
|
|
137
|
+
- `groups:history` — 查看私有频道消息历史
|
|
138
|
+
- `im:read` — 查看私信基本信息
|
|
139
|
+
- `im:history` — 查看私信消息历史
|
|
140
|
+
- `mpim:read` — 查看群组私信基本信息
|
|
141
|
+
- `mpim:history` — 查看群组私信消息历史
|
|
142
|
+
- `users:read` — 查看用户信息
|
|
143
|
+
- `files:read` — 查看文件
|
|
144
|
+
- `files:write` — 上传文件
|
|
145
|
+
- `reactions:read` — 查看表情回应
|
|
146
|
+
- `reactions:write` — 添加/移除表情回应
|
|
147
|
+
- `pins:read` — 查看置顶项
|
|
148
|
+
- `pins:write` — 置顶/取消置顶消息
|
|
149
|
+
- `commands` — 添加斜杠命令
|
|
150
|
+
- `assistant:write` — Assistant API(若使用 AI 功能)
|
|
151
|
+
4. 启用 Socket Mode(若使用 Socket Mode):
|
|
152
|
+
- 进入 Socket Mode 设置
|
|
153
|
+
- 启用 Socket Mode
|
|
154
|
+
- 生成带 `connections:write` scope 的应用级 Token
|
|
155
|
+
5. 订阅 Bot 事件:
|
|
156
|
+
- `message.channels` — 公开频道消息
|
|
157
|
+
- `message.groups` — 私有频道消息
|
|
158
|
+
- `message.im` — 私信
|
|
159
|
+
- `message.mpim` — 群组私信
|
|
160
|
+
- `app_mention` — Bot 被 @ 提及时
|
|
161
|
+
- `member_joined_channel` — 用户加入频道
|
|
162
|
+
- `member_left_channel` — 用户离开频道
|
|
163
|
+
- `reaction_added` — 添加表情回应
|
|
164
|
+
- `reaction_removed` — 移除表情回应
|
|
165
|
+
- `channel_archive` / `channel_unarchive`
|
|
166
|
+
- `channel_rename` / `channel_created` / `channel_deleted`
|
|
167
|
+
- `pin_added` / `pin_removed`
|
|
168
|
+
- `team_join` — 新用户加入工作区
|
|
169
|
+
- `assistant_thread_started`(若使用 Assistant API)
|
|
170
|
+
- `assistant_thread_context_changed`(若使用 Assistant API)
|
|
171
|
+
6. 将应用安装到工作区
|
|
172
|
+
7. 复制 Bot User OAuth Token(`xoxb-...`)
|
|
173
|
+
8. 复制 Signing Secret
|
|
174
|
+
9. 若使用 Socket Mode,复制 App-Level Token(`xapp-...`)
|
|
175
|
+
|
|
176
|
+
## 使用示例
|
|
177
|
+
|
|
178
|
+
### 基础消息处理
|
|
114
179
|
|
|
115
180
|
```typescript
|
|
116
181
|
import { usePlugin, MessageCommand } from 'zhin.js'
|
|
@@ -124,69 +189,113 @@ addCommand(new MessageCommand('hello')
|
|
|
124
189
|
)
|
|
125
190
|
```
|
|
126
191
|
|
|
127
|
-
###
|
|
192
|
+
### 发送带 Block Kit 按钮的富消息
|
|
128
193
|
|
|
129
194
|
```typescript
|
|
130
|
-
addCommand(new MessageCommand('
|
|
195
|
+
addCommand(new MessageCommand('vote')
|
|
131
196
|
.action(async (message) => {
|
|
132
197
|
return [
|
|
133
|
-
{ type: 'text', data: { text: '
|
|
134
|
-
{
|
|
198
|
+
{ type: 'text', data: { text: 'What do you think?' } },
|
|
199
|
+
{
|
|
200
|
+
type: 'keyboard',
|
|
201
|
+
data: {
|
|
202
|
+
rows: [[
|
|
203
|
+
{ label: 'Approve', id: 'vote_yes', style: 'primary' },
|
|
204
|
+
{ label: 'Reject', id: 'vote_no', style: 'danger' },
|
|
205
|
+
]]
|
|
206
|
+
}
|
|
207
|
+
}
|
|
135
208
|
]
|
|
136
209
|
})
|
|
137
210
|
)
|
|
138
211
|
```
|
|
139
212
|
|
|
140
|
-
###
|
|
213
|
+
### 在线程中回复
|
|
141
214
|
|
|
142
215
|
```typescript
|
|
143
|
-
addCommand(new MessageCommand('
|
|
144
|
-
.action(async (message
|
|
145
|
-
|
|
146
|
-
{ type: 'at', data: { id: result.params.userId } },
|
|
147
|
-
{ type: 'text', data: { text: ' Hello!' } }
|
|
148
|
-
]
|
|
216
|
+
addCommand(new MessageCommand('thread')
|
|
217
|
+
.action(async (message) => {
|
|
218
|
+
await message.$reply('This is a threaded reply!', true)
|
|
149
219
|
})
|
|
150
220
|
)
|
|
151
221
|
```
|
|
152
222
|
|
|
153
|
-
###
|
|
223
|
+
### 编辑消息
|
|
224
|
+
|
|
225
|
+
适配器支持 core `EditMessageOptions` 契约。`messageId` 优先使用 `channel:ts` 格式;若仅为 `ts`,则使用 `options.id` 作为 channel。
|
|
154
226
|
|
|
155
227
|
```typescript
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
)
|
|
228
|
+
const adapter = inject('slack')
|
|
229
|
+
|
|
230
|
+
// 旧 API(薄封装,仍可用)
|
|
231
|
+
await adapter.editMessage('my-slack-bot', 'C001', '1700000000.000000', [
|
|
232
|
+
{ type: 'text', data: { text: 'Updated message content' } }
|
|
233
|
+
])
|
|
234
|
+
|
|
235
|
+
// core 契约(推荐)
|
|
236
|
+
await adapter.editMessage({
|
|
237
|
+
messageId: 'C001:1700000000.000000',
|
|
238
|
+
context: 'slack',
|
|
239
|
+
endpoint: 'my-slack-bot',
|
|
240
|
+
id: 'C001',
|
|
241
|
+
type: 'group',
|
|
242
|
+
content: [{ type: 'text', data: { text: 'Updated message content' } }],
|
|
243
|
+
})
|
|
162
244
|
```
|
|
163
245
|
|
|
164
|
-
## Slack
|
|
246
|
+
## Slack MCP Server 集成
|
|
247
|
+
|
|
248
|
+
如果你的 zhin 实例使用了 `@zhin.js/agent`(AI 功能),可以将 Slack MCP Server 配置为 AI 的工具来源:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
export default defineConfig({
|
|
252
|
+
ai: {
|
|
253
|
+
mcpServers: {
|
|
254
|
+
slack: {
|
|
255
|
+
command: 'npx',
|
|
256
|
+
args: ['-y', '@anthropic/slack-mcp-server'],
|
|
257
|
+
env: {
|
|
258
|
+
SLACK_BOT_TOKEN: 'xoxb-your-bot-token',
|
|
259
|
+
SLACK_TEAM_ID: 'T0123456789'
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
})
|
|
265
|
+
```
|
|
165
266
|
|
|
166
|
-
|
|
267
|
+
这将使 AI Agent 获得搜索 Slack 消息、管理频道等额外能力。
|
|
167
268
|
|
|
168
|
-
|
|
169
|
-
- `*bold*` for **bold**
|
|
170
|
-
- `_italic_` for *italic*
|
|
171
|
-
- `~strike~` for ~~strikethrough~~
|
|
172
|
-
- `` `code` `` for `code`
|
|
173
|
-
- `> quote` for blockquotes
|
|
269
|
+
## Notice 事件映射
|
|
174
270
|
|
|
175
|
-
|
|
271
|
+
| Slack 事件 | zhin Notice 类型 |
|
|
272
|
+
|---|---|
|
|
273
|
+
| `member_joined_channel` | `notice.group.member_increase` |
|
|
274
|
+
| `member_left_channel` | `notice.group.member_decrease` |
|
|
275
|
+
| `reaction_added` / `reaction_removed` | `notice.group.emoji_reaction` |
|
|
276
|
+
| `message_deleted` | `notice.group.recall` |
|
|
277
|
+
| `team_join` | `notice.friend.increase` |
|
|
278
|
+
| `channel_archive` | `notice.slack.channel_archive` |
|
|
279
|
+
| `pin_added` / `pin_removed` | `notice.slack.pin_added` / `notice.slack.pin_removed` |
|
|
176
280
|
|
|
177
|
-
|
|
178
|
-
- `<@U12345678>` to user mentions
|
|
179
|
-
- `<#C12345678>` to channel mentions
|
|
281
|
+
## AI 工具
|
|
180
282
|
|
|
181
|
-
|
|
283
|
+
| 类别 | 路径 |
|
|
284
|
+
|------|------|
|
|
285
|
+
| Permit 词汇 | `agent/PERMITS.md` |
|
|
286
|
+
| 平台工具(11 个) | `agent/tools/`(`slack_*`:邀请、话题、反应、置顶等) |
|
|
287
|
+
| 技能说明 | `agent/skills/slack.md` |
|
|
288
|
+
| 群管标准工具 | `createSceneManagementTools()` |
|
|
182
289
|
|
|
183
|
-
Upload files using the `file` segment type with a local file path.
|
|
184
290
|
|
|
185
|
-
##
|
|
291
|
+
## 限制
|
|
186
292
|
|
|
187
|
-
-
|
|
188
|
-
-
|
|
293
|
+
- 入站 mrkdwn → Markdown 为启发式转换,复杂嵌套格式不保证完美往返
|
|
294
|
+
- Modals / `view_submission` / `view_closed` — 暂不支持
|
|
295
|
+
- Select menus / options load — 暂不支持
|
|
296
|
+
- File 事件全系列(`file_created` / `file_shared` 等)— 暂不支持
|
|
297
|
+
- OAuth 安装流程 — 暂不支持
|
|
189
298
|
|
|
190
|
-
##
|
|
299
|
+
## 许可证
|
|
191
300
|
|
|
192
301
|
MIT
|
|
@@ -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 { defineTool } from '@zhin.js/agent/tools';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
|
|
4
|
+
|
|
5
|
+
export default defineTool<{
|
|
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 { defineTool } 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 defineTool<{
|
|
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,27 @@
|
|
|
1
|
+
import { defineTool } from '@zhin.js/agent/tools';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
|
|
4
|
+
|
|
5
|
+
export default defineTool<{
|
|
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 { getAdapter } = getSlackAgentDeps();
|
|
22
|
+
await getAdapter().editMessage(endpoint_id, channel, message_ts, [
|
|
23
|
+
{ type: 'text', data: { text } },
|
|
24
|
+
]);
|
|
25
|
+
return { success: true, message: '消息已编辑' };
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { defineTool } 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 defineTool<{
|
|
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 { defineTool } 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 defineTool<{
|
|
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 { defineTool } from '@zhin.js/agent/tools';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getSlackAgentDeps } from '../../src/slack-agent-deps.js';
|
|
4
|
+
|
|
5
|
+
export default defineTool<{
|
|
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 { defineTool } 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 defineTool<{
|
|
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 { defineTool } 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 defineTool<{
|
|
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 { defineTool } 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 defineTool<{
|
|
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
|
+
});
|