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",