群应用与群数据同步

服务端 API 更新于 2026-09-21 阅读 11

阅读指引:本篇是《开放平台服务端 API 指南》的第 11 部分。接口基础地址、通用约定与各接口请求限制,请先阅读《服务端 API 概览》。

14. 群应用与群数据同步

群应用是“真实应用与某一个群之间的授权关系”。群主或群管理员在客户端把一个已发布、已获授 group:app 的真实应用添加到群后,该应用才可以读取该群的最小信息、同步成员,并以应用身份向该群发送消息。

Scope 与群关系必须同时成立有效 App Token 包含 group:app,只能证明应用具备群应用能力;目标群仍必须存在 active 绑定关系。应用实时 Scope 被撤销、应用不再是已发布状态或群关系被移除时,即使旧 Token 仍带有该 Scope,也不能继续访问。

14.1 能力边界与生命周期

  • 群应用不是群成员,不出现在群成员列表、不占群人数,也没有群主或管理员角色。
  • 应用只能读取本文明确列出的群 ID、名称、变化时间以及成员 ID、群内名称和角色;不能读取群聊历史、公告、头像、群设置或组织扩展信息。
  • 应用不能修改群资料、邀请、移除或修改群成员,也不能自行添加到群、搜索或枚举未绑定群。
  • 应用快捷方式不是独立应用身份,不能作为群应用添加;群关系绑定真实主应用 ID。
  • Webhook 不是群应用的准入条件,只是变化加速通知;没有 Webhook 时仍可完整使用游标同步。
  • 群主或管理员移除应用后,读取和发送权限立即失效。应用下架或删除会移除全部 active 群关系,且不保证再向已下架应用发送 removed Webhook;重新上架不会恢复,必须由各群重新添加。
  • 暂停的部门群保留已有绑定,应用仍可读取和同步当前群数据,但不能发送应用群消息;恢复后原关系继续生效。
管理员授予应用 group:app
  → 群主/群管理员在客户端添加真实应用
  → 应用用 App Token 调用 groups/changes
  → 获取群信息并全量同步成员
  → 保存 next_cursor,持续增量同步
  → Webhook 到达时只负责唤醒同步

14.2 增量获取应用的群

GET /openapi/v1/groups/changes?cursor=&limit=

首次调用省略 cursor,平台按群 ID 分页返回当前所有 active 群。全量页读取结束后,继续保存并使用最后的 next_cursor,后续调用自动进入增量模式,返回新增、变化和已移除群。

curl "${OPENAPI_BASE_URL}/openapi/v1/groups/changes?limit=50" \
  -H "Authorization: Bearer ${APP_ACCESS_TOKEN}"

{
  "code": 200,
  "message": "",
  "data": {
    "groups": [
      {
        "group_id": "20001",
        "relation_version": 3,
        "group_updated_at": 1789027000000,
        "member_updated_at": 1789027200123
      }
    ],
    "removed_group_ids": [],
    "next_cursor": "opaque_cursor",
    "has_more": false
  },
  "request_id": "request_xxx"
}
字段 类型 含义
groups[].group_id string 当前 active 绑定群 ID。
groups[].relation_version integer 添加或移除关系版本;与本地记录不同应视为一次新授权,并重新全量同步成员。
groups[].group_updated_at integer 群基本信息最后变化时间,Unix 毫秒;变化时重新获取群信息。
groups[].member_updated_at integer 群成员基本信息最后变化时间,Unix 毫秒;变化时继续成员增量同步。
removed_group_ids string[] 已经失效的群关系;停止该群任务并删除不再需要的本地群数据。
next_cursor string 不透明游标;必须原样保存,不能解析、修改或跨应用复用。
has_more boolean true 时立即使用本页 next_cursor 继续取下一页;false 时保存游标供下次轮询。

limit 省略时为 50,可填写 1~200。query 只能包含一个 cursor 和一个 limit;重复参数、未知参数、空或超限 limit 都返回无效请求。即使使用 Webhook,也应定期调用本接口兜底。

14.3 获取群基本信息

GET /openapi/v1/groups/info?group_id=

curl "${OPENAPI_BASE_URL}/openapi/v1/groups/info?group_id=20001" \
  -H "Authorization: Bearer ${APP_ACCESS_TOKEN}"

{
  "code": 200,
  "message": "",
  "data": {
    "group_id": "20001",
    "name": "产品研发群",
    "group_updated_at": 1789027000000,
    "member_updated_at": 1789027200123
  },
  "request_id": "request_xxx"
}

group_id 必须且只能出现一次,并使用十进制正整数字符串。接口只返回上述四个字段;群主通过成员接口的 role=owner 识别。群不存在、未绑定或关系已失效时统一返回 group_not_available,不会透露该群是否真实存在。

14.4 全量或增量获取群成员

GET /openapi/v1/groups/members?group_id=&cursor=&limit=

第一次同步某个群时省略 cursor,按用户 ID 分页获取全量成员;全量结束后继续保存最后的 next_cursor,后续调用进入增量模式。

{
  "code": 200,
  "message": "",
  "data": {
    "members": [
      {"user_id": "9001", "name": "张三", "role": "admin"}
    ],
    "removed_user_ids": ["9002"],
    "next_cursor": "opaque_member_cursor",
    "has_more": false,
    "full_sync_required": false
  },
  "request_id": "request_xxx"
}
字段 类型 含义
members[].user_id string 当前成员用户 ID。
members[].name string 群内显示名称。
members[].role string owneradminmember
removed_user_ids string[] 增量阶段已移除的用户;从该群本地成员快照删除。
next_cursor string 绑定当前应用、群和关系版本的不透明游标。
has_more boolean true 时继续读取下一页。
full_sync_required boolean true 表示关系版本变化或历史增量已不可连续读取;丢弃该群旧 cursor 和临时快照,从无 cursor 开始全量重建。

成员数据刻意收敛,不返回头像、手机号、邮箱、性别、备注、禁言、组织归属或部门群成员来源。limit 默认 50、最大 200;query 只允许 group_id/cursor/limit

14.5 推荐同步算法

  1. 持久化应用级 groups_cursor,首次为空;循环调用 groups/changes 直到 has_more=false
  2. 对每个新增群或 relation_version 变化的群,读取 groups/info,清空旧成员 cursor,从无 cursor 开始全量成员同步。
  3. group_updated_at 变化时重新读取群信息;member_updated_at 变化时用该群已完成的成员 cursor 继续增量读取。
  4. 收到 removed_group_ids 时立即停止访问并清理本地数据,不再调用该群 info/members。
  5. 成员响应 full_sync_required=true 时,不提交旧 cursor 重试;必须重新全量构建临时快照,完成全部分页后再原子替换正式快照。
  6. 只有一页处理和本地提交都成功后才保存该页 next_cursor;失败时使用原 cursor 重试,避免漏数据。

14.6 HTTP 状态与错误码

HTTP code message 处理
400 170800 invalid_request 修正 query、ID、limit 或游标;不要原样无限重试。
401/403 Token/Scope 相关码 按鉴权响应 重新取得 App Token,或确认管理员仍授予 group:app
404 170801 group_not_available 群不存在、未绑定或关系已失效;停止该群任务并通过 changes 收敛。
409 170802 full_sync_required 如果接口返回该兼容错误,丢弃旧游标并重新全量;成员接口成功响应中的同名布尔字段也按此处理。
503 170803 group_service_unavailable 保留已完成快照和原 cursor,有限次数指数退避。

成员同步要求优先检查 full_sync_required:当前关系版本变化或增量历史不连续时,返回 HTTP 200、code=200full_sync_required=true,此时 next_cursor 可为空。不要只等待 409。签名密钥轮换后旧游标会返回 400 / 170800;清空应用群列表游标及各群成员游标,从全量重新开始。

全量分页不是冻结快照;读完后保存游标并继续增量轮询以追平期间变化。群列表和各群成员分别维护游标,不能交叉使用。全量重建使用临时快照,完成后以新快照替换旧集合,不能只做新增合并,否则已移除对象会残留。

14.7 群主和管理员如何管理群应用

添加、查看和移除群应用是 Matrix 客户端登录态下的群管理能力,不是应用 OpenAPI。应用后端不能调用本文的 OpenAPI 把自己加入群,也不能取得“可添加群列表”。客户端侧遵循以下规则:

  • 当前群成员可以获取该群完整的应用 ID 列表;应用详情复用客户端已有应用数据。
  • 只有群主或群管理员可以添加、移除,一次操作一个真实应用 ID;用户身份和角色由服务端登录态判断。
  • 添加时服务端校验应用已发布、未删除且实时具备 group:app;重复添加和重复移除按幂等语义处理。
  • 管理操作成功不代表应用 Webhook 已送达。应用以 groups/changes 返回的当前状态作为最终依据。