Skip to main content

ezcapsolver/tasks/
datadome.rs

1use std::collections::BTreeMap;
2
3use serde::Serialize;
4use serde_json::Value;
5
6use super::ExtraFields;
7
8/// DataDome challenge step.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Default)]
10pub enum DataDomeStep {
11    /// Fetch the challenge URL.
12    #[serde(rename = "1")]
13    #[default]
14    One,
15    /// Produce validation instructions.
16    #[serde(rename = "2")]
17    Two,
18}
19
20/// DataDome tags JavaScript mode.
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Default)]
22#[serde(rename_all = "lowercase")]
23pub enum DataDomeJsType {
24    /// Challenge mode.
25    #[default]
26    Ch,
27    /// Legacy or external mode.
28    Le,
29}
30
31/// DataDome challenge task.
32#[derive(Debug, Clone, Serialize, Default, bon::Builder)]
33#[builder(on(String, into))]
34#[serde(remote = "Self")]
35pub struct DataDomeTask {
36    /// Base64-encoded challenge HTML.
37    pub html_b64: String,
38    /// Challenge workflow step.
39    #[builder(default)]
40    pub step: DataDomeStep,
41    /// Optional base64-encoded image.
42    #[builder(default)]
43    pub image: String,
44    /// Optional page or challenge URL.
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub referer: Option<String>,
47    /// Optional parent page URL.
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub parent_url: Option<String>,
50    /// Optional equipment identifier.
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub equipment: Option<String>,
53    /// Additional worker parameters.
54    #[serde(skip)]
55    #[builder(default)]
56    pub extra: ExtraFields,
57}
58
59/// Lowest packet counter the service accepts.
60///
61/// `bpc` is validated as one or greater, so zero — what a derived `Default`
62/// would produce — is rejected outright.
63const MIN_PACKET_COUNTER: u64 = 1;
64
65/// DataDome tags task.
66#[derive(Debug, Clone, Serialize, bon::Builder)]
67#[builder(on(String, into))]
68#[serde(remote = "Self")]
69pub struct DataDomeTagsTask {
70    /// DataDome JavaScript key.
71    pub ddk: String,
72    /// DataDome JavaScript mode.
73    #[builder(default)]
74    pub jstype: DataDomeJsType,
75    /// Session identifier. An empty string is valid.
76    #[builder(default)]
77    pub cid: String,
78    /// One-based packet counter.
79    ///
80    /// `ch` mode fixes it at one; `le` mode starts at two and counts up.
81    pub bpc: u64,
82    /// Current page URL.
83    pub referer: String,
84    /// Browser user agent.
85    pub ua: String,
86    /// External business fields forwarded to the worker.
87    #[builder(default)]
88    pub fields: BTreeMap<String, Value>,
89    /// Additional worker parameters.
90    #[serde(skip)]
91    #[builder(default)]
92    pub extra: ExtraFields,
93}
94
95impl Default for DataDomeTagsTask {
96    fn default() -> Self {
97        Self {
98            ddk: String::new(),
99            jstype: DataDomeJsType::default(),
100            cid: String::new(),
101            bpc: MIN_PACKET_COUNTER,
102            referer: String::new(),
103            ua: String::new(),
104            fields: BTreeMap::new(),
105            extra: ExtraFields::new(),
106        }
107    }
108}