@tencent-connect/openclaw-qqbot 1.6.3-alpha.channel → 1.6.4-alpha.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/clawdbot.plugin.json +1 -1
- package/dist/index.js +2 -0
- package/dist/src/api.d.ts +9 -0
- package/dist/src/api.js +11 -0
- package/dist/src/slash-commands.js +42 -89
- package/index.ts +2 -0
- package/moltbot.plugin.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/qqbot-channel/SKILL.md +263 -0
- package/skills/qqbot-channel/references/api_references.md +521 -0
- package/src/api.ts +17 -0
- package/src/openclaw-plugin-sdk.d.ts +39 -0
- package/src/slash-commands.ts +51 -95
- package/src/tools/channel.ts +281 -0
package/clawdbot.plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "OpenClaw QQ Bot",
|
|
4
4
|
"description": "QQ Bot channel plugin with message support, cron jobs, and proactive messaging",
|
|
5
5
|
"channels": ["qqbot"],
|
|
6
|
-
"skills": ["skills/qqbot-cron", "skills/qqbot-media"],
|
|
6
|
+
"skills": ["skills/qqbot-channel", "skills/qqbot-cron", "skills/qqbot-media"],
|
|
7
7
|
"capabilities": {
|
|
8
8
|
"proactiveMessaging": true,
|
|
9
9
|
"cronJobs": true
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
2
2
|
import { qqbotPlugin } from "./src/channel.js";
|
|
3
3
|
import { setQQBotRuntime } from "./src/runtime.js";
|
|
4
|
+
import { registerChannelTool } from "./src/tools/channel.js";
|
|
4
5
|
const plugin = {
|
|
5
6
|
id: "openclaw-qqbot",
|
|
6
7
|
name: "QQ Bot",
|
|
@@ -9,6 +10,7 @@ const plugin = {
|
|
|
9
10
|
register(api) {
|
|
10
11
|
setQQBotRuntime(api.runtime);
|
|
11
12
|
api.registerChannel({ plugin: qqbotPlugin });
|
|
13
|
+
registerChannelTool(api);
|
|
12
14
|
},
|
|
13
15
|
};
|
|
14
16
|
export default plugin;
|
package/dist/src/api.d.ts
CHANGED
|
@@ -81,6 +81,15 @@ export declare function sendChannelMessage(accessToken: string, channelId: strin
|
|
|
81
81
|
id: string;
|
|
82
82
|
timestamp: string;
|
|
83
83
|
}>;
|
|
84
|
+
/**
|
|
85
|
+
* 发送频道私信消息
|
|
86
|
+
* @param guildId - 私信会话的 guild_id(由 DIRECT_MESSAGE_CREATE 事件提供)
|
|
87
|
+
* @param msgId - 被动回复时必填
|
|
88
|
+
*/
|
|
89
|
+
export declare function sendDmMessage(accessToken: string, guildId: string, content: string, msgId?: string): Promise<{
|
|
90
|
+
id: string;
|
|
91
|
+
timestamp: string;
|
|
92
|
+
}>;
|
|
84
93
|
export declare function sendGroupMessage(accessToken: string, groupOpenid: string, content: string, msgId?: string): Promise<MessageResponse>;
|
|
85
94
|
export declare function sendProactiveC2CMessage(accessToken: string, openid: string, content: string): Promise<MessageResponse>;
|
|
86
95
|
export declare function sendProactiveGroupMessage(accessToken: string, groupOpenid: string, content: string): Promise<{
|
package/dist/src/api.js
CHANGED
|
@@ -340,6 +340,17 @@ export async function sendChannelMessage(accessToken, channelId, content, msgId)
|
|
|
340
340
|
...(msgId ? { msg_id: msgId } : {}),
|
|
341
341
|
});
|
|
342
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* 发送频道私信消息
|
|
345
|
+
* @param guildId - 私信会话的 guild_id(由 DIRECT_MESSAGE_CREATE 事件提供)
|
|
346
|
+
* @param msgId - 被动回复时必填
|
|
347
|
+
*/
|
|
348
|
+
export async function sendDmMessage(accessToken, guildId, content, msgId) {
|
|
349
|
+
return apiRequest(accessToken, "POST", `/dms/${guildId}/messages`, {
|
|
350
|
+
content,
|
|
351
|
+
...(msgId ? { msg_id: msgId } : {}),
|
|
352
|
+
});
|
|
353
|
+
}
|
|
343
354
|
export async function sendGroupMessage(accessToken, groupOpenid, content, msgId) {
|
|
344
355
|
const msgSeq = msgId ? getNextMsgSeq(msgId) : 1;
|
|
345
356
|
const body = buildMessageBody(content, msgId, msgSeq);
|
|
@@ -144,13 +144,25 @@ function findCli() {
|
|
|
144
144
|
return null;
|
|
145
145
|
}
|
|
146
146
|
/**
|
|
147
|
-
*
|
|
147
|
+
* 找到升级脚本路径(兼容源码运行、dist 运行、已安装扩展目录)
|
|
148
148
|
*/
|
|
149
149
|
function getUpgradeScriptPath() {
|
|
150
150
|
const currentFile = fileURLToPath(import.meta.url);
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
|
|
151
|
+
const currentDir = path.dirname(currentFile);
|
|
152
|
+
const candidates = [
|
|
153
|
+
path.resolve(currentDir, "..", "..", "scripts", "upgrade-via-npm.sh"),
|
|
154
|
+
path.resolve(currentDir, "..", "scripts", "upgrade-via-npm.sh"),
|
|
155
|
+
path.resolve(process.cwd(), "scripts", "upgrade-via-npm.sh"),
|
|
156
|
+
];
|
|
157
|
+
const homeDir = getHomeDir();
|
|
158
|
+
for (const cli of ["openclaw", "clawdbot", "moltbot"]) {
|
|
159
|
+
candidates.push(path.join(homeDir, `.${cli}`, "extensions", "openclaw-qqbot", "scripts", "upgrade-via-npm.sh"));
|
|
160
|
+
}
|
|
161
|
+
for (const p of candidates) {
|
|
162
|
+
if (fs.existsSync(p))
|
|
163
|
+
return p;
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
154
166
|
}
|
|
155
167
|
/**
|
|
156
168
|
* 在 Windows 上查找可用的 bash(Git Bash / WSL 等)
|
|
@@ -184,25 +196,19 @@ function findBash() {
|
|
|
184
196
|
* - 异步执行升级脚本(--no-restart,只做文件替换)
|
|
185
197
|
* - 脚本完成后触发 gateway restart(当前进程会被杀掉)
|
|
186
198
|
* - 新进程启动时 getStartupGreeting() 检测到版本变更,自动通知管理员
|
|
187
|
-
*
|
|
188
|
-
* @returns true 表示已启动升级流程,false 表示无法执行(如 Windows 无 bash)
|
|
189
199
|
*/
|
|
190
200
|
function fireHotUpgrade(targetVersion) {
|
|
191
201
|
const scriptPath = getUpgradeScriptPath();
|
|
192
202
|
if (!scriptPath)
|
|
193
|
-
return false;
|
|
203
|
+
return { ok: false, reason: "no-script" };
|
|
194
204
|
const cli = findCli();
|
|
195
205
|
if (!cli)
|
|
196
|
-
return false;
|
|
206
|
+
return { ok: false, reason: "no-cli" };
|
|
197
207
|
const bash = findBash();
|
|
198
208
|
if (!bash)
|
|
199
|
-
return false;
|
|
200
|
-
const args = ["--no-restart"];
|
|
201
|
-
if (targetVersion) {
|
|
202
|
-
args.push("--version", targetVersion);
|
|
203
|
-
}
|
|
209
|
+
return { ok: false, reason: "no-bash" };
|
|
204
210
|
// 异步执行升级脚本
|
|
205
|
-
execFile(bash, [scriptPath, ...
|
|
211
|
+
execFile(bash, [scriptPath, "--no-restart", ...(targetVersion ? ["--version", targetVersion] : [])], {
|
|
206
212
|
timeout: 120_000,
|
|
207
213
|
env: { ...process.env },
|
|
208
214
|
...(isWindows() ? { windowsHide: true } : {}),
|
|
@@ -213,104 +219,51 @@ function fireHotUpgrade(targetVersion) {
|
|
|
213
219
|
// 文件替换成功,触发 gateway restart
|
|
214
220
|
execFile(cli, ["gateway", "restart"], { timeout: 30_000 }, () => { });
|
|
215
221
|
});
|
|
216
|
-
return true;
|
|
222
|
+
return { ok: true };
|
|
217
223
|
}
|
|
218
224
|
/**
|
|
219
|
-
* /bot-upgrade —
|
|
220
|
-
*/
|
|
221
|
-
registerCommand({
|
|
222
|
-
name: "bot-upgrade",
|
|
223
|
-
description: "查看版本更新与升级指引",
|
|
224
|
-
handler: (ctx) => {
|
|
225
|
-
// 升级相关指令仅在私聊中可用
|
|
226
|
-
if (ctx.type !== "c2c") {
|
|
227
|
-
return `💡 请在私聊中使用此指令`;
|
|
228
|
-
}
|
|
229
|
-
const upgradeMode = ctx.accountConfig?.upgradeMode || "doc";
|
|
230
|
-
const url = ctx.accountConfig?.upgradeUrl || DEFAULT_UPGRADE_URL;
|
|
231
|
-
const info = getUpdateInfo();
|
|
232
|
-
const lines = [];
|
|
233
|
-
lines.push(`📌当前版本:v${PLUGIN_VERSION}`);
|
|
234
|
-
if (info.checkedAt === 0) {
|
|
235
|
-
lines.push(`⏳ 版本检查中,请稍后再试`);
|
|
236
|
-
return lines.join("\n");
|
|
237
|
-
}
|
|
238
|
-
else if (info.error) {
|
|
239
|
-
lines.push(`⚠️ 版本检查失败`);
|
|
240
|
-
lines.push(`⬆️升级指引:[点击查看](${url})`);
|
|
241
|
-
return lines.join("\n");
|
|
242
|
-
}
|
|
243
|
-
else if (info.hasUpdate && info.latest) {
|
|
244
|
-
lines.push(`🆕最新可用版本:v${info.latest}`);
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
lines.push(`✅ 当前已是最新版本`);
|
|
248
|
-
return lines.join("\n");
|
|
249
|
-
}
|
|
250
|
-
// 有新版本:根据 upgradeMode 决定行为
|
|
251
|
-
if (upgradeMode === "hot-reload") {
|
|
252
|
-
const started = fireHotUpgrade(info.latest);
|
|
253
|
-
if (!started) {
|
|
254
|
-
lines.push(`⚠️ 当前环境不支持热更新(需要 bash 环境)`);
|
|
255
|
-
lines.push(`⬆️升级指引:[点击查看](${url})`);
|
|
256
|
-
return lines.join("\n");
|
|
257
|
-
}
|
|
258
|
-
lines.push(``);
|
|
259
|
-
lines.push(`🔄 正在执行热更新到 v${info.latest}...`);
|
|
260
|
-
lines.push(`⏳ 升级过程约需 30~60 秒,完成后会自动通知您`);
|
|
261
|
-
return lines.join("\n");
|
|
262
|
-
}
|
|
263
|
-
// doc 模式:展示升级文档
|
|
264
|
-
lines.push(`⬆️升级指引:[点击查看](${url})`);
|
|
265
|
-
lines.push(`🌟官方 GitHub 仓库:[点击前往](https://github.com/tencent-connect/openclaw-qqbot/)`);
|
|
266
|
-
lines.push(``, `> 💡 提示:管理员可通过 <qqbot-cmd-input text="/bot-hot-upgrade" show="/bot-hot-upgrade"/> 直接执行热更新`);
|
|
267
|
-
return lines.join("\n");
|
|
268
|
-
},
|
|
269
|
-
});
|
|
270
|
-
/**
|
|
271
|
-
* /bot-hot-upgrade — 直接执行热更新(无论 upgradeMode 配置如何)
|
|
225
|
+
* /bot-upgrade — 统一升级入口:能热更就热更,失败则返回升级指引
|
|
272
226
|
*
|
|
273
227
|
* 支持参数:
|
|
274
|
-
* /bot-
|
|
275
|
-
* /bot-
|
|
276
|
-
* /bot-
|
|
228
|
+
* /bot-upgrade — 检查更新后自动热更
|
|
229
|
+
* /bot-upgrade 1.6.4 — 升级到指定版本
|
|
230
|
+
* /bot-upgrade --force — 强制升级(即使当前已是最新版)
|
|
277
231
|
*/
|
|
278
232
|
registerCommand({
|
|
279
|
-
name: "bot-
|
|
280
|
-
description: "
|
|
233
|
+
name: "bot-upgrade",
|
|
234
|
+
description: "检查更新并自动热更(失败则返回升级指引)",
|
|
281
235
|
handler: (ctx) => {
|
|
282
236
|
// 升级相关指令仅在私聊中可用
|
|
283
237
|
if (ctx.type !== "c2c") {
|
|
284
238
|
return `💡 请在私聊中使用此指令`;
|
|
285
239
|
}
|
|
286
|
-
|
|
287
|
-
const scriptPath = getUpgradeScriptPath();
|
|
288
|
-
if (!scriptPath) {
|
|
289
|
-
return "❌ 升级脚本不存在,请检查安装是否完整";
|
|
290
|
-
}
|
|
291
|
-
const cli = findCli();
|
|
292
|
-
if (!cli) {
|
|
293
|
-
return "❌ 未找到 openclaw / clawdbot / moltbot CLI";
|
|
294
|
-
}
|
|
240
|
+
const url = ctx.accountConfig?.upgradeUrl || DEFAULT_UPGRADE_URL;
|
|
295
241
|
const args = ctx.args.trim();
|
|
296
242
|
const info = getUpdateInfo();
|
|
297
|
-
// 解析参数
|
|
298
243
|
const isForce = args.includes("--force");
|
|
299
244
|
const versionArg = args.replace("--force", "").trim() || undefined;
|
|
300
|
-
// 如果没有指定版本,先检查是否有更新
|
|
301
245
|
if (!versionArg && !isForce) {
|
|
302
246
|
if (info.checkedAt === 0) {
|
|
303
247
|
return `⏳ 版本检查中,请稍后再试`;
|
|
304
248
|
}
|
|
305
|
-
if (
|
|
306
|
-
return
|
|
249
|
+
if (info.error) {
|
|
250
|
+
return `⚠️ 版本检查失败\n⬆️升级指引:[点击查看](${url})`;
|
|
251
|
+
}
|
|
252
|
+
if (!info.hasUpdate) {
|
|
253
|
+
return `✅ 当前版本 v${PLUGIN_VERSION} 已是最新,无需升级\n\n> 💡 使用 /bot-upgrade --force 可强制重新安装`;
|
|
307
254
|
}
|
|
308
255
|
}
|
|
309
256
|
const targetVersion = versionArg || info.latest || undefined;
|
|
310
257
|
// 异步执行升级
|
|
311
|
-
const
|
|
312
|
-
if (!
|
|
313
|
-
|
|
258
|
+
const startResult = fireHotUpgrade(targetVersion);
|
|
259
|
+
if (!startResult.ok) {
|
|
260
|
+
if (startResult.reason === "no-script") {
|
|
261
|
+
return `❌ 未找到本地升级脚本\n⬆️升级指引:[点击查看](${url})`;
|
|
262
|
+
}
|
|
263
|
+
if (startResult.reason === "no-cli") {
|
|
264
|
+
return `❌ 未找到 openclaw / clawdbot / moltbot CLI\n⬆️升级指引:[点击查看](${url})`;
|
|
265
|
+
}
|
|
266
|
+
return `❌ 当前环境不支持热更新(需要 bash 环境)\n⬆️升级指引:[点击查看](${url})\n\n> Windows 用户请安装 Git for Windows 后重试,或手动执行升级脚本`;
|
|
314
267
|
}
|
|
315
268
|
const lines = [
|
|
316
269
|
`🔄 开始热更新...`,
|
package/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
|
3
3
|
|
|
4
4
|
import { qqbotPlugin } from "./src/channel.js";
|
|
5
5
|
import { setQQBotRuntime } from "./src/runtime.js";
|
|
6
|
+
import { registerChannelTool } from "./src/tools/channel.js";
|
|
6
7
|
|
|
7
8
|
const plugin = {
|
|
8
9
|
id: "openclaw-qqbot",
|
|
@@ -12,6 +13,7 @@ const plugin = {
|
|
|
12
13
|
register(api: OpenClawPluginApi) {
|
|
13
14
|
setQQBotRuntime(api.runtime);
|
|
14
15
|
api.registerChannel({ plugin: qqbotPlugin });
|
|
16
|
+
registerChannelTool(api);
|
|
15
17
|
},
|
|
16
18
|
};
|
|
17
19
|
|
package/moltbot.plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "OpenClaw QQ Bot",
|
|
4
4
|
"description": "QQ Bot channel plugin with message support, cron jobs, and proactive messaging",
|
|
5
5
|
"channels": ["qqbot"],
|
|
6
|
-
"skills": ["skills/qqbot-cron", "skills/qqbot-media"],
|
|
6
|
+
"skills": ["skills/qqbot-channel", "skills/qqbot-cron", "skills/qqbot-media"],
|
|
7
7
|
"capabilities": {
|
|
8
8
|
"proactiveMessaging": true,
|
|
9
9
|
"cronJobs": true
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "OpenClaw QQ Bot",
|
|
4
4
|
"description": "QQ Bot channel plugin with message support, cron jobs, and proactive messaging",
|
|
5
5
|
"channels": ["qqbot"],
|
|
6
|
-
"skills": ["skills/qqbot-cron", "skills/qqbot-media"],
|
|
6
|
+
"skills": ["skills/qqbot-channel", "skills/qqbot-cron", "skills/qqbot-media"],
|
|
7
7
|
"capabilities": {
|
|
8
8
|
"proactiveMessaging": true,
|
|
9
9
|
"cronJobs": true
|
package/package.json
CHANGED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qqbot-channel
|
|
3
|
+
description: QQ 频道管理技能。查询频道列表、子频道、成员、发帖、公告、日程等操作。使用 qqbot_channel_api 工具代理 QQ 开放平台 HTTP 接口,自动处理 Token 鉴权。当用户需要查看频道、管理子频道、查询成员、发布帖子/公告/日程时使用此技能。
|
|
4
|
+
metadata: {"openclaw":{"emoji":"📡","requires":{"config":["channels.qqbot"]}}}
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# QQ 频道 API 请求指导
|
|
8
|
+
|
|
9
|
+
`qqbot_channel_api` 是一个 QQ 开放平台 HTTP 代理工具,**自动填充鉴权 Token**。你只需要指定 HTTP 方法、API 路径、请求体和查询参数。
|
|
10
|
+
|
|
11
|
+
## 📚 详细参考文档
|
|
12
|
+
|
|
13
|
+
每个接口的完整参数说明、返回值结构和枚举值定义:
|
|
14
|
+
- `references/api_references.md`
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 🔧 工具参数
|
|
19
|
+
|
|
20
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
21
|
+
|------|------|------|------|
|
|
22
|
+
| `method` | string | 是 | HTTP 方法:`GET`, `POST`, `PUT`, `PATCH`, `DELETE` |
|
|
23
|
+
| `path` | string | 是 | API 路径(不含域名),如 `/guilds/{guild_id}/channels`,需替换占位符为实际值 |
|
|
24
|
+
| `body` | object | 否 | 请求体 JSON(POST/PUT/PATCH 使用) |
|
|
25
|
+
| `query` | object | 否 | URL 查询参数键值对,值为字符串类型 |
|
|
26
|
+
|
|
27
|
+
> 基础 URL:`https://api.sgroup.qq.com`,鉴权头 `Authorization: QQBot {token}` 由工具自动填充。
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## ⭐ 接口速查
|
|
32
|
+
|
|
33
|
+
### 频道(Guild)
|
|
34
|
+
|
|
35
|
+
| 操作 | 方法 | 路径 | 参数说明 |
|
|
36
|
+
|------|------|------|----------|
|
|
37
|
+
| 获取频道列表 | `GET` | `/users/@me/guilds` | query: `before`, `after`, `limit`(最大100) |
|
|
38
|
+
| 获取频道 API 权限 | `GET` | `/guilds/{guild_id}/api_permission` | — |
|
|
39
|
+
|
|
40
|
+
### 子频道(Channel)
|
|
41
|
+
|
|
42
|
+
| 操作 | 方法 | 路径 | 参数说明 |
|
|
43
|
+
|------|------|------|----------|
|
|
44
|
+
| 获取子频道列表 | `GET` | `/guilds/{guild_id}/channels` | — |
|
|
45
|
+
| 获取子频道详情 | `GET` | `/channels/{channel_id}` | — |
|
|
46
|
+
| 创建子频道 | `POST` | `/guilds/{guild_id}/channels` | body: `name`\*, `type`\*, `position`\*, `sub_type`, `parent_id`, `private_type`, `private_user_ids`, `speak_permission`, `application_id` |
|
|
47
|
+
| 修改子频道 | `PATCH` | `/channels/{channel_id}` | body: `name`, `position`, `parent_id`, `private_type`, `speak_permission`(至少一个) |
|
|
48
|
+
| 删除子频道 | `DELETE` | `/channels/{channel_id}` | ⚠️ 不可逆 |
|
|
49
|
+
|
|
50
|
+
**子频道类型(type)**:`0`=文字, `2`=语音, `4`=分组(position≥2), `10005`=直播, `10006`=应用, `10007`=论坛
|
|
51
|
+
|
|
52
|
+
### 成员(Member)
|
|
53
|
+
|
|
54
|
+
| 操作 | 方法 | 路径 | 参数说明 |
|
|
55
|
+
|------|------|------|----------|
|
|
56
|
+
| 获取成员列表 | `GET` | `/guilds/{guild_id}/members` | query: `after`(首次填0), `limit`(1-400) |
|
|
57
|
+
| 获取成员详情 | `GET` | `/guilds/{guild_id}/members/{user_id}` | — |
|
|
58
|
+
| 获取身份组成员列表 | `GET` | `/guilds/{guild_id}/roles/{role_id}/members` | query: `start_index`(首次填0), `limit`(1-400) |
|
|
59
|
+
| 获取在线成员数 | `GET` | `/channels/{channel_id}/online_nums` | — |
|
|
60
|
+
|
|
61
|
+
### 公告(Announces)
|
|
62
|
+
|
|
63
|
+
| 操作 | 方法 | 路径 | 参数说明 |
|
|
64
|
+
|------|------|------|----------|
|
|
65
|
+
| 创建公告 | `POST` | `/guilds/{guild_id}/announces` | body: `message_id`, `channel_id`, `announces_type`(0=成员,1=欢迎), `recommend_channels`(最多3条) |
|
|
66
|
+
| 删除公告 | `DELETE` | `/guilds/{guild_id}/announces/{message_id}` | message_id 设 `all` 删除所有 |
|
|
67
|
+
|
|
68
|
+
### 论坛(Forum)— 仅私域机器人
|
|
69
|
+
|
|
70
|
+
| 操作 | 方法 | 路径 | 参数说明 |
|
|
71
|
+
|------|------|------|----------|
|
|
72
|
+
| 获取帖子列表 | `GET` | `/channels/{channel_id}/threads` | — |
|
|
73
|
+
| 获取帖子详情 | `GET` | `/channels/{channel_id}/threads/{thread_id}` | — |
|
|
74
|
+
| 发表帖子 | `PUT` | `/channels/{channel_id}/threads` | body: `title`\*, `content`\*, `format`(1=文本,2=HTML,3=Markdown,4=JSON,默认3) |
|
|
75
|
+
| 删除帖子 | `DELETE` | `/channels/{channel_id}/threads/{thread_id}` | ⚠️ 不可逆 |
|
|
76
|
+
| 发表评论 | `POST` | `/channels/{channel_id}/threads/{thread_id}/comment` | body: `thread_author`\*, `content`\*, `thread_create_time`, `image` |
|
|
77
|
+
|
|
78
|
+
### 日程(Schedule)
|
|
79
|
+
|
|
80
|
+
| 操作 | 方法 | 路径 | 参数说明 |
|
|
81
|
+
|------|------|------|----------|
|
|
82
|
+
| 创建日程 | `POST` | `/channels/{channel_id}/schedules` | body: `{ schedule: { name*, start_timestamp*, end_timestamp*, jump_channel_id, remind_type } }` |
|
|
83
|
+
| 修改日程 | `PATCH` | `/channels/{channel_id}/schedules/{schedule_id}` | body: `{ schedule: { name*, start_timestamp*, end_timestamp*, jump_channel_id, remind_type } }` |
|
|
84
|
+
| 删除日程 | `DELETE` | `/channels/{channel_id}/schedules/{schedule_id}` | ⚠️ 不可逆 |
|
|
85
|
+
|
|
86
|
+
**提醒类型(remind_type)**:`"0"`=不提醒, `"1"`=开始时, `"2"`=5分钟前, `"3"`=15分钟前, `"4"`=30分钟前, `"5"`=60分钟前
|
|
87
|
+
|
|
88
|
+
> `*` 表示必填参数
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 💡 调用示例
|
|
93
|
+
|
|
94
|
+
### 获取频道列表
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"method": "GET",
|
|
99
|
+
"path": "/users/@me/guilds",
|
|
100
|
+
"query": { "limit": "100" }
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 获取子频道列表
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"method": "GET",
|
|
109
|
+
"path": "/guilds/123456/channels"
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 创建子频道
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"method": "POST",
|
|
118
|
+
"path": "/guilds/123456/channels",
|
|
119
|
+
"body": {
|
|
120
|
+
"name": "新频道",
|
|
121
|
+
"type": 0,
|
|
122
|
+
"position": 1,
|
|
123
|
+
"sub_type": 0
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 获取成员列表(分页)
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"method": "GET",
|
|
133
|
+
"path": "/guilds/123456/members",
|
|
134
|
+
"query": { "after": "0", "limit": "100" }
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 发表论坛帖子
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"method": "PUT",
|
|
143
|
+
"path": "/channels/789012/threads",
|
|
144
|
+
"body": {
|
|
145
|
+
"title": "公告标题",
|
|
146
|
+
"content": "# 标题\n\n公告内容",
|
|
147
|
+
"format": 3
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 创建日程
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"method": "POST",
|
|
157
|
+
"path": "/channels/456789/schedules",
|
|
158
|
+
"body": {
|
|
159
|
+
"schedule": {
|
|
160
|
+
"name": "周会",
|
|
161
|
+
"start_timestamp": "1770733800000",
|
|
162
|
+
"end_timestamp": "1770737400000",
|
|
163
|
+
"remind_type": "2"
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 创建推荐子频道公告
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"method": "POST",
|
|
174
|
+
"path": "/guilds/123456/announces",
|
|
175
|
+
"body": {
|
|
176
|
+
"announces_type": 0,
|
|
177
|
+
"recommend_channels": [
|
|
178
|
+
{ "channel_id": "789012", "introduce": "欢迎来到攻略频道" }
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 删除所有公告
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"method": "DELETE",
|
|
189
|
+
"path": "/guilds/123456/announces/all"
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 🔄 常用操作流程
|
|
196
|
+
|
|
197
|
+
### 获取频道和子频道信息
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
1. GET /users/@me/guilds → 获取频道列表,拿到 guild_id
|
|
201
|
+
2. GET /guilds/{guild_id}/channels → 获取子频道列表,拿到 channel_id
|
|
202
|
+
3. GET /channels/{channel_id} → 获取子频道详情
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 论坛发帖 + 评论
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
1. GET /guilds/{guild_id}/channels → 找到论坛子频道(type=10007)
|
|
209
|
+
2. PUT /channels/{channel_id}/threads → 发表帖子
|
|
210
|
+
3. GET /channels/{channel_id}/threads → 获取帖子列表
|
|
211
|
+
4. GET /channels/{channel_id}/threads/{thread_id} → 获取帖子详情(含 author_id)
|
|
212
|
+
5. POST /channels/{channel_id}/threads/{thread_id}/comment → 发表评论
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 成员管理
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
1. GET /users/@me/guilds → 获取 guild_id
|
|
219
|
+
2. GET /guilds/{guild_id}/members?after=0&limit=100 → 获取成员列表
|
|
220
|
+
翻页:用上次最后一个 user.id 作为 after,直到返回空数组
|
|
221
|
+
3. GET /guilds/{guild_id}/members/{user_id} → 获取指定成员详情
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### 展示成员头像
|
|
225
|
+
|
|
226
|
+
成员详情返回的 `user.avatar` 是头像 URL,**必须使用 Markdown 图片语法展示**,让用户直接看到头像图片,而非纯文本链接:
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
成员信息:
|
|
230
|
+
· 昵称:{nick}
|
|
231
|
+
· 头像:
|
|
232
|
+

|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
> **禁止**将头像 URL 作为纯文本或超链接展示(如 `查看头像`),必须用 `` 语法内联显示。频道的 `icon` 字段同理。
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 🚨 错误码处理
|
|
240
|
+
|
|
241
|
+
| 错误码 | 说明 | 解决方案 |
|
|
242
|
+
|--------|------|----------|
|
|
243
|
+
| **401** | Token 鉴权失败 | 检查 AppID 和 ClientSecret 配置 |
|
|
244
|
+
| **11241** | 频道 API 无权限 | 前往 QQ 开放平台申请权限,或调用 `GET /guilds/{guild_id}/api_permission` 查看可用权限 |
|
|
245
|
+
| **11242** | 仅私域机器人可用 | 需在 QQ 开放平台将机器人切换为私域模式 |
|
|
246
|
+
| **11243** | 需要管理频道权限 | 确保机器人拥有管理权限 |
|
|
247
|
+
| **11281** | 日程频率限制 | 单管理员/天限 10 次,单频道/天限 100 次 |
|
|
248
|
+
| **304023** | 推荐子频道超限 | 推荐子频道最多 3 条 |
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## ⚠️ 注意事项
|
|
253
|
+
|
|
254
|
+
1. **路径中的占位符**(如 `{guild_id}`、`{channel_id}`)必须替换为实际值
|
|
255
|
+
2. **query 参数的值必须为字符串类型**,如 `{ "limit": "100" }` 而非 `{ "limit": 100 }`
|
|
256
|
+
3. **成员列表翻页**时可能返回重复成员,需按 `user.id` 去重
|
|
257
|
+
4. **公告**的两种类型(消息公告和推荐子频道公告)会互相顶替
|
|
258
|
+
5. **日程**的时间戳为毫秒级字符串
|
|
259
|
+
6. **删除操作不可逆**,请谨慎使用
|
|
260
|
+
7. **论坛操作**仅私域机器人可用
|
|
261
|
+
8. **子频道分组**(type=4)的 `position` 必须 >= 2
|
|
262
|
+
9. **日程操作**有频率限制:单个管理员每天 10 次,单个频道每天 100 次
|
|
263
|
+
10. **头像/图标展示**:成员 `user.avatar` 和频道 `icon` 等图片 URL 必须使用 Markdown 图片语法 `` 展示,禁止作为纯文本或超链接展示
|