From 8ba8b1404bcf8af3959d1da441c966cd25bf5087 Mon Sep 17 00:00:00 2001 From: gameloader Date: Wed, 18 Mar 2026 22:46:40 +0800 Subject: [PATCH] feat: add human-like pacing to signup and checkout requests --- src/chatgpt_payment.py | 3 +++ src/chatgpt_register_http_reverse.py | 9 -------- src/http_client.py | 32 +++++++++++++++++++++++++++- src/main.py | 1 + 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/chatgpt_payment.py b/src/chatgpt_payment.py index e7f1d26..4f74067 100644 --- a/src/chatgpt_payment.py +++ b/src/chatgpt_payment.py @@ -104,6 +104,7 @@ class ChatGPTPayment: else: captcha_token = "" print(" No captcha required") + skip_captcha_followup_delay = bool(captcha_token) # 4. Create Stripe payment method print("[4/6] Creating payment method...") @@ -162,6 +163,7 @@ class ChatGPTPayment: "Origin": "https://js.stripe.com", "Referer": "https://js.stripe.com/", }, + skip_pacing=skip_captcha_followup_delay, ) if r.status_code != 200: raise RuntimeError(f"Create payment method failed: {r.text}") @@ -212,6 +214,7 @@ class ChatGPTPayment: "Origin": "https://js.stripe.com", "Referer": "https://js.stripe.com/", }, + skip_pacing=skip_captcha_followup_delay, ) if r.status_code != 200: raise RuntimeError(f"Stripe confirm failed: {r.text}") diff --git a/src/chatgpt_register_http_reverse.py b/src/chatgpt_register_http_reverse.py index ce80059..4653130 100644 --- a/src/chatgpt_register_http_reverse.py +++ b/src/chatgpt_register_http_reverse.py @@ -1,8 +1,6 @@ """Pure HTTP registration experiment with detailed auth-state diagnostics.""" import os -import random import re -import time import uuid from typing import Optional from urllib.parse import unquote, urlencode, urljoin, urlparse @@ -19,9 +17,6 @@ class ChatGPTRegisterHTTPReverse: self.auth_base = "https://auth.openai.com" self.root_dir = os.path.dirname(os.path.dirname(__file__)) - def _delay(self, lo=0.5, hi=1.5): - time.sleep(random.uniform(lo, hi)) - def _cookie_rows(self) -> list[tuple[str, str, str]]: rows = [] for cookie in self.http.session.cookies.jar: @@ -345,16 +340,12 @@ class ChatGPTRegisterHTTPReverse: mailbox = self.mail.create_mailbox() email = mailbox["address"] print(f" Email: {email}") - self._delay() csrf_token = self._bootstrap_chatgpt() - self._delay() auth_url = self._signin_auth0(email, csrf_token) - self._delay() auth_page_url = self._follow_auth_redirects(auth_url) - self._delay() accounts_api_base = self._accounts_api_base(auth_url) register_url = self._register_endpoint(auth_url) diff --git a/src/http_client.py b/src/http_client.py index c025d36..2501c4c 100644 --- a/src/http_client.py +++ b/src/http_client.py @@ -1,3 +1,5 @@ +import random +import time import uuid from curl_cffi import requests as curl_requests @@ -16,6 +18,10 @@ class HTTPClient: "sec-ch-ua-platform": '"macOS"', }) self.device_id = str(uuid.uuid4()) + self._pacing_enabled = False + self._pacing_min_delay = 0.5 + self._pacing_max_delay = 2.0 + self._has_completed_request = False @staticmethod def _proxy_candidates(proxy: str) -> list[str]: @@ -42,12 +48,16 @@ class HTTPClient: return ordered def request(self, method: str, url: str, **kwargs): + skip_pacing = kwargs.pop("skip_pacing", False) kwargs.setdefault("timeout", 30) kwargs.setdefault("allow_redirects", False) # This environment/proxy setup does not expose a usable CA bundle to curl_cffi. kwargs.setdefault("verify", False) + self._maybe_delay_before_request(skip_pacing=skip_pacing) if not self.proxy_candidates: - return self.session.request(method, url, **kwargs) + response = self.session.request(method, url, **kwargs) + self._has_completed_request = True + return response last_exc = None for index, proxy in enumerate(self.proxy_candidates): @@ -58,6 +68,7 @@ class HTTPClient: print(f" Retrying HTTP request with proxy scheme fallback: {proxy.split('://', 1)[0]}") response = self.session.request(method, url, **request_kwargs) self.proxy = proxy + self._has_completed_request = True return response except Exception as exc: last_exc = exc @@ -65,5 +76,24 @@ class HTTPClient: raise raise last_exc + def enable_pacing(self, min_delay: float = 0.5, max_delay: float = 2.0): + if min_delay < 0 or max_delay < min_delay: + raise ValueError("Invalid pacing delay range") + self._pacing_enabled = True + self._pacing_min_delay = min_delay + self._pacing_max_delay = max_delay + self._has_completed_request = False + + def disable_pacing(self): + self._pacing_enabled = False + self._has_completed_request = False + + def _maybe_delay_before_request(self, skip_pacing: bool = False): + if skip_pacing or not self._pacing_enabled or not self._has_completed_request: + return + delay = random.uniform(self._pacing_min_delay, self._pacing_max_delay) + print(f" Human pacing delay: sleeping {delay:.2f}s before next request...") + time.sleep(delay) + def close(self): self.session.close() diff --git a/src/main.py b/src/main.py index b881708..20b3df9 100644 --- a/src/main.py +++ b/src/main.py @@ -40,6 +40,7 @@ def cmd_register(args): mail = MailClient() http = HTTPClient(proxy=settings.socks5_proxy) + http.enable_pacing(min_delay=0.5, max_delay=2.0) try: print("\n=== ChatGPT Registration ===")