From 38f515a8ea2a1b6112152eedf2d26a96a7405e06 Mon Sep 17 00:00:00 2001 From: pangxiaoli Date: Wed, 28 Aug 2024 18:24:22 +0800 Subject: [PATCH] =?UTF-8?q?feat(node=20sdk):=20=E8=A1=A5=E5=85=85=E7=BE=A4?= =?UTF-8?q?=E8=81=8A=E5=8F=8A=E7=A7=81=E4=BF=A1=E7=9B=B8=E5=85=B3=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .yarnrc.yml | 1 + docs/develop/nodesdk/README.md | 3 + docs/develop/nodesdk/config.js | 14 ++- .../nodesdk/group_and_c2c/del_message.md | 32 ++++++ docs/develop/nodesdk/group_and_c2c/files.md | 82 ++++++++++++++ .../nodesdk/group_and_c2c/post_message.md | 104 ++++++++++++++++++ docs/develop/nodesdk/wss/model.md | 15 +++ package.json | 2 +- 9 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 .yarnrc.yml create mode 100644 docs/develop/nodesdk/group_and_c2c/del_message.md create mode 100644 docs/develop/nodesdk/group_and_c2c/files.md create mode 100644 docs/develop/nodesdk/group_and_c2c/post_message.md diff --git a/.gitignore b/.gitignore index 4fdf57af..0814b7c5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ node_modules dist/ package-lock.json yarn.lock +pnpm-lock.yaml yarn-error.log +.yarn # General .DS_Store diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 00000000..8b757b29 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules \ No newline at end of file diff --git a/docs/develop/nodesdk/README.md b/docs/develop/nodesdk/README.md index c75d9d16..3f74af53 100644 --- a/docs/develop/nodesdk/README.md +++ b/docs/develop/nodesdk/README.md @@ -156,6 +156,9 @@ ws.on('AUDIO_ACTION', (data) => { ws.on('PUBLIC_GUILD_MESSAGES', (data) => { console.log('[PUBLIC_GUILD_MESSAGES] 事件接收 :', data); }); +ws.on("GROUP_AND_C2C_EVENT", (data) => { + console.log("[GROUP_AND_C2C_EVENT] 事件接收 :", data); +}); ``` ### ws 返回示例 diff --git a/docs/develop/nodesdk/config.js b/docs/develop/nodesdk/config.js index 3fd18aab..1157cdf4 100644 --- a/docs/develop/nodesdk/config.js +++ b/docs/develop/nodesdk/config.js @@ -25,7 +25,7 @@ module.exports = { { title: '成员对象(Member)', path: 'model/member' }, { title: '频道身份组对象(Role)', path: 'model/role' }, { title: '消息对象(Message)', path: 'model/message' }, - {title: '消息按钮对象(InlineKeyboard)', path: 'model/inline_keyboard'}, + { title: '消息按钮对象(InlineKeyboard)', path: 'model/inline_keyboard' }, { title: '私信对象(DMS)', path: 'model/dms' }, { title: '公告对象(Announce)', path: 'model/announce' }, { title: '精华消息对象(PinsMessage)', path: 'model/pins_message.md' }, @@ -94,7 +94,7 @@ module.exports = { ], }, { - title: '消息 API', + title: '频道消息 API', collapsable: false, sidebarDepth: 0, children: [ @@ -109,7 +109,7 @@ module.exports = { ], }, { - title: '私信 API', + title: '频道私信 API', collapsable: false, sidebarDepth: 0, children: ['dms/post_dms.md', 'dms/post_dms_messages.md'], @@ -170,7 +170,13 @@ module.exports = { title: '接口权限 API', collapsable: false, sidebarDepth: 0, - children: ['api_permissions/get_permissions','api_permissions/post_permission.md'], + children: ['api_permissions/get_permissions', 'api_permissions/post_permission.md'], + }, + { + title: 'QQ 群和私聊 API', + collapsable: false, + sidebarDepth: 0, + children: ['group_and_c2c/post_message', 'group_and_c2c/files.md', 'group_and_c2c/del_message'], }, ], }, diff --git a/docs/develop/nodesdk/group_and_c2c/del_message.md b/docs/develop/nodesdk/group_and_c2c/del_message.md new file mode 100644 index 00000000..a6a1a7f2 --- /dev/null +++ b/docs/develop/nodesdk/group_and_c2c/del_message.md @@ -0,0 +1,32 @@ +# 撤回消息 + +## 功能描述 + +用于撤回机器人发送给当前用户 openid 的消息 message_id,发送超出2分钟的消息不可撤回 + +## 使用示例 + +```js +/** 单聊 */ +async function demo() { + const res = await client.C2cAPI.delMessage(openid, message_id); +} + +/** 群聊 */ +async function demo() { + const res = await client.GroupAPI.delMessage(group_openid, message_id); +} +``` + +## 参数说明 + +| 字段名 | 必填 | 类型 | 描述 | +| ------- | ---- | -------------------------------------------------------------- | ---------------------------------------------------- | +| openid | 是(单聊) | string | QQ 用户的 openid,可在各类事件中获得。 | +| group_openid | 是(群聊) | string | 群号,可在各类事件中获得。| +| message_id | 是 | string | 消息id | + + +## 返回参数 + +成功返回 HTTP 状态码 200。 diff --git a/docs/develop/nodesdk/group_and_c2c/files.md b/docs/develop/nodesdk/group_and_c2c/files.md new file mode 100644 index 00000000..006a63a1 --- /dev/null +++ b/docs/develop/nodesdk/group_and_c2c/files.md @@ -0,0 +1,82 @@ +# 发送富媒体消息 + +## 功能描述 + +仅用于在QQ单聊和QQ群聊内,发送图片、视频、语音、文件的相关富媒体资源在消息收发的候使用。 本接口有以下两种使用方式: + +- 当 `srv_send_msg = true` 时,消息会直接发送到目标端,占用 主动消息频次,超频会发送失败。 + +- 当 `srv_send_msg = false` 时,消息不会直接发送到目标端,返回的 file_info 字段数据,可使用在消息发送接口 `media` 字段中,`file_info` 有 过期时间 ,开发者需要自行维护有效期,过期需要重新获得新的 `file_info`,`file_info` 不受发送的目标端影响,一个 `file_info` 可复用发送到多个群或多个用户(注意:用 `GroupAPI` 上传的文件,仅能发到群聊内,用 `C2cAPI` 上传的文件,也仅能发送到单聊)。 + +推荐使用第 2 种方式 + +## 使用示例 + +- 单聊 +```js +async function demo() { + const res = await client.c2cApi.files('openid', { + file_type: 1, + url: '', + srv_send_msg: false, + }) + + const result = client.c2cApi.postMessage('openid', { + msg_type: 7, + media: { + file_info: res.data.file_info, + }, + msg_id: 'msg_id', + event_id: 'event_id', + }) +} +``` + +- 群聊 +```js +async function demo() { + const res = await client.groupApi.files('group_openid', { + file_type: 1, + url: '', + srv_send_msg: false, + }) + + const result = client.groupApi.postMessage('group_openid', { + msg_type: 7, + media: { + file_info: res.data.file_info, + }, + msg_id: 'msg_id', + event_id: 'event_id', + }) +} +``` + +## 参数说明 + +| 字段名 | 必填 | 类型 | 描述 | +| ------- | ---- | -------------------------------------------------------------- | ---------------------------------------------------- | +| openid | 是(单聊) | string | QQ 用户的 openid,可在各类事件中获得。 | +| group_openid | 是(群聊) | string | 群号,可在各类事件中获得。| +| TMedia | 是 | [TMedia](./post_message.md#tmedia) | 富媒体对象 | + + +## 返回参数 + +| 字段 | 类型 | 说明 | +|-----------|------------|----------------------------------------------------------------------| +| `file_uuid` | `string` | 文件 ID | +| `file_info` | `string` | 文件信息,用于发消息接口的 `media` 字段使用 | +| `ttl` | `number` | 有效期,表示剩余多少秒到期,到期后 `file_info` 失效,等于 `0` 时表示可长期使用 | +| `id` | `string` | 发送消息的唯一 ID,当 `srv_send_msg` 设置为 `true` 时返回 | + +## 返回示例 + +```json +{ + "file_uuid": "f3d2f5b7-7f3a-4d8a-9e2d-8e8d8e8e8e8e", + "file_info": "", + "ttl": 86400, + "id": "id" +} +``` diff --git a/docs/develop/nodesdk/group_and_c2c/post_message.md b/docs/develop/nodesdk/group_and_c2c/post_message.md new file mode 100644 index 00000000..1a94a79c --- /dev/null +++ b/docs/develop/nodesdk/group_and_c2c/post_message.md @@ -0,0 +1,104 @@ +# 发送消息 + +## 功能描述 + +- 主动消息与被动消息说明: QQ 用户可以在 QQ 客户端主动设置是否接收机器人发送的主动消息,如果设置了关闭,主动消息一律发送失败。 +- 单聊 + - 主动消息每月 4 条,超额会发送失败。(例如:给相同用户每月最多发 4 条) + - 被动消息(回复类)有效时间为 60 分钟,每个消息最多回复 5 次,超时或超频会发送(回复)失败; +- 群聊 + - 主动消息每月 4 条,超额会发送失败。(例如:给相同群每月最多发 4 条) + - 被动消息(回复类)有效时间为 5 分钟,每个消息最多回复 5 次,超时或超频会发送(回复)失败; + +## 使用示例 + +```js +/** 单聊 */ +async function demo() { + const res = await client.C2cAPI.postMessage(openid, message); +} + +/** 群聊 */ +async function demo() { + const res = await client.GroupAPI.postMessage(group_openid, message); +} +``` + +## 参数说明 + +| 字段名 | 必填 | 类型 | 描述 | +| ------- | ---- | -------------------------------------------------------------- | ---------------------------------------------------- | +| openid | 是(单聊) | string | QQ 用户的 openid,可在各类事件中获得。 | +| group_openid | 是(群聊) | string | 群号,可在各类事件中获得。| +| message | 是 | [TMessage](#tmessage) | 消息体 | + + +### `TMessage` + +| 字段 | 类型 | 说明 | +|-------------------|---------------------------|-------------------------------------------------------------------------------------------------------------| +| `content` | `string` | 文本内容 | +| `msg_type` | `0 \| 2 \| 3 \| 4 \| 7` | 消息类型:
**`0`** 文本
**`2`** markdown
**`3`** ark
**`4`** embed
**`7`** media 富媒体 | +| `markdown` | [`TMarkdown`](#tmarkdown) | Markdown 消息 | +| `keyboard` | [`TKeyboard`](#tkeyboard) | keyboard 消息 | +| `ark` | [`TArk`](#tark) | Ark 消息 | +| `media` | [`TMedia`](#tmedia) | 媒体数据 | +| `message_referance`| `unknown` | 消息引用
@future 暂未支持 | +| `event_id` | `string` | 前置收到的事件 ID,用于发送被动消息
支持事件:`INTERACTION_CREATE`、`C2C_MSG_RECEIVE` 等 | +| `msg_id` | `string` | 前置收到的用户发送过来的消息 ID,用于发送被动消息(回复) | +| `msg_seq` | `number` | 回复消息的序号,与 `msg_id` 联合使用,避免相同消息 ID 回复重复发送,不填默认是 `1` | + +### `TMessageResult` + +| 字段 | 类型 | 说明 | +|------------|------------|------------| +| `id` | `string` | 消息唯一 ID | +| `timestamp`| `number` | 发送时间 | + +### `TMarkdown` + +| 字段 | 类型 | 说明 | +|-------------------|------------------------------|--------------------------| +| `content` | `string` | 原生 markdown 文本内容 | +| `custom_template_id` | `string` | markdown 模版 id | +| `params` | `{ key: unknown; values: unknown }[]` | 模版内变量与填充值的 kv 映射 | + +### `TKeyboard` + +| 字段 | 类型 | 说明 | +|-------------------|------------------------------|--------------------------| +| `id` | `string` | 按钮 ID,在一个 keyboard 消息内设置唯一 | +| `render_data` | `{ label: string; visited_label: string; style: 0 \| 1; }` | 按钮渲染数据 | +| `action` | `{ type: 0 \| 1 \| 2; permission: { type: 0 \| 1 \| 2 \| 3; specify_user_ids?: string[]; specify_role_ids?: string[]; }; data: string; reply?: boolean; enter?: boolean; anchor?: number; click_limit?: number; at_bot_show_channel_list?: boolean; unsupport_tips: string; }` | 按钮操作数据 | + +### `TArk` + +| 字段 | 类型 | 说明 | +|-------------------|------------------------------|--------------------------| +| `template_id` | `number` | 模版 id,管理端可获得或内邀申请获得 | +| `kv` | `{ key: string; value: string }[] \| { key: string; obj: { obj_kv: { key: string; value: string }[] }[] }[]` | 模版内变量与填充值的 kv 映射 | + +### `TMedia` + +| 字段 | 类型 | 说明 | +|-------------------|------------------------------|--------------------------| +| `file_type` | `1 \| 2 \| 3 \| 4` | 媒体类型:
**`1`** 图片
**`2`** 视频
**`3`** 语音
**`4`** 文件(暂不开放) | +| `url` | `string` | 需要发送媒体资源的 url | +| `srv_send_msg` | `boolean` | 设置 `true` 会直接发送消息到目标端,且会占用主动消息频次 | +| `file_data` | `unknown` | @future 【暂未支持】 | +| `file_info` | `string` | 来自富媒体消息上传 | + +## 返回参数 +|属性|类型|说明| +|---|---|---| +|id|string|消息唯一ID| +|timestamp|number|发送时间| + +## 返回示例 + +```json +{ + "id": "", + "timestamp": 1688488488 +} +``` diff --git a/docs/develop/nodesdk/wss/model.md b/docs/develop/nodesdk/wss/model.md index 69ea6e9c..2108a42d 100644 --- a/docs/develop/nodesdk/wss/model.md +++ b/docs/develop/nodesdk/wss/model.md @@ -28,6 +28,18 @@ DIRECT_MESSAGE (1 << 12) - DIRECT_MESSAGE_CREATE // 当收到用户发给机器人的私信消息时 - DIRECT_MESSAGE_DELETE // 删除(撤回)消息事件 +GROUP_AND_C2C_EVENT (1 << 25) + - GROUP_ADD_ROBOT // 机器人被添加到群聊 + - GROUP_DEL_ROBOT // 机器人被移出群聊 + - GROUP_MSG_REJECT // 群管理员主动在机器人资料页操作关闭通知 + - GROUP_MSG_RECEIVE // 群管理员主动在机器人资料页操作开启通知 + - GROUP_AT_MESSAGE_CREATE // 用户在群聊@机器人发送消息 + - C2C_MESSAGE_CREATE // 用户在单聊发送消息给机器人 + - FRIEND_ADD // 用户添加机器人'好友'到消息列表 + - FRIEND_DEL // 用户删除机器人'好友' + - C2C_MSG_REJECT // 用户在机器人资料卡手动关闭"主动消息"推送 + - C2C_MSG_RECEIVE // 用户在机器人资料卡手动开启"主动消息"推送开关 + INTERACTION (1 << 26) - INTERACTION_CREATE // 互动事件创建时 @@ -99,6 +111,9 @@ ws.on('AUDIO_ACTION', data => { ws.on('PUBLIC_GUILD_MESSAGES', data => { console.log('[PUBLIC_GUILD_MESSAGES] 事件接收 :', data); }); +ws.on("GROUP_AND_C2C_EVENT", (data) => { + console.log("[GROUP_AND_C2C_EVENT] 事件接收 :", data); +}); ``` ### 接收到的通知示例 diff --git a/package.json b/package.json index 92531e3a..5c751ea1 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "sync-api": "node scripts/sync-inner-docs/index.js", "change-log": "node scripts/change-log.js", "build-tag": "node scripts/add-build-tag.js", - "postinstall":"patch-package" + "postinstall": "patch-package" }, "dependencies": { "async-validator": "1.11.5",