cacode commited on
Commit
1257cc2
·
verified ·
1 Parent(s): bbc6b0b

Upload 7 files

Browse files
Files changed (7) hide show
  1. Dockerfile +24 -0
  2. app.py +45 -0
  3. logger.py +12 -0
  4. register.py +242 -0
  5. requirements.txt +6 -0
  6. scheduler.py +23 -0
  7. uploader.py +53 -0
Dockerfile ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # 安装 Chromium 及依赖
4
+ RUN apt-get update && apt-get install -y \
5
+ chromium \
6
+ chromium-driver \
7
+ fonts-liberation \
8
+ libnss3 \
9
+ libatk-bridge2.0-0 \
10
+ libgtk-3-0 \
11
+ libxss1 \
12
+ libasound2 \
13
+ libgbm1 \
14
+ && rm -rf /var/lib/apt/lists/*
15
+
16
+ ENV CHROME_BIN=/usr/bin/chromium
17
+ ENV CHROMEDRIVER_BIN=/usr/bin/chromedriver
18
+
19
+ WORKDIR /app
20
+ COPY . /app
21
+
22
+ RUN pip install --no-cache-dir -r requirements.txt
23
+
24
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.responses import HTMLResponse
3
+ import threading
4
+
5
+ from scheduler import scheduler_loop
6
+
7
+ app = FastAPI()
8
+
9
+ @app.on_event("startup")
10
+ def start_scheduler():
11
+ t = threading.Thread(target=scheduler_loop, daemon=True)
12
+ t.start()
13
+
14
+ @app.get("/", response_class=HTMLResponse)
15
+ def index():
16
+ try:
17
+ logs = open("runtime.log", "r", encoding="utf-8").read()[-20000:]
18
+ except:
19
+ logs = ""
20
+
21
+ return f"""
22
+ <html>
23
+ <head>
24
+ <meta http-equiv="refresh" content="5">
25
+ <title>Gemini Auto Register</title>
26
+ <style>
27
+ body {{
28
+ background:#0b0b0b;
29
+ color:#00ff9c;
30
+ font-family: monospace;
31
+ padding:20px;
32
+ }}
33
+ pre {{
34
+ white-space: pre-wrap;
35
+ font-size: 13px;
36
+ }}
37
+ </style>
38
+ </head>
39
+ <body>
40
+ <h2>Gemini Business 自动注册</h2>
41
+ <p>每 3 小时自动创建 5 个账号</p>
42
+ <pre>{logs}</pre>
43
+ </body>
44
+ </html>
45
+ """
logger.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime
2
+ import threading
3
+
4
+ LOG_FILE = "runtime.log"
5
+ _lock = threading.Lock()
6
+
7
+ def log(msg, level="INFO"):
8
+ line = f"[{datetime.now():%Y-%m-%d %H:%M:%S}] [{level}] {msg}"
9
+ with _lock:
10
+ with open(LOG_FILE, "a", encoding="utf-8") as f:
11
+ f.write(line + "\n")
12
+ print(line)
register.py ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Gemini Business 自动注册模块 (Docker / HF Space 版)
3
+ """
4
+
5
+ # ================= 标准库 =================
6
+ import json
7
+ import time
8
+ import random
9
+ from pathlib import Path
10
+ from datetime import datetime
11
+ from urllib.parse import urlparse, parse_qs
12
+ from concurrent.futures import ThreadPoolExecutor
13
+
14
+ # ================= 第三方 =================
15
+ import requests
16
+ from bs4 import BeautifulSoup
17
+ import undetected_chromedriver as uc
18
+ from selenium.webdriver.common.by import By
19
+ from selenium.webdriver.common.keys import Keys
20
+ from selenium.webdriver.support.ui import WebDriverWait
21
+ from selenium.webdriver.support import expected_conditions as EC
22
+
23
+ # ================= 项目内 =================
24
+ from logger import log
25
+
26
+
27
+ # ==================== 配置 ====================
28
+ LOGIN_URL = "https://auth.business.gemini.google/login?continueUrl=https:%2F%2Fbusiness.gemini.google%2F"
29
+
30
+ MAIL_API = "https://mail.chatgpt.org.uk"
31
+ MAIL_KEY = "gpt-test"
32
+
33
+ ACCOUNTS_FILE = "accounts.json"
34
+
35
+ HEADLESS_MODE = True
36
+
37
+ XPATH = {
38
+ "email_input": "//input[@type='email']",
39
+ "continue_btn": "//button",
40
+ }
41
+
42
+ NAMES = [
43
+ "James Smith", "John Johnson", "Robert Williams", "Michael Brown",
44
+ "William Jones", "David Garcia", "Mary Miller", "Patricia Davis",
45
+ "Jennifer Rodriguez", "Linda Martinez", "Elizabeth Taylor"
46
+ ]
47
+
48
+
49
+ # ==================== 邮箱 ====================
50
+ email_queue = []
51
+
52
+
53
+ def create_temp_email():
54
+ try:
55
+ r = requests.get(
56
+ f"{MAIL_API}/api/generate-email",
57
+ headers={"X-API-Key": MAIL_KEY},
58
+ timeout=20
59
+ )
60
+ if r.status_code == 200 and r.json().get("success"):
61
+ return r.json()["data"]["email"]
62
+ except Exception as e:
63
+ log(f"邮箱创建失败: {e}", "ERROR")
64
+ return None
65
+
66
+
67
+ def prefetch_email():
68
+ email = create_temp_email()
69
+ if email:
70
+ email_queue.append(email)
71
+
72
+
73
+ def get_email():
74
+ if email_queue:
75
+ email = email_queue.pop(0)
76
+ log(f"使用预取邮箱: {email}")
77
+ return email
78
+ email = create_temp_email()
79
+ log(f"新邮箱: {email}")
80
+ return email
81
+
82
+
83
+ def fetch_verification_code(email, timeout=90):
84
+ log("等待验证码...")
85
+ start = time.time()
86
+ while time.time() - start < timeout:
87
+ try:
88
+ r = requests.get(
89
+ f"{MAIL_API}/api/emails",
90
+ params={"email": email},
91
+ headers={"X-API-Key": MAIL_KEY},
92
+ timeout=10
93
+ )
94
+ if r.status_code == 200:
95
+ emails = r.json().get("data", {}).get("emails", [])
96
+ if emails:
97
+ soup = BeautifulSoup(
98
+ emails[0].get("html_content", ""),
99
+ "html.parser"
100
+ )
101
+ span = soup.find("span", class_="verification-code")
102
+ if span:
103
+ code = span.text.strip()
104
+ if len(code) == 6:
105
+ log(f"验证码: {code}", "OK")
106
+ return code
107
+ except:
108
+ pass
109
+ time.sleep(2)
110
+
111
+ log("验证码超时", "ERROR")
112
+ return None
113
+
114
+
115
+ # ==================== 浏览器 ====================
116
+ def create_driver():
117
+ options = uc.ChromeOptions()
118
+ options.add_argument("--headless=new")
119
+ options.add_argument("--no-sandbox")
120
+ options.add_argument("--disable-dev-shm-usage")
121
+ options.add_argument("--disable-gpu")
122
+ options.add_argument("--window-size=1280,800")
123
+
124
+ return uc.Chrome(options=options, use_subprocess=True)
125
+
126
+
127
+ # ==================== 保存配置 ====================
128
+ def save_account_config(email, driver):
129
+ cookies = driver.get_cookies()
130
+ url = driver.current_url
131
+ parsed = urlparse(url)
132
+
133
+ config_id = None
134
+ for p in url.split("/"):
135
+ if len(p) > 10 and p.isalnum():
136
+ config_id = p
137
+
138
+ cookie_map = {c["name"]: c["value"] for c in cookies}
139
+
140
+ csesidx = parse_qs(parsed.query).get("csesidx", [None])[0]
141
+
142
+ if not all([config_id, csesidx]):
143
+ log("配置提取失败", "ERROR")
144
+ return None
145
+
146
+ data = {
147
+ "id": email,
148
+ "config_id": config_id,
149
+ "csesidx": csesidx,
150
+ "cookies": cookie_map,
151
+ "expires_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
152
+ }
153
+
154
+ accounts = []
155
+ if Path(ACCOUNTS_FILE).exists():
156
+ accounts = json.load(open(ACCOUNTS_FILE, "r", encoding="utf-8"))
157
+
158
+ accounts.append(data)
159
+ json.dump(accounts, open(ACCOUNTS_FILE, "w", encoding="utf-8"), indent=2)
160
+
161
+ log(f"账号保存成功: {email}", "OK")
162
+ return data
163
+
164
+
165
+ # ==================== 注册单个 ====================
166
+ def register_single(driver, executor):
167
+ email = get_email()
168
+ wait = WebDriverWait(driver, 30)
169
+
170
+ try:
171
+ driver.get(LOGIN_URL)
172
+ time.sleep(2)
173
+
174
+ inp = wait.until(EC.element_to_be_clickable((By.XPATH, XPATH["email_input"])))
175
+ inp.clear()
176
+ inp.send_keys(email)
177
+ inp.send_keys(Keys.ENTER)
178
+
179
+ executor.submit(prefetch_email)
180
+
181
+ code = fetch_verification_code(email)
182
+ if not code:
183
+ return False
184
+
185
+ time.sleep(1)
186
+ driver.switch_to.active_element.send_keys(code)
187
+
188
+ time.sleep(2)
189
+
190
+ name = random.choice(NAMES)
191
+ driver.switch_to.active_element.send_keys(name)
192
+ driver.switch_to.active_element.send_keys(Keys.ENTER)
193
+
194
+ time.sleep(5)
195
+
196
+ save_account_config(email, driver)
197
+ log(f"注册成功: {email}", "OK")
198
+ return True
199
+
200
+ except Exception as e:
201
+ log(f"注册异常: {e}", "ERROR")
202
+ return False
203
+
204
+
205
+ # ==================== 批量注册 ====================
206
+ def run_batch_registration(target=5):
207
+ if Path(ACCOUNTS_FILE).exists():
208
+ Path(ACCOUNTS_FILE).unlink()
209
+
210
+ driver = create_driver()
211
+ executor = ThreadPoolExecutor(max_workers=2)
212
+
213
+ success = 0
214
+ attempts = 0
215
+
216
+ executor.submit(prefetch_email)
217
+
218
+ while success < target:
219
+ attempts += 1
220
+ log(f"开始注册第 {attempts} 次")
221
+ ok = register_single(driver, executor)
222
+ if ok:
223
+ success += 1
224
+ time.sleep(random.randint(2, 4))
225
+
226
+ driver.quit()
227
+ executor.shutdown(wait=False)
228
+
229
+ return {
230
+ "success": success,
231
+ "attempts": attempts,
232
+ "is_ok": success > 0
233
+ }
234
+
235
+
236
+ # ==================== 对外接口 ====================
237
+ def handle_task_execution(count, uploader):
238
+ stats = run_batch_registration(count)
239
+ if stats["is_ok"]:
240
+ uploader.login()
241
+ uploader.upload_and_merge(ACCOUNTS_FILE)
242
+ return stats
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ requests
4
+ beautifulsoup4
5
+ selenium
6
+ undetected-chromedriver
scheduler.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ from datetime import datetime
3
+ from uploader import AccountUploader
4
+ from register import handle_task_execution
5
+ from logger import log
6
+
7
+ API_HOST = "https://cacode-hajimi-bus-2api.hf.space/"
8
+ ADMIN_KEY = "CodeAtlantis"
9
+
10
+ INTERVAL = 3 * 60 * 60
11
+ COUNT = 5
12
+
13
+ def scheduler_loop():
14
+ uploader = AccountUploader(API_HOST, ADMIN_KEY)
15
+
16
+ while True:
17
+ log("==== 自动任务开始 ====")
18
+ try:
19
+ handle_task_execution(COUNT, uploader)
20
+ except Exception as e:
21
+ log(f"任务异常: {e}", "ERROR")
22
+ log("==== 任务结束,休眠 ====")
23
+ time.sleep(INTERVAL)
uploader.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import requests
3
+ from pathlib import Path
4
+ from logger import log
5
+
6
+ class AccountUploader:
7
+ def __init__(self, api_host, admin_key):
8
+ self.api_host = api_host.rstrip("/")
9
+ self.admin_key = admin_key
10
+ self.session = requests.Session()
11
+
12
+ def login(self):
13
+ log("连接服务器中...")
14
+ r = self.session.post(
15
+ f"{self.api_host}/login",
16
+ data={"admin_key": self.admin_key},
17
+ timeout=30
18
+ )
19
+ if self.session.cookies:
20
+ log("服务器登录成功", "OK")
21
+ return True
22
+ log("服务器登录失败", "ERROR")
23
+ return False
24
+
25
+ def upload_and_merge(self, file_path):
26
+ if not Path(file_path).exists():
27
+ log("账号文件不存在", "ERROR")
28
+ return False
29
+
30
+ local = json.load(open(file_path, "r", encoding="utf-8"))
31
+
32
+ r = self.session.get(f"{self.api_host}/admin/accounts-config", timeout=30)
33
+ remote = r.json().get("accounts", []) if r.status_code == 200 else []
34
+
35
+ ids = {a["id"] for a in remote}
36
+ merged = remote[:]
37
+
38
+ for a in local:
39
+ if a["id"] not in ids:
40
+ merged.append(a)
41
+
42
+ r = self.session.put(
43
+ f"{self.api_host}/admin/accounts-config",
44
+ json=merged,
45
+ timeout=30
46
+ )
47
+
48
+ if r.status_code == 200:
49
+ log(f"上传完成,共 {len(merged)} 个账号", "OK")
50
+ return True
51
+
52
+ log("上传失败", "ERROR")
53
+ return False