Skip to main content

bpi_rs/dynamic/
all.rs

1use serde::{ Deserialize, Serialize };
2
3use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
4
5#[derive(Debug, Clone, Default, Serialize, Deserialize)]
6pub struct DynamicAllData {
7    pub has_more: bool,
8    pub items: Vec<DynamicItem>,
9    pub offset: String,
10    pub update_baseline: String,
11    pub update_num: i64,
12}
13
14#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
15pub struct DynamicItem {
16    pub basic: Basic,
17    pub id_str: String,
18    pub modules: serde_json::Value,
19    #[serde(rename = "type")]
20    pub type_field: String,
21    pub visible: bool,
22}
23
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
25pub struct Basic {
26    pub comment_id_str: String,
27    pub comment_type: i64,
28    pub like_icon: serde_json::Value,
29    pub rid_str: String,
30    pub is_only_fans: Option<bool>,
31    pub jump_url: Option<String>,
32}
33
34/// 检测新动态响应数据
35#[derive(Debug, Clone, Deserialize)]
36pub struct DynamicUpdateData {
37    /// 新动态的数量
38    pub update_num: u64,
39}
40
41impl BpiClient {
42    /// 获取全部动态列表
43    ///
44    /// # 文档
45    /// [查看API文档](https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/dynamic)
46    ///
47    /// # 参数
48    ///
49    /// | 名称 | 类型 | 说明 |
50    /// | ---- | ---- | ---- |
51    /// | `host_mid` | `Option<&str>` | UP 主 UID |
52    /// | `offset` | `Option<&str>` | 分页偏移量 |
53    /// | `update_baseline` | `Option<&str>` | 更新基线,用于获取新动态 |
54    pub async fn dynamic_all(
55        &self,
56        host_mid: Option<&str>,
57        offset: Option<&str>,
58        update_baseline: Option<&str>
59    ) -> Result<BpiResponse<DynamicAllData>, BpiError> {
60        let mut req = self.get("https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all").query(
61            &[
62                (
63                    "features",
64                    "itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote,decorationCard,onlyfansAssetsV2,forwardListHidden,ugcDelete",
65                ),
66                ("web_location", "333.1365"),
67            ]
68        );
69
70        if let Some(mid) = host_mid {
71            req = req.query(&[("host_mid", mid)]);
72        }
73        if let Some(off) = offset {
74            req = req.query(&[("offset", off)]);
75        }
76        if let Some(baseline) = update_baseline {
77            req = req.query(&[("update_baseline", baseline)]);
78        }
79
80        req.send_bpi("获取全部动态列表").await
81    }
82
83    /// 检测是否有新动态
84    ///
85    /// # 文档
86    /// [查看API文档](https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/dynamic)
87    ///
88    /// # 参数
89    ///
90    /// | 名称 | 类型 | 说明 |
91    /// | ---- | ---- | ---- |
92    /// | `update_baseline` | &str | 上次列表返回的 update_baseline |
93    /// | `type_str` | `Option<&str>` | 动态类型 |
94    pub async fn dynamic_check_new(
95        &self,
96        update_baseline: &str,
97        type_str: Option<&str>
98    ) -> Result<BpiResponse<DynamicUpdateData>, BpiError> {
99        let mut req = self
100            .get("https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all/update")
101            .query(&[("update_baseline", update_baseline)]);
102
103        if let Some(typ) = type_str {
104            req = req.query(&[("type", typ)]);
105        }
106
107        req.send_bpi("检测新动态").await
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use super::*;
114    use tracing::info;
115
116    #[tokio::test]
117    async fn test_dynamic_get_all() -> Result<(), BpiError> {
118        let bpi = BpiClient::new();
119        let resp = bpi.dynamic_all(None, None, None).await?;
120        assert_eq!(resp.code, 0);
121
122        let data = resp.into_data()?;
123
124        info!("成功获取 {} 条动态", data.items.len());
125
126        Ok(())
127    }
128
129    #[tokio::test]
130    async fn test_dynamic_check_new() -> Result<(), BpiError> {
131        let bpi = BpiClient::new();
132        let update_baseline = "0";
133        let resp = bpi.dynamic_check_new(update_baseline, None).await?;
134        let data = resp.into_data().unwrap();
135
136        info!("成功检测到 {} 条新动态", data.update_num);
137
138        Ok(())
139    }
140}