capmonstercloud_client/requests/
recaptcha_v2_enterprise.rs1use serde::Serialize;
2
3use super::{require_non_empty, CaptchaRequest};
4use crate::error::Result;
5use crate::proxy::ProxyInfo;
6use crate::timeouts::GetResultTimeouts;
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
13pub struct EnterprisePayload {
14 pub s: String,
16}
17
18impl EnterprisePayload {
19 pub fn new(s: impl Into<String>) -> Self {
20 Self { s: s.into() }
21 }
22}
23
24#[derive(Debug, Clone, Serialize)]
29pub struct RecaptchaV2EnterpriseRequest {
30 #[serde(rename = "websiteURL")]
32 pub website_url: String,
33 #[serde(rename = "websiteKey")]
35 pub website_key: String,
36 #[serde(flatten, skip_serializing_if = "Option::is_none")]
38 pub proxy: Option<ProxyInfo>,
39 #[serde(rename = "enterprisePayload", skip_serializing_if = "Option::is_none")]
41 pub enterprise_payload: Option<EnterprisePayload>,
42 #[serde(rename = "apiDomain", skip_serializing_if = "Option::is_none")]
44 pub api_domain: Option<String>,
45 #[serde(rename = "pageAction", skip_serializing_if = "Option::is_none")]
47 pub page_action: Option<String>,
48 #[serde(rename = "userAgent", skip_serializing_if = "Option::is_none")]
50 pub user_agent: Option<String>,
51 #[serde(skip_serializing_if = "Option::is_none")]
53 pub cookies: Option<String>,
54}
55
56impl RecaptchaV2EnterpriseRequest {
57 pub fn new(website_url: impl Into<String>, website_key: impl Into<String>) -> Self {
58 Self {
59 website_url: website_url.into(),
60 website_key: website_key.into(),
61 proxy: None,
62 enterprise_payload: None,
63 api_domain: None,
64 page_action: None,
65 user_agent: None,
66 cookies: None,
67 }
68 }
69
70 pub fn with_proxy(mut self, proxy: ProxyInfo) -> Self {
71 self.proxy = Some(proxy);
72 self
73 }
74
75 pub fn with_enterprise_payload(mut self, value: EnterprisePayload) -> Self {
76 self.enterprise_payload = Some(value);
77 self
78 }
79
80 pub fn with_enterprise_s(self, s: impl Into<String>) -> Self {
82 self.with_enterprise_payload(EnterprisePayload::new(s))
83 }
84
85 pub fn with_api_domain(mut self, value: impl Into<String>) -> Self {
86 self.api_domain = Some(value.into());
87 self
88 }
89
90 pub fn with_page_action(mut self, value: impl Into<String>) -> Self {
91 self.page_action = Some(value.into());
92 self
93 }
94
95 pub fn with_user_agent(mut self, value: impl Into<String>) -> Self {
96 self.user_agent = Some(value.into());
97 self
98 }
99
100 pub fn with_cookies(mut self, value: impl Into<String>) -> Self {
101 self.cookies = Some(value.into());
102 self
103 }
104}
105
106impl CaptchaRequest for RecaptchaV2EnterpriseRequest {
107 const TASK_TYPE: &'static str = "RecaptchaV2EnterpriseTask";
108
109 fn timeouts(&self) -> GetResultTimeouts {
110 GetResultTimeouts::secs(1.0, 10.0, 3.0, 180.0)
111 }
112
113 fn validate(&self) -> Result<()> {
114 require_non_empty("websiteURL", &self.website_url)?;
115 require_non_empty("websiteKey", &self.website_key)?;
116 if let Some(payload) = &self.enterprise_payload {
117 require_non_empty("enterprisePayload.s", &payload.s)?;
118 }
119 Ok(())
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126 use crate::proxy::ProxyType;
127 use serde_json::json;
128
129 #[test]
130 fn minimal_task() {
131 let task = RecaptchaV2EnterpriseRequest::new("https://example.com", "KEY")
132 .to_task()
133 .unwrap();
134 assert_eq!(
135 task,
136 json!({"type": "RecaptchaV2EnterpriseTask", "websiteURL": "https://example.com", "websiteKey": "KEY"})
137 );
138 }
139
140 #[test]
141 fn full_task() {
142 let task = RecaptchaV2EnterpriseRequest::new("https://example.com", "KEY")
143 .with_proxy(ProxyInfo::new(ProxyType::Http, "1.2.3.4", 8080).with_auth("u", "p"))
144 .with_enterprise_s("SVAL")
145 .with_api_domain("www.recaptcha.net")
146 .with_page_action("login")
147 .with_user_agent("UA")
148 .with_cookies("a=b")
149 .to_task()
150 .unwrap();
151 assert_eq!(
152 task,
153 json!({
154 "type": "RecaptchaV2EnterpriseTask", "websiteURL": "https://example.com",
155 "websiteKey": "KEY",
156 "proxyType": "http", "proxyAddress": "1.2.3.4", "proxyPort": 8080,
157 "proxyLogin": "u", "proxyPassword": "p",
158 "enterprisePayload": {"s": "SVAL"}, "apiDomain": "www.recaptcha.net",
159 "pageAction": "login", "userAgent": "UA", "cookies": "a=b"
160 })
161 );
162 }
163
164 #[test]
165 fn empty_required_strings_are_rejected() {
166 let err = RecaptchaV2EnterpriseRequest::new("", "KEY")
167 .to_task()
168 .unwrap_err();
169 assert!(matches!(err, crate::error::Error::Validation(ref m) if m.contains("websiteURL")));
170 let err = RecaptchaV2EnterpriseRequest::new("https://example.com", "")
171 .to_task()
172 .unwrap_err();
173 assert!(matches!(err, crate::error::Error::Validation(ref m) if m.contains("websiteKey")));
174 let err = RecaptchaV2EnterpriseRequest::new("https://example.com", "KEY")
175 .with_enterprise_s("")
176 .to_task()
177 .unwrap_err();
178 assert!(
179 matches!(err, crate::error::Error::Validation(ref m) if m.contains("enterprisePayload.s"))
180 );
181 }
182}