Skip to main content

bpi_rs/dynamic/
banner.rs

1use crate::{BilibiliRequest, BpiClient, BpiError, BpiResponse};
2use serde::{Deserialize, Serialize};
3
4/// 动态首页公告栏响应数据
5#[derive(Debug, Clone, Deserialize, Serialize)]
6pub struct DynamicBannerData {
7    /// 横幅列表
8    pub banners: Vec<DynamicBanner>,
9}
10
11/// 动态横幅数据
12#[derive(Debug, Clone, Deserialize, Serialize)]
13pub struct DynamicBanner {
14    /// 横幅 ID
15    pub banner_id: u64,
16    /// 结束时间(UNIX 秒级时间戳)
17    pub end_time: u64,
18    /// 图片 URL
19    pub img_url: String,
20    /// 跳转链接
21    pub link: String,
22    /// 平台
23    pub platform: u64,
24    /// 位置
25    pub position: String,
26    /// 开始时间(UNIX 秒级时间戳)
27    pub start_time: u64,
28    /// 标题
29    pub title: String,
30    /// 权重
31    pub weight: u64,
32}
33
34impl BpiClient {
35    /// 获取动态首页公告栏
36    ///
37    /// # 参数
38    /// * `platform` - 平台,默认为 1
39    pub async fn dynamic_feed_banner(&self) -> Result<BpiResponse<DynamicBannerData>, BpiError> {
40        let req = self
41            .get("https://api.bilibili.com/x/dynamic/feed/dyn/banner")
42            .query(&[
43                ("platform", "1"),
44                ("position", "web动态"),
45                ("web_location", "333.1365"),
46            ]);
47
48        req.send_bpi("获取动态首页公告栏").await
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use tracing::info;
56
57    #[tokio::test]
58    async fn test_dynamic_feed_banner() -> Result<(), BpiError> {
59        let bpi = BpiClient::new();
60        let resp = bpi.dynamic_feed_banner().await?;
61        let data = resp.into_data()?;
62
63        info!("成功获取到 {} 条公告", data.banners.len());
64        assert!(!data.banners.is_empty());
65
66        Ok(())
67    }
68}