Files
open-im-server-deploy/docs/redpacket-message-structure.md
kim.dev.6789 e50142a3b9 复制项目
2026-01-14 22:16:44 +08:00

12 KiB
Raw Blame History

红包消息结构文档

客户端收到的推送消息结构

完整消息结构 (MsgData)

客户端通过WebSocket或HTTP拉取收到的红包消息消息结构如下

{
    "clientMsgID": "client_1234567890abcdef",      // 客户端消息IDstring
    "serverMsgID": "msg_1234567890abcdef",         // 服务器消息IDstring
    "sendID": "user_owner123",                     // 发送者ID群主IDstring
    "recvID": "",                                  // 接收者ID群消息为空string
    "groupID": "group123",                         // 群IDstring
    "senderPlatformID": 0,                         // 发送者平台IDint320表示系统
    "senderNickname": "群主昵称",                   // 发送者昵称string
    "senderFaceURL": "https://...",                // 发送者头像URLstring
    "sessionType": 3,                              // 会话类型int323-群聊
    "msgFrom": 200,                                // 消息来源int32200-系统消息
    "contentType": 110,                            // 消息类型int32110-自定义消息
    "content": "{\"data\":\"{\\\"redPacketID\\\":\\\"rp_123\\\",\\\"redPacketType\\\":1,\\\"blessing\\\":\\\"恭喜发财\\\"}\",\"description\":\"redpacket\",\"extension\":\"\"}",  // 消息内容JSON字符串自定义消息格式
    "seq": 123456,                                 // 消息序号int64
    "sendTime": 1704067200000,                     // 发送时间戳int64毫秒
    "createTime": 1704067200000,                   // 创建时间戳int64毫秒
    "status": 2,                                   // 消息状态int322-发送成功
    "isRead": false,                               // 是否已读bool
    "options": {                                   // 消息选项map[string]bool
        "history": true,                           // 是否保存历史
        "persistent": true,                        // 是否持久化
        "offlinePush": true,                       // 是否离线推送
        "unreadCount": true,                       // 是否计入未读数
        "conversationUpdate": true,                // 是否更新会话
        "senderSync": true                         // 是否同步给发送者
    },
    "offlinePushInfo": {                          // 离线推送信息(可选)
        "title": "[HONGBAO]",                      // 推送标题
        "desc": "[HONGBAO]",                       // 推送描述
        "ex": "",                                  // 扩展字段
        "iosPushSound": "",                        // iOS推送声音
        "iosBadgeCount": false                     // iOS角标计数
    },
    "atUserIDList": [],                           // @用户列表string[]
    "attachedInfo": "",                           // 附加信息string
    "ex": ""                                      // 扩展字段string
}

Content字段解析

content 字段是一个JSON字符串需要先解析为 CustomElem 结构(自定义消息格式),然后从 data 字段中解析出 RedPacketElem 结构:

CustomElem 结构(自定义消息外层结构)

{
    "data": "{\"redPacketID\":\"rp_123\",\"redPacketType\":1,\"blessing\":\"恭喜发财\",\"isReceived\":false,\"receiveInfo\":null}",  // 红包数据的JSON字符串string必填
    "description": "redpacket",  // 二级类型标识string"redpacket"表示红包消息
    "extension": ""              // 扩展字段string可选
}

RedPacketElem 结构从data字段中解析

{
    "redPacketID": "rp_1234567890abcdef",          // 红包IDstring必填
    "redPacketType": 1,                            // 红包类型int32必填1-普通红包2-拼手气红包
    "blessing": "恭喜发财",                         // 祝福语string可选
    "isReceived": false,                           // 当前用户是否已领取bool服务器填充
    "receiveInfo": null                            // 领取信息RedPacketReceiveInfo仅拼手气红包且已领取时返回
}

RedPacketReceiveInfo 结构(领取信息)

{
    "amount": 1000,                                 // 领取金额int64单位
    "receiveTime": 1704067200000,                  // 领取时间戳int64毫秒
    "isLucky": false                               // 是否为手气最佳bool仅拼手气红包有效
}

字段说明

字段名 类型 必填 说明
redPacketID string 红包唯一标识用于后续领取、查询等操作总金额、总个数等信息可通过红包ID查询获取
redPacketType int32 红包类型1-普通红包平均分配2-拼手气红包(随机分配)
blessing string 祝福语
isReceived bool 当前用户是否已领取服务器根据用户ID自动填充
receiveInfo RedPacketReceiveInfo 领取信息,仅当 isReceived=trueredPacketType=2(拼手气红包)时返回

receiveInfo 字段说明

字段名 类型 说明
amount int64 领取金额,单位:分
receiveTime int64 领取时间戳,毫秒
isLucky bool 是否为手气最佳(仅拼手气红包有效)

消息类型常量

  • ContentType: 110 (constant.Custom - 自定义消息)
  • 二级类型标识: "redpacket" (存储在 CustomElem.description 字段中)
  • SessionType: 3 (constant.ReadGroupChatType - 群聊)
  • MsgFrom: 200 (constant.SysMsgType - 系统消息)

客户端解析示例

JavaScript/TypeScript

interface RedPacketReceiveInfo {
    amount: number;         // 领取金额(分)
    receiveTime: number;     // 领取时间戳(毫秒)
    isLucky: boolean;        // 是否为手气最佳
}

interface RedPacketElem {
    redPacketID: string;
    redPacketType: number;   // 1-普通红包2-拼手气红包
    blessing?: string;
    isReceived: boolean;     // 当前用户是否已领取
    receiveInfo?: RedPacketReceiveInfo;  // 领取信息(仅拼手气红包且已领取时返回)
}

interface CustomElem {
    data: string;        // 红包数据的JSON字符串
    description: string; // 二级类型标识:"redpacket"
    extension?: string;  // 扩展字段
}

interface RedPacketMessage {
    clientMsgID: string;
    serverMsgID: string;
    sendID: string;
    groupID: string;
    contentType: number;   // 110 (自定义消息)
    content: string;       // CustomElem的JSON字符串
    sendTime: number;
    // ... 其他字段
}

// 解析消息
function parseRedPacketMessage(msg: RedPacketMessage): RedPacketElem | null {
    // 检查是否为自定义消息类型
    if (msg.contentType !== 110) {
        return null;
    }
    
    try {
        // 先解析自定义消息结构
        const customElem: CustomElem = JSON.parse(msg.content);
        
        // 检查二级类型是否为红包
        if (customElem.description !== "redpacket") {
            return null;
        }
        
        // 从data字段中解析红包数据
        const redPacketElem: RedPacketElem = JSON.parse(customElem.data);
        return redPacketElem;
    } catch (e) {
        console.error('Failed to parse red packet content:', e);
        return null;
    }
}

Go

type RedPacketReceiveInfo struct {
    Amount      int64 `json:"amount"`      // 领取金额(分)
    ReceiveTime int64 `json:"receiveTime"` // 领取时间戳(毫秒)
    IsLucky     bool  `json:"isLucky"`     // 是否为手气最佳
}

type RedPacketElem struct {
    RedPacketID   string                 `json:"redPacketID"`
    RedPacketType int32                  `json:"redPacketType"`
    TotalAmount   int64                  `json:"totalAmount"`
    TotalCount    int32                  `json:"totalCount"`
    Blessing      string                 `json:"blessing"`
    IsReceived    bool                   `json:"isReceived"`    // 当前用户是否已领取
    ReceiveInfo   *RedPacketReceiveInfo  `json:"receiveInfo,omitempty"` // 领取信息(仅拼手气红包且已领取时返回)
}

type CustomElem struct {
    Data        string `json:"data"`        // 红包数据的JSON字符串
    Description string `json:"description"` // 二级类型标识:"redpacket"
    Extension   string `json:"extension"`   // 扩展字段
}

func ParseRedPacketContent(content []byte) (*RedPacketElem, error) {
    // 先解析自定义消息结构
    var customElem CustomElem
    if err := json.Unmarshal(content, &customElem); err != nil {
        return nil, err
    }
    
    // 检查二级类型是否为红包
    if customElem.Description != "redpacket" {
        return nil, fmt.Errorf("not a red packet message")
    }
    
    // 从data字段中解析红包数据
    var redPacketElem RedPacketElem
    if err := json.Unmarshal([]byte(customElem.Data), &redPacketElem); err != nil {
        return nil, err
    }
    
    return &redPacketElem, nil
}

完整消息示例

{
    "clientMsgID": "client_1704067200000_abc123",
    "serverMsgID": "msg_1704067200000_def456",
    "sendID": "user_owner123",
    "recvID": "",
    "groupID": "group123",
    "senderPlatformID": 0,
    "senderNickname": "群主",
    "senderFaceURL": "https://example.com/avatar.jpg",
    "sessionType": 3,
    "msgFrom": 200,
    "contentType": 110,
    "content": "{\"data\":\"{\\\"redPacketID\\\":\\\"rp_1234567890abcdef\\\",\\\"redPacketType\\\":1,\\\"blessing\\\":\\\"恭喜发财\\\",\\\"isReceived\\\":false,\\\"receiveInfo\\\":null}\",\"description\":\"redpacket\",\"extension\":\"\"}",
    "seq": 123456,
    "sendTime": 1704067200000,
    "createTime": 1704067200000,
    "status": 2,
    "isRead": false,
    "options": {
        "history": true,
        "persistent": true,
        "offlinePush": true,
        "unreadCount": true,
        "conversationUpdate": true,
        "senderSync": true
    },
    "offlinePushInfo": {
        "title": "[HONGBAO]",
        "desc": "[HONGBAO]"
    },
    "atUserIDList": [],
    "attachedInfo": "",
    "ex": ""
}

消息选项说明

选项名 说明
history 是否保存到历史记录
persistent 是否持久化存储
offlinePush 是否离线推送
unreadCount 是否计入未读数
conversationUpdate 是否更新会话
senderSync 是否同步给发送者

注意事项

  1. Content字段: 是JSON字符串需要先解析为 CustomElem 结构,然后从 data 字段中解析 RedPacketElem
  2. 消息类型: 使用自定义消息类型(contentType = 110),通过 description 字段标识二级类型为 "redpacket"
  3. 二级类型扩展: 未来可以扩展其他自定义消息类型,只需在 description 字段中使用不同的标识(如 "wallet""coupon" 等)
  4. 金额单位: receiveInfo.amount 单位是"分",不是"元"
  5. 总金额和总个数: 不在消息中传递,客户端可通过 redPacketID 调用查询接口获取详细信息
  6. 红包类型:
    • 1 = 普通红包(平均分配)
    • 2 = 拼手气红包(随机分配)
  7. 发送者: 固定为群主,sendID 为群主ID
  8. 消息来源: msgFrom = 200 表示系统消息
  9. 会话类型: sessionType = 3 表示群聊
  10. 领取状态: isReceived 字段由服务器根据当前用户ID自动填充客户端无需设置
  11. 领取信息: receiveInfo 仅在以下情况返回:
    • isReceived = true(用户已领取)
    • redPacketType = 2(拼手气红包)
    • 普通红包(redPacketType = 1)即使已领取也不会返回 receiveInfo
  12. 客户端存储: 客户端收到消息后,应将 isReceivedreceiveInfo 存储到本地用于UI展示
  13. 兼容性: 使用标准自定义消息类型无需修改客户端SDK只需在客户端添加红包消息的解析逻辑