bpi_rs/login/login_action/
captcha.rs1use serde::{Deserialize, Serialize};
2
3use crate::client::BilibiliRequest;
4use crate::{BpiClient, BpiError, BpiResponse};
5
6#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
7pub struct GeetestData {
8 #[serde(rename = "type")]
9 pub type_field: String,
10 pub token: String,
11 pub geetest: Geetest,
12 pub tencent: Tencent,
13}
14
15#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
16pub struct Geetest {
17 pub challenge: String,
18 pub gt: String,
19}
20
21#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
22pub struct Tencent {
23 pub appid: String,
24}
25
26#[derive(Serialize, Deserialize, Clone)]
27pub struct GenerateCaptcha {
28 pub token: String,
29 pub gt: String,
30 pub challenge: String,
31}
32
33impl BpiClient {
34 pub async fn login_generate_captcha(&self) -> Result<GenerateCaptcha, BpiError> {
35 let result: BpiResponse<GeetestData> = self
36 .get("https://passport.bilibili.com/x/passport-login/captcha?source=main_web")
37 .send_bpi("获取验证码")
38 .await?;
39
40 let data = result.into_data()?;
41
42 let token = data.token;
43 let geetest = data.geetest;
44
45 Ok(GenerateCaptcha {
46 token,
47 gt: geetest.gt,
48 challenge: geetest.challenge,
49 })
50 }
51}
52
53#[tokio::test]
54async fn test_generate_captcha() {
55 let bpi = BpiClient::new();
56 match bpi.login_generate_captcha().await {
57 Ok(captcha) => {
58 tracing::info!("验证码请求成功!");
59 tracing::info!("Token: {}", captcha.token);
60 tracing::info!("GT: {}", captcha.gt);
61 tracing::info!("Challenge: {}", captcha.challenge);
62 }
63 Err(e) => {
64 tracing::info!("验证码请求失败: {}", e);
65 }
66 }
67}