# IM 测试环境接口审核报告(2026-08-20) ## 1. 审核范围 - 对照文档:`docs/IM-前后端对接文档.md` - 测试环境:`https://api.118im.com` - WebSocket:`wss://api.118im.com/v0/channels` - API Key:已使用测试环境普通 Key,报告中不展开。 - 租户:`default` - 测试账号:本轮通过短信验证码固定码 `123456` 和 WebSocket `{acc}` 临时注册,用户 ID `usrIPhpZJeJDMI`。 - 本轮只新增本报告,不修改原前后端对接文档。 ## 2. 总体结论 测试环境已能跑通基础启动、注册、登录、bootstrap、通讯录空列表、建群、工作台、日报/月报草稿、个人资料、隐私、反馈、设备推送 Token 等主链路。整体方向和产品需求基本匹配:Tinode WebSocket 承担消息与 Topic,`/v1/im/*` 承担产品化业务接口。 但当前仍不建议直接按整份对接文档全量联调。主要风险是:部分文档接口没有路由或路由兜底错误,部分配置类接口在测试库空数据时返回 500/502,部分通用响应约定没有统一落到所有列表接口,办公协同和转发/群文件相关接口还存在明显缺口。 ## 3. P0/P1 问题 处理备注(2026-08-20): - 已在提交 `6c6d2f6 fix: stabilize im audit endpoints` 中处理本节前 6 项,以及 `bootstrap.limits` 缺失问题。 - 已用本地 Docker 启动服务并调用本地 API 验证通过;测试环境需发布该提交后再复测公网结果。 - 当前短信供应商未接入时,注册、找回密码和敏感操作验证码均按测试码 `123456` 验证;生产接入短信供应商后应切回真实短信策略。 | 优先级 | 问题 | 测试结果 | 影响 | 建议 | | --- | --- | --- | --- | --- | | P0 | 密码重置发码 `scene=reset_password` 返回 502 | `POST /v1/im/auth/verification-codes`,Body `{"scene":"reset_password","phone":"15509271990"}`,带 `Idempotency-Key`,返回 Cloudflare `502` | 忘记密码无法联调,且不是统一 JSON 错误 | 已处理:短信未接入时保留 challenge,并用测试码 `123456` 验证;本地 API 验证返回 200 | | P0 | 登录后二次身份验证挑战返回 502 | `POST /v1/im/security/challenges`,Body `{"scene":"close_youth_mode","channel":"sms"}`,带 `Idempotency-Key`,返回 Cloudflare `502` | 关闭青少年模式、敏感操作二次验证不可用 | 已处理:短信发送失败不再使 challenge 失败;带 `Idempotency-Key` 创建和 `123456` verify 本地均返回 200 | | P0 | 总经理信箱配置和提交返回 500 | `GET /v1/im/executive-mailbox/config` 返回 `INTERNAL_ERROR`;按文档提交也返回 500 | 工作台入口开启但页面不可用 | 已处理:修复 `im_mailbox_config`、`im_mailbox_submissions` 的 `SELECT *` 映射问题;本地 config/submit 均返回 200 | | P1 | 举报原因返回 500 | `GET /v1/im/reports/abuse/reasons?target_type=user` 返回 `INTERNAL_ERROR` | 举报页无法打开 | 已处理:补齐 `AbuseReason` 数据库字段映射;本地返回 200 和 `items` | | P1 | 转发目标接口不存在 | `GET /v1/im/forward-targets?query=` 返回 404 | 4.17~4.20 转发目标页无法联调 | 已处理:新增 `/v1/im/forward-targets`,返回文件助手和可转发的 P2P/群会话;本地返回 200 | | P1 | 群文件接口被群详情兜底吞掉 | `GET /v1/im/groups/{topic}/files` 返回群详情 JSON,而不是文件列表或 404 | 前端会误判接口成功,群文件页数据结构错误 | 已处理:未知一级 tail 不再落到群详情;`/files` 未实现时本地返回 404 | ## 4. 章节审核 ### 0. 公共对接约定 通过项: - `POST /v1/im/tenants/resolve` 可未登录调用,返回统一 `code/data/request_id/server_time`。 - `endpoints` 已返回正确公网地址:`https://api.118im.com/v1/im`、`wss://api.118im.com/v0/channels`、`https://api.118im.com/v0/file`。 - 缺 token 访问 `GET /v1/im/bootstrap` 返回统一 JSON:`401 AUTH_REQUIRED`。 问题: - 公共约定写分页统一返回 `items,next_cursor,has_more`,但很多接口只返回 `items,next_cursor`,例如 `friends`、`friend-requests`、`system-notifications`、`favorites`、`calls`。 - 写请求确实依赖 `Idempotency-Key`,但部分章节没有重复强调;前端实现时必须按公共约定统一加。 ### 1. 账号注册、登录与身份安全 通过项: - 企业解析通过,且不泄漏 `tenant_id`。 - 注册短信发码通过:返回 `challenge_id/expires_in_seconds/resend_after_seconds/phone_mask`。 - 固定验证码 `123456` 验证通过:返回 `verification_token`。 - WebSocket `hi(tenant=default)` 返回 `201`,`acc user:new login:true` 注册成功,返回 `user/token/expires/username`。 - `GET /v1/im/security/realname` 返回 `status=unverified, can_submit=true`。 问题: - 已处理待发版复测:`reset_password` 发码不再因短信供应商未接入返回 502,本地返回 200。 - 已处理待发版复测:`POST /v1/im/security/challenges` 不再因短信供应商未接入返回 502,本地创建和校验均返回 200。 - 文档目标错误 reason 很完整,但 WS 登录/注册仍主要是 Tinode `ctrl.text/code`;稳定 `params.reason` 是否全链路返回还需要继续核。 ### 2. 消息首页、全局导航与系统通知 通过项: - `GET /v1/im/bootstrap` 已返回 `features/permissions/message_policy/security/modules/system_topic`。 - 最新测试环境已补 `entries` 和 `entry_badges`,包括 `new_friends/groups/file_assistant/system_messages` 入口与未读数字段,能支撑通讯录和首页入口显示。 - `GET /v1/im/system-notifications?limit=5` 返回 `items,next_cursor`。 - `GET /v1/im/search/conversations?q=a` 可返回已创建群会话,包含 `seq/read/unread/public/private`。 问题: - 已处理待发版复测:`bootstrap` 已补 `limits.max_file_size/max_text_length/max_forward_targets`,本地返回 200。 - 系统通知没有聚合未读接口,当前依赖 `bootstrap.entry_badges.system_unread_count`,需要确认其真实计算来源和实时更新事件。 ### 3. 单聊会话、会话建立与消息状态 通过项: - 路由存在 `GET /v1/im/conversations/{topic}/context`。 - 好友申请接口存在:`POST/GET /v1/im/friend-requests`,列表空数据返回正常。 - 好友列表 `GET /v1/im/friends` 返回正常空列表。 问题: - 文档出现 `POST /v1/im/conversations/p2p`、`GET /v1/im/conversations/{topic}/messages`、`PATCH /v1/im/conversations/{topic}/settings`,路由清单未看到对应明确 handler,需要进一步实测或补实现。 - 单聊发送约束最终仍要靠 WebSocket `pub` 校验,HTTP 文档里的关系状态和 WS 发布路径需要做端到端用例。 ### 4. 消息输入、媒体内容与消息操作 通过项: - 收藏基础接口存在,`GET /v1/im/favorites?limit=5` 正常返回空列表。 - 消息撤回/编辑/回执类路由挂在 `/v1/im/topics/` 下,代码有统一 handler。 问题: - 已处理待发版复测:`GET /v1/im/forward-targets?query=` 已新增,本地返回 200。 - 文档里的 `POST /v1/im/messages/forward`、`GET /v1/im/forward-bundles/{bundle_id}` 未在路由表看到。 - 文件上传仍主要使用 `/v0/file`,但业务 `purpose`、附件 ACL、群文件登记接口还没有从测试结果证明可用。 - 已处理待发版复测:`bootstrap.limits.max_forward_targets/max_file_size/max_text_length` 本地已返回。 ### 5. 通讯录、好友关系与黑名单 通过项: - `GET /v1/im/friends`、`GET /v1/im/friend-requests`、`GET /v1/im/blocks` 均返回统一成功空列表。 - `GET /v1/im/users/search` 可调用,空结果返回 `items:[]`。 - `bootstrap.entries.new_friends` 和 `entry_badges.new_friends_pending_count` 已能控制入口和未处理数。 问题: - 本轮新注册用户搜索自己的 username 返回空列表,可能是“排除自己”的合理策略,也可能是搜索索引/隐私导致,需要用第二个用户互搜确认。 - 新朋友未处理数现在在 `bootstrap.entry_badges` 返回,但需要确认好友申请创建/处理后是否实时准确更新。 ### 6. 群聊创建、资料维护与成员治理 通过项: - `POST /v1/im/groups` 已支持截图里的 `name + description` 创建群聊,返回 `topic/name/description/owner/member_count/version/permissions`。 - `GET /v1/im/groups`、`GET /v1/im/groups/{topic}`、`GET /summary`、`GET /members`、`POST /qrcodes`、`GET /governance`、`GET /role-limits`、`GET /mutes` 均可用。 - 群二维码返回 `qr_token/qr_payload/expires_at/group_snapshot`,符合需求。 问题: - `GET /v1/im/groups/{topic}/members` 返回的 owner 成员 `user_id` 为空字符串,这不适合前端成员列表和后续管理员/转让操作,应返回 `usr...`。 - 已处理待发版复测:`GET /v1/im/groups/{topic}/files` 不再返回群详情,本地返回 404。 - 已处理待发版复测:`GET /v1/im/groups/{topic}/announcements` 不再返回群详情,未知一级 tail 统一返回 404。 - 文档里的 `POST /v1/im/group-invitations/{invitation_id}/accept` 未在路由表看到;当前更像是走群内 `/invitations` 和扫码 join-request。 ### 7. 文件下载、收藏管理与聊天记录检索 通过项: - `GET /v1/im/favorites` 可用。 - 收藏批量、删除、转发相关 handler 在 `/favorites` 和 `/favorites/` 下存在。 问题: - 群文件接口不可用,且被错误兜底。 - 文档中的聊天记录搜索、媒体筛选、上下文接口挂在 `/v1/im/topics/{topic}/...`,需要有真实消息后再端到端验证;本轮未创建聊天消息。 - 文件下载鉴权复用 `/v0/file`,本轮未上传真实附件,ACL 未验证。 ### 8. 实时语音与视频通话 通过项: - `GET /v1/im/calls?limit=5` 返回正常空列表。 - 文档对通话主体设计合理:WebSocket 信令为主,HTTP 只做记录查询。 问题: - 需要真机或至少两个 WS 用户做 call `started/ringing/accept/hang-up` 端到端;本轮只验证 HTTP 通话记录列表。 - Push、好友关系、拉黑、并发通话校验没有通过测试环境验证。 ### 9. 企业工作台与办公协同 通过项: - `GET /v1/im/workbench` 返回模块列表和 `layout_version`。 - `GET /v1/im/organization/departments` 返回正常空列表。 - 日报列表、日报统计、日报草稿创建通过。 - 月报列表、月报统计、月报草稿创建通过。 - 会议创建按文档 Body 通过。 问题: - `GET /v1/im/meetings?limit=5` 返回 405;文档没明确会议列表接口,但会议通知页面通常需要列表,设计上应补 `GET /v1/im/meetings`。 - `GET /v1/im/organization/search?q=` 空关键词返回 400;文档示例写 `q=`,需明确前端空关键词应不请求还是后端返回空列表。 - `GET /v1/im/executive-mailbox/config` 和提交均返回 500,总经理信箱不可联调。 - `modules[].unread_count` 当前全 0,需要确认是否真实 badge,还是静态占位。 ### 10. 个人资料、通用设置、隐私与青少年模式 通过项: - `GET /v1/im/me`、`GET /v1/im/me/profile`、`GET /v1/im/me/privacy`、`GET /v1/im/settings/youth-mode` 均可用。 - `POST /v1/im/me/qrcodes` 可用,返回 `qr_token/qr_payload/display_profile/expires_at`。 - `PUT /v1/im/devices/{device_id}/push-token` 可用,能登记 APNs 测试 token。 - `GET /v1/im/app/releases/latest?platform=ios&version=1.0.0` 可用。 问题: - 文档写应用更新参数为 `current_version`,测试使用 `version` 也能返回;实现似乎不消费当前版本参数,建议统一字段名,避免客户端多套逻辑。 - 青少年模式关闭依赖二次验证,而二次验证挑战当前 502。 - Android 系统权限说明多为客户端能力,本轮无法通过服务端验证。 ### 11. 反诈安全、举报与意见反馈 通过项: - `POST /v1/im/security/urls/check` 可用,安全 URL 返回 `decision=allow/risk_level=low`。 - `GET /v1/im/feedback/config` 可用。 - `POST /v1/im/feedback` 可用,返回 `feedback_id/status=received`。 问题: - `GET /v1/im/reports/abuse/reasons?target_type=user` 返回 500,举报页阻塞。 - 风控 challenge confirm 路由存在,但需要先有业务接口返回 `RISK_CONFIRMATION_REQUIRED` 后才能完整验证。 - 举报提交需要真实目标对象和原因数据,本轮因原因接口 500 未继续提交。 ### 12. 联调实施清单 建议把当前验收顺序调整为: 1. 已处理待发版复测:密码重置 502、二次验证 502、总经理信箱 500、举报原因 500。 2. 部分已处理待发版复测:转发目标已补、群文件路径错误兜底已修;消息转发/Forward Bundle 缺路由、群成员 `user_id` 为空仍待处理。 3. 统一公共协议:所有列表是否必须返回 `has_more`;所有写接口是否都必须 `Idempotency-Key`;`bootstrap.limits` 是否需要补。 4. 两用户端到端:好友申请、同意、P2P context、普通消息、已读、拉黑、删除好友。 5. 群端到端:邀请成员、入群审批、公告、群文件、管理员、禁言、群主转让。 6. 真机端到端:文件上传下载、APNs/FCM 推送、WebRTC 通话。 ## 5. 代表性实测结果 | 接口 | 方法 | 状态 | 结论 | | --- | --- | --- | --- | | `/v1/im/tenants/resolve` | POST | 200 | 企业解析正常,endpoint host 正确 | | `/v1/im/auth/verification-codes` register | POST | 200 | 注册发码正常 | | `/v1/im/auth/verification-codes/{id}/verify` | POST | 200 | 固定验证码 `123456` 正常 | | WebSocket `hi + acc` | WS | 201/200 | 注册并登录成功 | | `/v1/im/auth/verification-codes` reset_password | POST | 502 | 已处理待发版复测;本地返回 200 | | `/v1/im/security/challenges` | POST | 502 | 已处理待发版复测;本地创建和 `123456` 校验返回 200 | | `/v1/im/bootstrap` | GET | 200 | 已包含 `entries/entry_badges`;已补 `limits` 待发版复测 | | `/v1/im/groups` | POST | 200 | 创建群聊含 `description` 正常 | | `/v1/im/groups/{topic}/members` | GET | 200 | 可用,但成员 `user_id` 为空 | | `/v1/im/groups/{topic}/files` | GET | 200 | 已处理待发版复测;未实现时本地返回 404,不再误返回群详情 | | `/v1/im/forward-targets` | GET | 404 | 已处理待发版复测;本地返回 200 | | `/v1/im/executive-mailbox/config` | GET | 500 | 已处理待发版复测;本地 config/submit 返回 200 | | `/v1/im/reports/abuse/reasons` | GET | 500 | 已处理待发版复测;本地返回 200 | | `/v1/im/feedback` | POST | 200 | 意见反馈提交正常 | | `/v1/im/devices/{device_id}/push-token` | PUT | 200 | 推送 token 登记正常 | ## 6. 本轮测试产生的数据 - 创建临时用户:`usrIPhpZJeJDMI` - 创建群:`grpcNdeRoa_VO0` - 创建会议:`mtg_vN4182ncLyi5wp4A` - 创建日报草稿:`dr_MdAFCj2fYTkBjiq8` - 创建月报草稿:`mr_eWjm2hpuzSsqcIcH` - 创建反馈:`fb_TEJYaStZn9i0JSun` - 登记设备:`audit-device` 这些数据均在测试租户 `default` 下,可按需要由测试库清理。