mod anticaptcha;
mod capsolver;
mod twocaptcha;
pub use anticaptcha::AntiCaptchaProvider;
pub use capsolver::CapSolverProvider;
pub use twocaptcha::TwoCaptchaProvider;
use std::collections::HashMap;
use std::time::Duration;
use async_trait::async_trait;
use thiserror::Error;
use url::Url;
#[derive(Debug, Clone)]
pub struct CaptchaConfig {
pub timeout: Duration,
pub poll_interval: Duration,
}
impl Default for CaptchaConfig {
fn default() -> Self {
Self {
timeout: Duration::from_secs(120),
poll_interval: Duration::from_secs(2),
}
}
}
#[derive(Debug, Clone)]
pub struct CaptchaTask {
pub site_key: String,
pub page_url: Url,
pub action: Option<String>,
pub data: HashMap<String, String>,
}
impl CaptchaTask {
pub fn new(site_key: impl Into<String>, page_url: Url) -> Self {
Self {
site_key: site_key.into(),
page_url,
action: None,
data: HashMap::new(),
}
}
pub fn with_action(mut self, action: impl Into<String>) -> Self {
self.action = Some(action.into());
self
}
pub fn insert_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.data.insert(key.into(), value.into());
self
}
}
#[derive(Debug, Clone)]
pub struct CaptchaSolution {
pub token: String,
pub expires_in: Option<Duration>,
pub metadata: HashMap<String, String>,
}
impl CaptchaSolution {
pub fn new(token: impl Into<String>) -> Self {
Self {
token: token.into(),
expires_in: None,
metadata: HashMap::new(),
}
}
pub fn with_expiry(mut self, ttl: Duration) -> Self {
self.expires_in = Some(ttl);
self
}
pub fn insert_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.metadata.insert(key.into(), value.into());
self
}
}
pub type CaptchaResult = Result<CaptchaSolution, CaptchaError>;
#[async_trait]
pub trait CaptchaProvider: Send + Sync {
fn name(&self) -> &'static str;
async fn solve(&self, task: &CaptchaTask) -> CaptchaResult;
}
#[derive(Debug, Error)]
pub enum CaptchaError {
#[error("captcha provider misconfigured: {0}")]
Configuration(String),
#[error("captcha provider request failed: {0}")]
Provider(String),
#[error("captcha solving timed out after {0:?}")]
Timeout(Duration),
#[error("captcha provider {0} not implemented")]
NotImplemented(&'static str),
#[error("captcha error: {0}")]
Other(String),
}