Skip to main content

eoka_server/
captcha.rs

1#[derive(Debug, Clone)]
2pub struct CaptchaInfo {
3    pub captcha_type: String,
4    pub sitekey: String,
5}
6
7pub async fn detect_captcha_on_page(page: &crate::eoka::Page) -> Option<CaptchaInfo> {
8    let hcaptcha_script = r#"
9        (() => document.querySelector('[data-sitekey]')?.getAttribute('data-sitekey') || null)()
10    "#;
11    if let Ok(result) = page.evaluate::<serde_json::Value>(hcaptcha_script).await {
12        if let Some(sitekey) = result.as_str().filter(|key| !key.is_empty()) {
13            return Some(CaptchaInfo {
14                captcha_type: "hcaptcha".into(),
15                sitekey: sitekey.into(),
16            });
17        }
18    }
19
20    let recaptcha_script = r#"
21        (() => {
22            if (![...document.scripts].some(s => s.src.includes('recaptcha'))) return null;
23            return document.documentElement.innerHTML.match(/"sitekey"\s*:\s*"([^"]+)"/)?.[1] || null;
24        })()
25    "#;
26    if let Ok(result) = page.evaluate::<serde_json::Value>(recaptcha_script).await {
27        if let Some(sitekey) = result.as_str().filter(|key| !key.is_empty()) {
28            return Some(CaptchaInfo {
29                captcha_type: "recaptcha".into(),
30                sitekey: sitekey.into(),
31            });
32        }
33    }
34    None
35}