1use crate::{BilibiliRequest, BpiClient, BpiError, BpiResponse};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct BangumiFollowResult {
9 pub fmid: i64,
10 pub relation: bool,
11 pub status: i32,
12 pub toast: String,
13}
14
15impl BpiClient {
16 pub async fn bangumi_follow(
24 &self,
25 season_id: u64,
26 ) -> Result<BpiResponse<BangumiFollowResult>, BpiError> {
27 let csrf = self.csrf()?;
28 self.post("https://api.bilibili.com/pgc/web/follow/add")
29 .with_bilibili_headers()
30 .form(&[
31 ("season_id", season_id.to_string()),
32 ("csrf", csrf.to_string()),
33 ])
34 .send_bpi("追番")
35 .await
36 }
37
38 pub async fn bangumi_unfollow(
45 &self,
46 season_id: u64,
47 ) -> Result<BpiResponse<BangumiFollowResult>, BpiError> {
48 let csrf = self.csrf()?;
49 self.post("https://api.bilibili.com/pgc/web/follow/del")
50 .with_bilibili_headers()
51 .form(&[
52 ("season_id", season_id.to_string()),
53 ("csrf", csrf.to_string()),
54 ])
55 .send_bpi("取消追番")
56 .await
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 const TEST_BANGUMI_ID: u64 = 99644; #[tokio::test]
66 async fn test_follow_bangumi() -> Result<(), Box<BpiError>> {
67 let bpi = BpiClient::new();
68 let result = bpi.bangumi_follow(TEST_BANGUMI_ID).await?;
69
70 let data = result.into_data()?;
71 tracing::info!("{:#?}", data);
72
73 assert_eq!(data.toast, "自己追的番就要好好看完哟^o^");
74
75 Ok(())
76 }
77
78 #[tokio::test]
79 async fn test_unfollow_bangumi() -> Result<(), Box<BpiError>> {
80 let bpi = BpiClient::new();
81 let result = bpi.bangumi_unfollow(TEST_BANGUMI_ID).await?;
82
83 let data = result.into_data()?;
84 tracing::info!("{:#?}", data);
85
86 assert_eq!(data.toast, "已取消追番");
87
88 Ok(())
89 }
90}