bpi_rs/user/relation/
action.rs

1//! B站用户关系操作相关接口
2//!
3//! 文档: https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/user
4use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
5use serde::{ Deserialize, Serialize };
6
7// --- 响应数据结构体 ---
8
9/// 操作用户关系响应数据
10///
11/// 该接口的响应 `data` 字段为 `null`,因此我们使用空元组 `()` 来表示。
12#[derive(Debug, Clone, Deserialize, Serialize)]
13pub struct ModifyRelationResponseData;
14
15// --- API 实现 ---
16
17/// 操作代码
18///
19/// 用于 `act` 参数,定义了要执行的关系操作类型。
20#[repr(u8)]
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
22pub enum RelationAction {
23    /// 关注
24    Follow = 1,
25    /// 取关
26    Unfollow = 2,
27    /// 悄悄关注(已下线)
28    Whisper = 3,
29    /// 取消悄悄关注
30    Unwhisper = 4,
31    /// 拉黑
32    Blacklist = 5,
33    /// 取消拉黑
34    Unblacklist = 6,
35    /// 踢出粉丝
36    KickFan = 7,
37}
38
39/// 关注来源代码
40///
41/// 用于 `re_src` 参数,表示关注操作的来源。
42#[repr(u32)]
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
44pub enum RelationSource {
45    /// 包月充电
46    MonthlyCharge = 1,
47    /// 个人空间
48    Space = 11,
49    /// 视频
50    Video = 14,
51    /// 评论区
52    Comment = 15,
53    /// 视频播放器结束页面
54    VideoEndPage = 17,
55    /// H5推荐关注
56    H5Recommend = 58,
57    /// H5关注列表
58    H5FollowingList = 106,
59    /// H5粉丝列表
60    H5FanList = 107,
61    /// 专栏
62    Article = 115,
63    /// 私信
64    Message = 118,
65    /// 搜索
66    Search = 120,
67    /// 视频播放器左上角关注按钮
68    VideoPlayerButton = 164,
69    /// H5共同关注
70    H5CommonFollow = 167,
71    /// 创作激励计划
72    CreativeIncentive = 192,
73    /// 活动页面
74    ActivityPage = 222,
75    /// 联合投稿视频
76    JointVideo = 229,
77    /// 消息中心点赞详情
78    MessageCenterLike = 235,
79    /// 视频播放器关注弹幕
80    VideoPlayerDanmaku = 245,
81}
82
83impl BpiClient {
84    /// 操作用户关系
85    ///
86    /// 文档: https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/user
87    ///
88    /// # 参数
89    /// | 名称      | 类型                | 说明                       |
90    /// | --------- | -------------------| -------------------------- |
91    /// | `fid`     | u64                | 目标用户 mid               |
92    /// | `action`  | RelationAction     | 操作代码,见 RelationAction 枚举 |
93    /// | `source`  | Option<RelationSource> | 关注来源代码,可选,见 RelationSource 枚举 |
94    pub async fn user_modify_relation(
95        &self,
96        fid: u64,
97        action: RelationAction,
98        source: Option<RelationSource>
99    ) -> Result<BpiResponse<()>, BpiError> {
100        let csrf = self.csrf()?;
101        let mut form = reqwest::multipart::Form
102            ::new()
103            .text("fid", fid.to_string())
104            .text("act", (action as u8).to_string())
105            .text("csrf", csrf.to_string());
106
107        if let Some(s) = source {
108            form = form.text("re_src", (s as u32).to_string());
109        }
110
111        self
112            .post("https://api.bilibili.com/x/relation/modify")
113            .multipart(form)
114            .send_bpi("操作用户关系").await
115    }
116}
117
118// --- 测试模块 ---
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123    use tracing::info;
124
125    const TEST_FID: u64 = 2;
126
127    #[tokio::test]
128    async fn test_modify_relation_follow() -> Result<(), BpiError> {
129        let bpi = BpiClient::new();
130        let resp = bpi.user_modify_relation(
131            TEST_FID,
132            RelationAction::Follow,
133            Some(RelationSource::Space)
134        ).await?;
135
136        info!("关注用户结果: {:?}", resp);
137
138        Ok(())
139    }
140
141    #[tokio::test]
142    async fn test_modify_relation_unfollow() -> Result<(), BpiError> {
143        let bpi = BpiClient::new();
144
145        let resp = bpi.user_modify_relation(TEST_FID, RelationAction::Unfollow, None).await?;
146
147        info!("取关用户结果: {:?}", resp);
148
149        Ok(())
150    }
151
152    #[tokio::test]
153    async fn test_modify_relation_blacklist() -> Result<(), BpiError> {
154        let bpi = BpiClient::new();
155        let resp = bpi.user_modify_relation(TEST_FID, RelationAction::Blacklist, None).await?;
156
157        info!("拉黑用户结果: {:?}", resp);
158
159        let _ = bpi.user_modify_relation(TEST_FID, RelationAction::Unblacklist, None).await;
160
161        Ok(())
162    }
163}