bpi_rs/misc/
b23tv.rs

1//! 用于生成 b23.tv 短链
2//!
3//! https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/b23tv.md
4
5use crate::{BilibiliRequest, BpiClient, BpiError, BpiResponse};
6use serde::{Deserialize, Serialize};
7
8/// 生成 b23.tv 短链 - 响应数据
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct ShortLinkData {
11    /// 原始返回内容(标题 + 短链)
12    pub content: String,
13
14    /// 恒为 0
15    pub count: i32,
16
17    /// 纯短链 URL
18    #[serde(skip_serializing, skip_deserializing)]
19    pub link: String,
20    /// 标题
21    #[serde(skip_serializing, skip_deserializing)]
22    pub title: String,
23}
24
25impl ShortLinkData {
26    pub fn extract(&mut self) {
27        if let Some(pos) = self.content.find("https://b23.tv/") {
28            self.link = self.content[pos..].to_string().trim().to_string();
29            self.title = self.content[..pos].trim().to_string();
30        } else {
31            self.link = String::new();
32            self.title = self.content.clone();
33        }
34    }
35}
36
37impl BpiClient {
38    /// 根据视频 aid 生成 b23.tv 短链
39    ///
40    /// 文档: https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/misc
41    ///
42    /// 参数
43    ///
44    /// | 名称 | 类型 | 说明 |
45    /// | ---- | ---- | ---- |
46    /// | `aid` | u64 | 稿件 avid |
47    pub async fn misc_b23_short_link(
48        &self,
49        aid: u64,
50    ) -> Result<BpiResponse<ShortLinkData>, BpiError> {
51        let params = [
52            ("platform", "unix"),
53            ("share_channel", "COPY"),
54            ("share_id", "main.ugc-video-detail.0.0.pv"),
55            ("share_mode", "4"),
56            ("oid", &aid.to_string()),
57            ("buvid", "qwq"),
58            ("build", "6114514"),
59        ];
60
61        let mut result: BpiResponse<ShortLinkData> = self
62            .post("https://api.biliapi.net/x/share/click")
63            .form(&params)
64            .send_bpi("生成短链")
65            .await?;
66
67        // 额外解析出纯短链
68
69        if let Some(data) = &mut result.data {
70            data.extract();
71        }
72
73        Ok(result)
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[tokio::test]
82    async fn test_generate_short_link() {
83        let bpi = BpiClient::new();
84
85        match bpi.misc_b23_short_link(10001).await {
86            Ok(resp) => {
87                if resp.code == 0 {
88                    let data = resp.data.unwrap();
89                    tracing::info!("原始内容: {}", data.content);
90                    tracing::info!("提取短链: {}", data.link);
91                    tracing::info!("提取标题: {}", data.title)
92                } else {
93                    tracing::info!("生成短链失败: code={}, message={}", resp.code, resp.message);
94                }
95            }
96            Err(err) => {
97                panic!("请求出错: {}", err);
98            }
99        }
100    }
101}