1use serde::{ Deserialize, Serialize };
2
3use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
4
5#[derive(Debug, Serialize, Clone, Deserialize)]
8pub struct GiftItem {
9 pub id: i64,
11 pub name: String,
13 pub price: i64,
15 pub r#type: i32,
17 pub coin_type: String,
19 pub effect: i32,
21 pub stay_time: i32,
23 pub animation_frame_num: i32,
25 pub desc: String,
27 pub img_basic: String,
29 pub gif: String,
31}
32
33#[derive(Debug, Serialize, Clone, Deserialize)]
34pub struct GiftConfig {
35 pub list: Vec<GiftItem>,
37}
38
39#[derive(Debug, Serialize, Clone, Deserialize)]
40pub struct GiftBaseConfig {
41 pub base_config: GiftConfig,
43}
44
45#[derive(Debug, Serialize, Clone, Deserialize)]
46pub struct RoomGiftData {
47 pub gift_config: GiftBaseConfig,
49}
50
51pub type RoomGiftResponse = BpiResponse<RoomGiftData>;
52
53#[derive(Debug, Serialize, Clone, Deserialize)]
54pub struct BlindGiftItem {
55 pub gift_id: i64,
57 pub price: i64,
59 pub gift_name: String,
61 pub gift_img: String,
63 pub chance: String,
65}
66
67#[derive(Debug, Serialize, Clone, Deserialize)]
68pub struct BlindGiftData {
69 pub note_text: String,
71 pub blind_price: i64,
73 pub blind_gift_name: String,
75 pub gifts: Vec<BlindGiftItem>,
77}
78
79pub type BlindGiftResponse = BpiResponse<BlindGiftData>;
80
81impl BpiClient {
84 pub async fn live_room_gift_list(
100 &self,
101 room_id: i64,
102 area_parent_id: Option<i32>,
103 area_id: Option<i32>
104 ) -> Result<RoomGiftResponse, BpiError> {
105 let mut params: Vec<(&str, String)> = vec![
106 ("room_id", room_id.to_string()),
107 ("platform", "web".to_string())
108 ];
109
110 if let Some(area_parent_id) = area_parent_id {
111 params.push(("area_parent_id", area_parent_id.to_string()));
112 }
113
114 if let Some(area_id) = area_id {
115 params.push(("area_id", area_id.to_string()));
116 }
117
118 let resp: RoomGiftResponse = self
119 .get("https://api.live.bilibili.com/xlive/web-room/v1/giftPanel/roomGiftList")
120 .query(¶ms)
121 .send_bpi("获取直播间礼物列表").await?;
122
123 Ok(resp)
124 }
125
126 pub async fn live_blind_gift_info(&self, gift_id: i64) -> Result<BlindGiftResponse, BpiError> {
138 let params = [("gift_id", gift_id.to_string())];
139
140 let resp: BlindGiftResponse = self
141 .get("https://api.live.bilibili.com/xlive/general-interface/v1/blindFirstWin/getInfo")
142 .query(¶ms)
143 .send_bpi("获取盲盒概率").await?;
144
145 Ok(resp)
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[tokio::test]
154 async fn test_get_room_gift_list() -> Result<(), Box<BpiError>> {
155 let bpi = BpiClient::new();
156 let resp = bpi.live_room_gift_list(23174842, None, None).await?;
157
158 let data = resp.data.unwrap();
159 assert!(data.gift_config.base_config.list.len() > 0);
160 Ok(())
161 }
162
163 #[tokio::test]
164 async fn test_get_blind_gift_info() -> Result<(), Box<BpiError>> {
165 let bpi = BpiClient::new();
166 let resp = bpi.live_blind_gift_info(32251).await?;
167
168 let data = resp.data.unwrap();
169 assert!(data.gifts.len() > 0);
170 Ok(())
171 }
172}