Skip to main content

bpi_rs/user/relation/
action.rs

1//! B站用户关系操作相关接口
2//!
3//! [查看 API 文档](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    /// # 文档
87    /// [查看API文档](https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/user)
88    ///
89    /// # 参数
90    /// | 名称      | 类型                | 说明                       |
91    /// | --------- | -------------------| -------------------------- |
92    /// | `fid`     | u64                | 目标用户 mid               |
93    /// | `action`  | RelationAction     | 操作代码,见 RelationAction 枚举 |
94    /// | `source`  | `Option<RelationSource>` | 关注来源代码,可选,见 RelationSource 枚举 |
95    pub async fn user_modify_relation(
96        &self,
97        fid: u64,
98        action: RelationAction,
99        source: Option<RelationSource>
100    ) -> Result<BpiResponse<()>, BpiError> {
101        let csrf = self.csrf()?;
102        let mut form = reqwest::multipart::Form
103            ::new()
104            .text("fid", fid.to_string())
105            .text("act", (action as u8).to_string())
106            .text("csrf", csrf.to_string());
107
108        if let Some(s) = source {
109            form = form.text("re_src", (s as u32).to_string());
110        }
111
112        self
113            .post("https://api.bilibili.com/x/relation/modify")
114            .multipart(form)
115            .send_bpi("操作用户关系").await
116    }
117}
118
119// --- 测试模块 ---
120
121#[cfg(test)]
122mod tests {
123    use super::*;
124    use tracing::info;
125
126    const TEST_FID: u64 = 2;
127
128    #[tokio::test]
129    async fn test_modify_relation_follow() -> Result<(), BpiError> {
130        let bpi = BpiClient::new();
131        let resp = bpi.user_modify_relation(
132            TEST_FID,
133            RelationAction::Follow,
134            Some(RelationSource::Space)
135        ).await?;
136
137        info!("关注用户结果: {:?}", resp);
138
139        Ok(())
140    }
141
142    #[tokio::test]
143    async fn test_modify_relation_unfollow() -> Result<(), BpiError> {
144        let bpi = BpiClient::new();
145
146        let resp = bpi.user_modify_relation(TEST_FID, RelationAction::Unfollow, None).await?;
147
148        info!("取关用户结果: {:?}", resp);
149
150        Ok(())
151    }
152
153    #[tokio::test]
154    async fn test_modify_relation_blacklist() -> Result<(), BpiError> {
155        let bpi = BpiClient::new();
156        let resp = bpi.user_modify_relation(TEST_FID, RelationAction::Blacklist, None).await?;
157
158        info!("拉黑用户结果: {:?}", resp);
159
160        let _ = bpi.user_modify_relation(TEST_FID, RelationAction::Unblacklist, None).await;
161
162        Ok(())
163    }
164}