use serde::{ Deserialize, Serialize };
use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
#[derive(Debug, Serialize, Clone, Deserialize)]
pub struct GiftItem {
pub id: i64,
pub name: String,
pub price: i64,
pub r#type: i32,
pub coin_type: String,
pub effect: i32,
pub stay_time: i32,
pub animation_frame_num: i32,
pub desc: String,
pub img_basic: String,
pub gif: String,
}
#[derive(Debug, Serialize, Clone, Deserialize)]
pub struct GiftConfig {
pub list: Vec<GiftItem>,
}
#[derive(Debug, Serialize, Clone, Deserialize)]
pub struct GiftBaseConfig {
pub base_config: GiftConfig,
}
#[derive(Debug, Serialize, Clone, Deserialize)]
pub struct RoomGiftData {
pub gift_config: GiftBaseConfig,
}
pub type RoomGiftResponse = BpiResponse<RoomGiftData>;
#[derive(Debug, Serialize, Clone, Deserialize)]
pub struct BlindGiftItem {
pub gift_id: i64,
pub price: i64,
pub gift_name: String,
pub gift_img: String,
pub chance: String,
}
#[derive(Debug, Serialize, Clone, Deserialize)]
pub struct BlindGiftData {
pub note_text: String,
pub blind_price: i64,
pub blind_gift_name: String,
pub gifts: Vec<BlindGiftItem>,
}
pub type BlindGiftResponse = BpiResponse<BlindGiftData>;
impl BpiClient {
pub async fn live_room_gift_list(
&self,
room_id: i64,
area_parent_id: Option<i32>,
area_id: Option<i32>
) -> Result<RoomGiftResponse, BpiError> {
let mut params: Vec<(&str, String)> = vec![
("room_id", room_id.to_string()),
("platform", "web".to_string())
];
if let Some(area_parent_id) = area_parent_id {
params.push(("area_parent_id", area_parent_id.to_string()));
}
if let Some(area_id) = area_id {
params.push(("area_id", area_id.to_string()));
}
let resp: RoomGiftResponse = self
.get("https://api.live.bilibili.com/xlive/web-room/v1/giftPanel/roomGiftList")
.query(¶ms)
.send_bpi("获取直播间礼物列表").await?;
Ok(resp)
}
pub async fn live_blind_gift_info(&self, gift_id: i64) -> Result<BlindGiftResponse, BpiError> {
let params = [("gift_id", gift_id.to_string())];
let resp: BlindGiftResponse = self
.get("https://api.live.bilibili.com/xlive/general-interface/v1/blindFirstWin/getInfo")
.query(¶ms)
.send_bpi("获取盲盒概率").await?;
Ok(resp)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_get_room_gift_list() -> Result<(), Box<BpiError>> {
let bpi = BpiClient::new();
let resp = bpi.live_room_gift_list(23174842, None, None).await?;
let data = resp.data.unwrap();
assert!(data.gift_config.base_config.list.len() > 0);
Ok(())
}
#[tokio::test]
async fn test_get_blind_gift_info() -> Result<(), Box<BpiError>> {
let bpi = BpiClient::new();
let resp = bpi.live_blind_gift_info(32251).await?;
let data = resp.data.unwrap();
assert!(data.gifts.len() > 0);
Ok(())
}
}