1use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
6use serde::{ Deserialize, Serialize };
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct ShortLinkData {
11 pub content: String,
13
14 pub count: i32,
16
17 #[serde(skip_serializing, skip_deserializing)]
19 pub link: String,
20 #[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 pub async fn misc_b23_short_link(
49 &self,
50 aid: u64
51 ) -> Result<BpiResponse<ShortLinkData>, BpiError> {
52 let params = [
53 ("platform", "unix"),
54 ("share_channel", "COPY"),
55 ("share_id", "main.ugc-video-detail.0.0.pv"),
56 ("share_mode", "4"),
57 ("oid", &aid.to_string()),
58 ("buvid", "qwq"),
59 ("build", "6114514"),
60 ];
61
62 let mut result: BpiResponse<ShortLinkData> = self
63 .post("https://api.biliapi.net/x/share/click")
64 .form(¶ms)
65 .send_bpi("生成短链").await?;
66
67 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}