# 私信 ## 对象说明 ### 会话对象 待补充…… ### 私信主体对象 注:私信主体对象≠[私信内容对象](private_msg_content.md) | 字段 | 类型 | 内容 | 备注 | | ---------------- | ---- | ------------------ | -------------------------------------------------------------- | | sender_uid | num | 发送者mid | | | receiver_type | num | 接收者类型 | 1:用户
2:粉丝团 | | receiver_id | num | 接收者id | `receiver_type` 为 `1` 时表示用户 mid,为 `2` 时表示应援团 id | | msg_type | num | 消息类型 | 详见[私信消息类型、内容说明](private_msg_content.md) | | content | str | 消息内容 | [私信内容对象](private_msg_content.md)经过 JSON 序列化后的文本 | | msg_seqno | num | 消息序列号 | 按照时间顺序从小到大 | | timestamp | num | 消息发送秒级时间戳 | | | at_uids | 有效时:array
无效时:null | at的成员mid | 在粉丝团时有效;此项为 `null` 或 `[0]` 均表示没有 at 成员 | | msg_key | num | 消息唯一id | 部分库在解析JSON对象中的大数时存在数值的精度丢失问题,因此在处理私信时可能会出现问题,建议使用修复了这一问题的库(如将大数转换成文本) | | msg_status | num | 消息状态 | 0:正常
1:被撤回(接口仍能返回被撤回的私信内容)
2:被系统撤回(私信将不会显示在前端,B站接口也不会返回被系统撤回的私信)
51:(?) | | notify_code | str | 通知代码 | 发送通知时使用;若这条私信非通知则为空文本 | | new_face_version | num | 表情包版本 | 为 `0` 或无此项表示旧版表情包,此时 B 站会自动转换成新版表情包,例如 `[doge]` -> `[tv_doge]`;`1` 为新版 | | msg_source | num | 消息来源 | 见[消息来源列表](#消息来源列表) | ### 消息来源列表 | 代码 | 含义 | 备注 | | ---- | ------------------------- | ---- | | 1 | iOS | | | 2 | Android | | | 3 | H5 | | | 4 | PC客户端 | | | 5 | 官方自动推送 | 包括:官方向大多数用户发送的私信等 | | 6 | 自动推送/发送 | 包括:特别关注时稿件的自动推送、因成为契约者而自动发送的私信、包月充电回馈私信、官方发送的特定于自己的消息等 | | 7 | Web | | | 8 | 自动回复 - 被关注回复 | | | 9 | 自动回复 - 收到消息回复 | | | 10 | 自动回复 - 关键词回复 | | | 11 | 自动回复 - 大航海上船回复 | | | 12 | 自动推送 - UP 主赠言 | 在以前稿件的自动推送与其附带的 UP 主赠言是 2 条不同的私信(其中 UP 主赠言的消息来源代码为 12),现在 UP 主赠言已被合并成为稿件自动推送的一部分 | | 13 | 应援团系统提示 | 如:应援团中的提示信息“欢迎xxx入群” | | 17 | 互相关注 | 互相关注时自动发送的私信“我们已互相关注,开始聊天吧~” | | 18 | 系统提示 | 如:“对方主动回复或关注你前,最多发送1条消息” | | 19 | AI | 如:给[搜索AI助手测试版](https://space.bilibili.com/1400565964/)发送私信时对方的自动回复 | ## 未读私信数 > https://api.vc.bilibili.com/session_svr/v1/session_svr/single_unread *请求方式:GET* 认证方式:Cookie(SESSDATA) **json回复:** 根对象: | 字段 | 类型 | 内容 | 备注 | | ------- | ---- | -------- | ----------------------------- | | code | num | 返回值 | 0:成功
-101:账号未登录 | | msg | str | 错误信息 | 默认为0 | | message | str | 错误信息 | 默认为0 | | ttl | num | 1 | | | data | obj | 信息本体 | | `data` 对象: | 字段 | 类型 | 内容 | 备注 | | ----------------------- | ---- | ---------------------- | ------------ | | unfollow_unread | num | 未关注用户未读私信数 | | | follow_unread | num | 已关注用户未读私信数 | | | unfollow_push_msg | num | 未读推送消息数 | | | dustbin_push_msg | num | 被拦截的未读推送消息数 | | | dustbin_unread | num | 被拦截的未读私信数 | | | biz_msg_unfollow_unread | num | (?) | 作用尚不明确 | | biz_msg_follow_unread | num | (?) | 作用尚不明确 | | custom_unread | num | 未读客服消息数 | | **示例:** 以下信息代表未关注用户未读私信数为`1`条,已关注用户未读私信数为`6`条 ```shell curl 'https://api.vc.bilibili.com/session_svr/v1/session_svr/single_unread' \ -b 'SESSDATA=xxx' ```
查看响应示例: ```json { "code": 0, "msg": "0", "message": "0", "ttl": 1, "data": { "unfollow_unread": 1, "follow_unread": 6, "unfollow_push_msg": 0, "dustbin_push_msg": 0, "dustbin_unread": 0, "biz_msg_unfollow_unread": 0, "biz_msg_follow_unread": 0, "custom_unread": 0 } } ```
## 私信消息记录 > https://api.vc.bilibili.com/svr_sync/v1/svr_sync/fetch_session_msgs *请求方式:GET* 此接口有设计缺陷,可以获取已经撤回的私信内容 认证方式:Cookie(SESSDATA) **url参数:** | 参数名 | 类型 | 内容 | 必要性 | 备注 | | ----------------- | ---- | ---------------- | ------ | ------------------------------------------------------ | | talker_id | num | 聊天对象的id | 必要 | `session_type` 为 `1` 时表示用户 mid,为 `2` 时表示应援团 id | | session_type | num | 聊天对象的类型 | 必要 | 1:用户
2:粉丝团 | | size | num | 返回消息数量 | 非必要 | 默认为 20,最大为 200 | | begin_seqno | num | 开始的序列号 | 非必要 | 提供本参数时返回以本序列号开始(不包括本序列号)的消息 | | end_seqno | num | 结束的序列号 | 非必要 | 提供本参数时返回以本序列号结束(不包括本序列号)的消息 | | sender_device_id | num | 发送者设备 | 非必要 | 默认为 `1` | | build | num | 客户端内部版本号 | 非必要 | 默认为 `0` | | mobi_app | str | 平台标识 | 非必要 | 可为 `web` 等;**若本参数值为 `web`,则返回新版表情包** | **json回复:** 根对象: | 字段 | 类型 | 内容 | 备注 | | ------- | ---- | -------- | ------------------------------------------------- | | code | num | 返回值 | 0:成功
-101:账号未登录
-400:请求错误 | | msg | str | 错误信息 | 默认为0 | | message | str | 错误信息 | 默认为0 | | ttl | num | 1 | | | data | obj | 数据本体 | | `data`对象: | 字段 | 类型 | 内容 | 备注 | | --------- | ----- | ------------------------------ | ----------------------------------- | | messages | 有私信时:array
无私信时:null | 私信列表 | 按发送时间顺序反向排序 | | has_more | num | 是否有更多私信 | | | min_seqno | num | 所有消息中最小的序列号(最早) | 若无私信则为 `18446744073709551615` | | max_seqno | num | 所有消息中最大的序列号(最晚) | 若无私信则为 `0` | | e_infos | array | 聊天表情列表 | 若私信列表中无表情则无此项 | `messages`数组: | 项 | 类型 | 内容 | 备注 | | ---- | ---- | --------- | --------------------------------- | | 0 | obj | 私信1 | 详见[私信主体对象](#私信主体对象) | | n | obj | 私信(n+1) | | | …… | obj | …… | …… | `e_infos`数组: | 项 | 类型 | 内容 | 备注 | | ---- | ---- | --------- | ---- | | 0 | obj | 表情1 | | | n | obj | 表情(n+1) | | | …… | obj | …… | …… | `e_infos`数组中的对象: | 字段 | 类型 | 内容 | 备注 | | ------- | ---- | ----------- | ----------------------------------- | | text | str | 表情名称 | 包括左右两侧的中括号,如`[tv_doge]` | | uri | str | 表情链接 | | | size | num | 表情尺寸 | 1:小
2:大 | | gif_url | str | 表情GIF链接 | 仅部分表情存在此项 | **示例:** 获取与目标用户`mid=123`的私信记录: ```shell curl -G 'https://api.vc.bilibili.com/svr_sync/v1/svr_sync/fetch_session_msgs' \ --data-urlencode 'talker_id=123' \ --data-urlencode 'session_type=1' \ --data-urlencode 'size=20' \ --data-urlencode 'sender_device_id=1' \ --data-urlencode 'build=0' \ --data-urlencode 'mobi_app=web' \ -b 'SESSDATA=xxx' ```
查看响应示例: ```json { "code": 0, "msg": "0", "message": "0", "ttl": 1, "data": { "messages": [ { "sender_uid": 2239814, "receiver_type": 1, "receiver_id": 123, "msg_type": 1, "content": "{\"content\":\"[口罩]\"}", "msg_seqno": 309675413389322, "timestamp": 1654154093, "at_uids": [ 0 ], "msg_key": 7104537732714964358, "msg_status": 0, "notify_code": "", "new_face_version": 1, "msg_source": 2 }, { "sender_uid": 2239814, "receiver_type": 1, "receiver_id": 123, "msg_type": 5, "content": "{\"content\":\"1\"}", "msg_seqno": 308302399586307, "timestamp": 1654072255, "at_uids": [ 0 ], "msg_key": 7104186240789226795, "msg_status": 0, "notify_code": "", "msg_source": 7 }, ], "has_more": 0, "min_seqno": 308188515844097, "max_seqno": 309675413389322, "e_infos": [ { "text": "[口罩]", "url": "http://i0.hdslb.com/bfs/emote/3ad2f66b151496d2a5fb0a8ea75f32265d778dd3.png", "size": 1 } ] } } ```
## 发送私信(web端) > https://api.vc.bilibili.com/web_im/v1/web_im/send_msg *请求方式:POST* 认证方式:Cookie(SESSDATA) **正文参数(application/x-www-form-urlencoded):** | 参数名 | 类型 | 内容 | 必要性 | 备注 | | --------------------- | ---- | ------------------------ | ------ | ---------------------------------------------------- | | msg[sender_uid] | num | 发送者mid | 必要 | | | msg[receiver_id] | num | 接收者id | 必要 | `msg[receiver_type]` 为 `1` 时表示用户 mid,为 `2` 时表示应援团 id | | msg[receiver_type] | num | 接收者类型 | 必要 | 1:用户
2:粉丝团 | | msg[msg_type] | num | 消息类型 | 必要 | 详见[私信消息类型、内容说明](private_msg_content.md) | | msg[msg_status] | num | 消息状态 | 非必要 | 恒为 `0` | | msg[dev_id] | str | dev_id | 必要 | 实质上即 UUID(版本 4),**生成方式在下面** | | msg[timestamp] | num | 当前时间戳(秒) | 必要 | | | msg[new_face_version] | num | 表情包版本 | 非必要 | 提供 `0` 或者未提供本参数表示旧版表情包,此时 B 站会自动转换成新版表情包,例如 `[doge]` -> `[tv_doge]`;`1` 为新版 | | msg[content] | str | 消息内容 | 必要 | 详见[私信消息类型、内容说明](private_msg_content.md) | | csrf_token | str | CSRF Token(位于cookie) | 必要 | | | csrf | str | CSRF Token(位于cookie) | 必要 | | | build | num | 客户端内部版本号 | 非必要 | 默认为 `0` | | mobi_app | str | 平台标识 | 非必要 | 可为 `web` 等 | --- **dev_id 的生成:** dev_id 实质上就是 UUID(版本 4)
查看生成 UUID 的代码 **以 Python 为例:** ```python import uuid dev_id = str(uuid.uuid4()) ``` **以 JS 为例:** 以下代码适用于较新版的 JS 引擎(Chrome≥92,Firefox≥95,Safari≥15.4,Node.js≥19.0.0): ```js const dev_id = crypto.randomUUID(); ``` 以下为通用代码(来自 [andywang425/BLTH](https://github.com/andywang425/BLTH/blob/45fe93e31754ca8bf07059d46266398e787dbf45/B%E7%AB%99%E7%9B%B4%E6%92%AD%E9%97%B4%E6%8C%82%E6%9C%BA%E5%8A%A9%E6%89%8B.js#L6618)) ```js const dev_id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (function (name) { let randomInt = 16 * Math.random() | 0; return ("x" === name ? randomInt : 3 & randomInt | 8).toString(16).toUpperCase() })); ``` **以 Java 为例:** ```java import java.util.UUID; public class Main { private String getDevId() { UUID uuid = UUID.randomUUID(); return uuid.toString(); } } ```
--- **json回复:** 根对象: | 字段 | 类型 | 内容 | 备注 | | ------- | ---- | -------- | ------------------------------------------------- | | code | num | 返回值 | 0:成功
-101:账号未登录
-400:请求错误
21047:你最多发送1条消息,对方回复或者关注你后可以继续发消息~ | | message | str | 错误信息 | 默认为0 | | ttl | num | | 默认为1 | | data | obj | 信息本体 | 出错时无此项 | `data`对象: | 字段 | 类型 | 内容 | 备注 | | ------------- | ---- | ---------- | ------------------------------------------------------------------- | | msg_key | num | 消息唯一id | | | msg_content | str | 发送的消息 | 仅当请求参数中`msg[msg_type]`为`1`且`msg[receiver_type]`为`1`时显示 | | key_hit_infos | obj | 触发的提示 | 仅当请求参数中`msg[msg_type]`为`1`且`msg[receiver_type]`为`1`时显示 | `data`对象中的`key_hit_infos`: | 字段 | 类型 | 内容 | 备注 | | --------- | ----- | ------------ | -------------------------------------- | | toast | str | 提示信息文字 | 未触发提示不显示此项 | | rule_id | num | 触发的规则id | 未触发提示不显示此项,详细信息有待补充 | | high_text | array | 高亮的文本 | 未触发提示不显示此项 | `data`对象中的`key_hit_infos`中的`high_text`数组: | 项 | 类型 | 内容 | 备注 | | ---- | ---- | ------------- | ---------------- | | 0 | obj | 高亮文本1 | 详细信息有待补充 | | n | obj | 高亮文本(n+1) | | | …… | obj | …… | …… | **示例:** 给目标用户`mid=1`发一条文字私信: > up主你好, > 催更[doge] ```shell curl 'https://api.vc.bilibili.com/web_im/v1/web_im/send_msg' \ --data-urlencode 'msg[sender_uid]=293793435' \ --data-urlencode 'msg[receiver_id]=1' \ --data-urlencode 'msg[receiver_type] =1' \ --data-urlencode 'msg[msg_type]=1' \ --data-urlencode 'msg[msg_status]=0' \ --data-urlencode 'msg[dev_id]=372778FD-E359-461D-86A3-EA2BCC6FF52A' \ --data-urlencode 'msg[timestamp]=1626181379' \ --data-urlencode 'msg[new_face_version]=1' \ --data-urlencode 'msg[content]={"content":"up主你好,\n催更[doge]"}' \ --data-urlencode 'csrf=xxx' \ --data-urlencode 'csrf_token=xxx' \ -b 'SESSDATA=xxx' ```
查看响应示例: ```json { "code": 0, "message": "0", "ttl": 1, "data": { "msg_key": 6984393491767669026, "msg_content": "{\"content\":\"up主你好,\n催更[doge]\"}", "key_hit_infos": {} } } ```
给目标用户`mid=1`发一条图片私信: > ```shell curl 'https://api.vc.bilibili.com/web_im/v1/web_im/send_msg' \ --data-urlencode 'msg[sender_uid]=293793435' \ --data-urlencode 'msg[receiver_id]=1' \ --data-urlencode 'msg[receiver_type] =1' \ --data-urlencode 'msg[msg_type]=2' \ --data-urlencode 'msg[msg_status]=0' \ --data-urlencode 'msg[dev_id]=372778FD-E359-461D-86A3-EA2BCC6FF52A' \ --data-urlencode 'msg[timestamp]=1626181379' \ --data-urlencode 'msg[content]={"url":"https://i1.hdslb.com/bfs/face/aebb2639a0d47f2ce1fec0631f412eaf53d4a0be.jpg"}' \ --data-urlencode 'csrf=xxx' \ --data-urlencode 'csrf_token=xxx' \ -b 'SESSDATA=xxx' ```
查看响应示例: ```json { "code": 0, "message": "0", "data": { "msg_key": 6852570013146024354 } } ```
给目标用户`mid=1`发送会触发提示的私信: > 支付宝 ```shell curl 'https://api.vc.bilibili.com/web_im/v1/web_im/send_msg' \ --data-urlencode 'msg[sender_uid]=293793435' \ --data-urlencode 'msg[receiver_id]=1' \ --data-urlencode 'msg[receiver_type] =1' \ --data-urlencode 'msg[msg_type]=1' \ --data-urlencode 'msg[msg_status]=0' \ --data-urlencode 'msg[dev_id]=372778FD-E359-461D-86A3-EA2BCC6FF52A' \ --data-urlencode 'msg[timestamp]=1626181379' \ --data-urlencode 'msg[content]={"content":"支付宝"}' \ --data-urlencode 'csrf=xxx' \ --data-urlencode 'csrf_token=xxx' \ -b 'SESSDATA=xxx' ```
查看响应示例: ```json { "code": 0, "message": "0", "ttl": 1, "data": { "msg_key": 6984393491767669026, "msg_content": "{\"content\":\"支付宝\"}", "key_hit_infos": { "toast": "【温馨提示】为保障消费者权益,根据平台规则,如创作者在与消费者沟通中进行发布要求非法转账、欺诈转账等违规行为,平台有权对此进行处罚,感谢您的理解。", "rule_id": 2, "high_text": [ {} ] } } } ```