5.7 KiB
5.7 KiB
Inbox Messages 协议
本文档定义 /api/v1/inbox/messages 的收件箱消息协议。
Base URL: /api/v1/inbox/messages
端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | `` | 获取消息列表 |
| PATCH | /{message_id}/read |
标记消息为已读 |
| GET | /stream |
订阅收件箱实时事件(SSE) |
枚举类型
InboxMessageType
| 值 | 说明 |
|---|---|
friend_request |
好友申请 |
calendar |
日历消息 |
system |
系统消息 |
group |
群组消息 |
InboxMessageStatus
| 值 | 说明 |
|---|---|
pending |
待处理 |
accepted |
已接受 |
rejected |
已拒绝 |
dismissed |
已忽略 |
消息内容类型
CalendarInviteContent (schema_version=2)
{
"type": "invite",
"schema_version": 2,
"item": {
"id": "uuid",
"title": "string",
"description": "string | null",
"start_at": "datetime",
"end_at": "datetime | null",
"timezone": "string"
},
"actor": {
"user_id": "uuid",
"username": "string",
"phone": "string | null"
},
"summary": "string",
"permission": "int (1=view, 2=invite, 4=edit, 8=delete, 15=owner)",
"action": "pending"
}
说明:description/start_at/end_at/timezone/actor.phone 为 invite 类型的扩展字段,
用于前端展示邀请详情(邀请人、联系电话、时间区间、描述)。
CalendarUpdateContent (schema_version=2)
{
"type": "updated",
"schema_version": 2,
"item": {
"id": "uuid",
"title": "string"
},
"actor": {
"user_id": "uuid",
"username": "string"
},
"summary": "string",
"changes": [
{
"field": "title | description | start_at | end_at | timezone | status",
"label": "string",
"before": "any | null",
"after": "any | null",
"display_before": "string | null",
"display_after": "string | null",
"change_type": "added | removed | modified"
}
],
"action": "updated"
}
CalendarDeleteContent (schema_version=2)
{
"type": "deleted",
"schema_version": 2,
"item": {
"id": "uuid",
"title": "string"
},
"actor": {
"user_id": "uuid",
"username": "string"
},
"summary": "string",
"changes": [],
"action": "deleted"
}
FriendshipContent
{
"type": "request",
"message": "string | null"
}
数据结构
InboxMessageResponse
{
"id": "uuid",
"recipient_id": "uuid",
"sender_id": "uuid | null",
"message_type": "InboxMessageType",
"schedule_item_id": "uuid | null",
"friendship_id": "uuid | null",
"content": "CalendarInviteContent | CalendarUpdateContent | CalendarDeleteContent | FriendshipContent | null",
"is_read": "boolean",
"status": "InboxMessageStatus",
"created_at": "datetime"
}
1) GET /
获取消息列表。
Query Parameters
is_read: boolean | null(可选,筛选已读/未读状态)
Response
InboxMessageResponse 对象数组。
2) PATCH /{message_id}/read
标记指定消息为已读。
Path Parameters
message_id: 消息 UUID
Response
InboxMessageResponse 对象。
3) GET /stream (SSE)
订阅当前登录用户的 inbox 实时增量事件。
Headers
Accept: text/event-streamLast-Event-ID(可选):断点续流游标,格式\d+-\d+
Query Parameters
idle_limit:1..3600(可选,默认300),连续空轮询上限,超过后服务端主动结束连接。
SSE 事件帧
id: 1743313300000-0
event: INBOX_MESSAGE_CREATED
data: {"event_id":"6f0d...","occurred_at":"2026-03-30T07:00:00Z","user_id":"...","message_id":"...","op":"created","version":1743313300000,"data":{"message":{...}}}
事件类型
INBOX_MESSAGE_CREATEDINBOX_MESSAGE_READ_CHANGEDINBOX_MESSAGE_STATUS_CHANGEDINBOX_SNAPSHOT_REQUIRED
Event Envelope
{
"event_id": "uuid",
"occurred_at": "datetime",
"user_id": "uuid",
"message_id": "uuid",
"event_type": "INBOX_MESSAGE_CREATED | INBOX_MESSAGE_READ_CHANGED | INBOX_MESSAGE_STATUS_CHANGED | INBOX_SNAPSHOT_REQUIRED",
"op": "created | read_changed | status_changed | snapshot_required",
"version": 1743313300000,
"data": {}
}
说明:
- SSE 帧的
event:行与 payload 内event_type当前实现保持一致。 - 客户端可优先使用 SSE
event,也可在 payload 内读取event_type做调试或补偿。
Delta 约定
created:
{
"message": {
"id": "uuid",
"recipient_id": "uuid",
"sender_id": "uuid | null",
"message_type": "InboxMessageType",
"schedule_item_id": "uuid | null",
"friendship_id": "uuid | null",
"content": {},
"is_read": false,
"status": "pending",
"created_at": "datetime"
}
}
read_changed:
{
"is_read": true
}
status_changed:
{
"status": "accepted"
}
snapshot_required:
{}
幂等与补偿策略
- 客户端按
message_id + version做幂等合并;旧版本事件必须丢弃。 - 若检测到版本跳跃或本地状态不可信,客户端应回退到
GET /api/v1/inbox/messages全量快照。 id字段可用于Last-Event-ID断点续流。
前端渲染约束(强制)
- 对
message_type=calendar,前端必须按content.type严格分发:invite | updated | deleted。 - 若
content缺少协议必填字段(schema_version/item/actor/summary,以及updated的changes),前端必须进入协议异常展示路径。 - 禁止将协议异常消息兜底渲染为“默认日历邀请”或其他正常业务消息。
Compatibility Strategy
- 策略:
backward-compatible - 本次仅补全文档遗漏字段
event_type,不改变现有 SSE wire 协议。