dan92 commited on
Commit
858b443
·
verified ·
1 Parent(s): 199c4e9

Upload 7 files

Browse files
Files changed (3) hide show
  1. Dockerfile +4 -3
  2. app.py +102 -36
  3. register_bot.py +303 -303
Dockerfile CHANGED
@@ -10,9 +10,10 @@ COPY requirements.txt .
10
  RUN pip install --upgrade pip && \
11
  pip install --no-cache-dir -r requirements.txt gunicorn
12
 
13
- # 复制应用程序文件
14
  COPY app.py .
15
  COPY register_bot.py .
 
16
 
17
  # 设置环境变量
18
  ENV FLASK_APP=app.py
@@ -22,5 +23,5 @@ ENV PYTHONUNBUFFERED=1
22
  # 暴露端口
23
  EXPOSE 3000
24
 
25
- # 使用 gunicorn 作为生产级 WSGI 服务器
26
- CMD ["gunicorn", "--bind", "0.0.0.0:3000", "--workers", "4", "app:app"]
 
10
  RUN pip install --upgrade pip && \
11
  pip install --no-cache-dir -r requirements.txt gunicorn
12
 
13
+ # 复制应用程序文件和模板
14
  COPY app.py .
15
  COPY register_bot.py .
16
+ COPY templates templates/
17
 
18
  # 设置环境变量
19
  ENV FLASK_APP=app.py
 
23
  # 暴露端口
24
  EXPOSE 3000
25
 
26
+ # 使用 gunicorn 作为生产级 WSGI 服务器,添加错误日志
27
+ CMD ["gunicorn", "--bind", "0.0.0.0:3000", "--workers", "4", "--log-level", "debug", "--error-logfile", "-", "app:app"]
app.py CHANGED
@@ -19,6 +19,7 @@ import urllib3
19
  from cachetools import TTLCache
20
  import threading
21
  from datetime import datetime
 
22
 
23
  # 新增导入
24
  import register_bot
@@ -490,7 +491,7 @@ def get_auth_credentials():
490
  if data.get('status') == 'success' and data.get('content'):
491
  content = data['content']
492
  credentials = []
493
- # 分割多个凭据(如果��的话)
494
  for cred in content.split(';'):
495
  if '|' in cred:
496
  email, password = cred.strip().split('|')
@@ -555,44 +556,83 @@ def get_accounts_status():
555
 
556
  @app.route('/', methods=['GET'])
557
  def root():
558
- accounts_status = get_accounts_status()
559
-
560
- if request.headers.get('Accept') == 'application/json':
561
- return get_json_status(accounts_status)
562
-
563
- return render_template('monitor.html', **get_template_data(accounts_status))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
564
 
565
  def get_template_data(accounts_status):
566
- total_accounts = len(accounts_status)
567
- valid_accounts = sum(1 for acc in accounts_status if acc["is_valid"])
568
-
569
- accounts_data = []
570
- total_requests = 0
571
-
572
- for auth_manager in multi_auth_manager.auth_managers:
573
- success_rate = 0
574
- if auth_manager.total_requests > 0:
575
- success_rate = (auth_manager.success_requests / auth_manager.total_requests) * 100
576
 
577
- account_info = {
578
- "email": auth_manager._email,
579
- "is_valid": auth_manager.is_token_valid(),
580
- "total_requests": auth_manager.total_requests,
581
- "success_requests": auth_manager.success_requests,
582
- "failed_requests": auth_manager.failed_requests,
583
- "success_rate": success_rate,
584
- "last_used_time": auth_manager.last_used_time.strftime('%m/%d/%Y, %I:%M:%S %p') if auth_manager.last_used_time else "从未使用"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  }
586
- accounts_data.append(account_info)
587
- total_requests += auth_manager.total_requests
588
-
589
- return {
590
- "total_accounts": total_accounts,
591
- "valid_accounts": valid_accounts,
592
- "total_requests": total_requests,
593
- "accounts": accounts_data,
594
- "last_update": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
595
- }
596
 
597
  def get_json_status(accounts_status):
598
  template_data = get_template_data(accounts_status)
@@ -789,7 +829,7 @@ def make_request(payload, auth_manager, model_id):
789
 
790
  if response.status_code == 403: # Forbidden, 模型使用限制
791
  logger.warning(f"Model {model_id} usage limit reached for account {auth_manager._email}")
792
- # 立即触发注册
793
  if trigger_registration():
794
  # 重试请求
795
  return make_request(payload, None, model_id)
@@ -841,3 +881,29 @@ if __name__ == "__main__":
841
  port = int(os.environ.get("PORT", 3000))
842
  app.run(debug=False, host='0.0.0.0', port=port, threaded=True)
843
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  from cachetools import TTLCache
20
  import threading
21
  from datetime import datetime
22
+ from werkzeug.exceptions import HTTPException
23
 
24
  # 新增导入
25
  import register_bot
 
491
  if data.get('status') == 'success' and data.get('content'):
492
  content = data['content']
493
  credentials = []
494
+ # 分割多个凭据(如果的话)
495
  for cred in content.split(';'):
496
  if '|' in cred:
497
  email, password = cred.strip().split('|')
 
556
 
557
  @app.route('/', methods=['GET'])
558
  def root():
559
+ try:
560
+ accounts_status = get_accounts_status()
561
+
562
+ if request.headers.get('Accept') == 'application/json':
563
+ return get_json_status(accounts_status)
564
+
565
+ template_data = get_template_data(accounts_status)
566
+ return render_template('monitor.html', **template_data)
567
+ except Exception as e:
568
+ logger.error(f"Error in root route: {str(e)}", exc_info=True)
569
+ if request.headers.get('Accept') == 'application/json':
570
+ return jsonify({
571
+ "error": "Internal Server Error",
572
+ "message": str(e)
573
+ }), 500
574
+ # 对于 HTML 请求,返回一个简单的错误页面
575
+ error_html = """
576
+ <html>
577
+ <head><title>Error</title></head>
578
+ <body>
579
+ <h1>Internal Server Error</h1>
580
+ <p>An error occurred while processing your request.</p>
581
+ <p>Error details: {}</p>
582
+ <p><a href="javascript:location.reload()">Retry</a></p>
583
+ </body>
584
+ </html>
585
+ """.format(str(e) if app.debug else "Please try again later")
586
+ return error_html, 500
587
 
588
  def get_template_data(accounts_status):
589
+ try:
590
+ if not multi_auth_manager or not multi_auth_manager.auth_managers:
591
+ return {
592
+ "total_accounts": 0,
593
+ "valid_accounts": 0,
594
+ "total_requests": 0,
595
+ "accounts": [],
596
+ "last_update": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
597
+ }
 
598
 
599
+ total_accounts = len(accounts_status)
600
+ valid_accounts = sum(1 for acc in accounts_status if acc["is_valid"])
601
+
602
+ accounts_data = []
603
+ total_requests = 0
604
+
605
+ for auth_manager in multi_auth_manager.auth_managers:
606
+ try:
607
+ success_rate = 0
608
+ if auth_manager.total_requests > 0:
609
+ success_rate = (auth_manager.success_requests / auth_manager.total_requests) * 100
610
+
611
+ account_info = {
612
+ "email": auth_manager._email,
613
+ "is_valid": auth_manager.is_token_valid(),
614
+ "total_requests": auth_manager.total_requests,
615
+ "success_requests": auth_manager.success_requests,
616
+ "failed_requests": auth_manager.failed_requests,
617
+ "success_rate": success_rate,
618
+ "last_used_time": auth_manager.last_used_time.strftime('%m/%d/%Y, %I:%M:%S %p') if auth_manager.last_used_time else "从未使用"
619
+ }
620
+ accounts_data.append(account_info)
621
+ total_requests += auth_manager.total_requests
622
+ except Exception as e:
623
+ logger.error(f"Error processing account {auth_manager._email}: {str(e)}", exc_info=True)
624
+ continue
625
+
626
+ return {
627
+ "total_accounts": total_accounts,
628
+ "valid_accounts": valid_accounts,
629
+ "total_requests": total_requests,
630
+ "accounts": accounts_data,
631
+ "last_update": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
632
  }
633
+ except Exception as e:
634
+ logger.error(f"Error in get_template_data: {str(e)}", exc_info=True)
635
+ raise
 
 
 
 
 
 
 
636
 
637
  def get_json_status(accounts_status):
638
  template_data = get_template_data(accounts_status)
 
829
 
830
  if response.status_code == 403: # Forbidden, 模型使用限制
831
  logger.warning(f"Model {model_id} usage limit reached for account {auth_manager._email}")
832
+ # ��即触发注册
833
  if trigger_registration():
834
  # 重试请求
835
  return make_request(payload, None, model_id)
 
881
  port = int(os.environ.get("PORT", 3000))
882
  app.run(debug=False, host='0.0.0.0', port=port, threaded=True)
883
 
884
+ # 添加错误处理器
885
+ @app.errorhandler(Exception)
886
+ def handle_exception(e):
887
+ """处理所有异常"""
888
+ logger.error(f"Unhandled exception: {str(e)}", exc_info=True)
889
+
890
+ # 如果是 HTTP 异常,返回其状态码
891
+ if isinstance(e, HTTPException):
892
+ return jsonify({
893
+ "error": {
894
+ "type": "http_error",
895
+ "code": e.code,
896
+ "name": e.name,
897
+ "description": e.description
898
+ }
899
+ }), e.code
900
+
901
+ # 其他异常返回 500
902
+ return jsonify({
903
+ "error": {
904
+ "type": "server_error",
905
+ "message": "Internal Server Error",
906
+ "details": str(e) if app.debug else "An unexpected error occurred"
907
+ }
908
+ }), 500
909
+
register_bot.py CHANGED
@@ -1,303 +1,303 @@
1
- import requests
2
- from bs4 import BeautifulSoup
3
- from requests.adapters import HTTPAdapter
4
- from requests.packages.urllib3.util.retry import Retry
5
- import uuid
6
- import json
7
- import time
8
- import re
9
- import hashlib
10
- import base64
11
- import random
12
- import string
13
- import os
14
- import sys
15
- from urllib.parse import quote, urlparse, parse_qs
16
- import concurrent.futures
17
- import logging
18
-
19
- # 配置日志(仅控制台输出)
20
- logging.basicConfig(
21
- level=logging.DEBUG, # 改为DEBUG级别,获取更详细的日志
22
- format='%(asctime)s - %(levelname)s - %(message)s',
23
- stream=sys.stdout
24
- )
25
-
26
- # 获取环境变量
27
- PASTE_API_URL = os.getenv('PASTE_API_URL')
28
- PASTE_API_PASSWORD = os.getenv('PASTE_API_PASSWORD')
29
-
30
- # 构建上传 URL
31
- UPLOAD_URL = PASTE_API_URL.replace('/api/paste/', '/api/admin/paste/') + '/content'
32
-
33
- # 新的临时邮箱API
34
- TEMP_EMAIL_API = "https://www.1secmail.com/api/v1/?action=genRandomMailbox"
35
-
36
- # 注册 API 地址
37
- REGISTER_API_URL = "https://spuckhogycrxcbomznwo.supabase.co/auth/v1/signup?redirect_to=https%3A%2F%2Fchat.notdiamond.ai"
38
-
39
- # Supabase API
40
- SUPABASE_API_KEY = os.getenv('SUPABASE_API_KEY')
41
-
42
- # 请求限制和重试相关配置
43
- MAX_RETRIES = 3
44
- RETRY_DELAY = 10 # 秒
45
- RATE_LIMIT_DELAY = 60 # 秒
46
-
47
- def generate_strong_password():
48
- """固定密码为password123"""
49
- return "password123"
50
-
51
- def generate_code_verifier():
52
- return base64.urlsafe_b64encode(uuid.uuid4().bytes).decode('utf-8').rstrip('=')
53
-
54
- def generate_code_challenge(code_verifier):
55
- code_challenge = hashlib.sha256(code_verifier.encode('utf-8')).digest()
56
- return base64.urlsafe_b64encode(code_challenge).decode('utf-8').rstrip('=')
57
-
58
- def get_temp_email():
59
- session = requests.Session()
60
- retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
61
- session.mount('https://', HTTPAdapter(max_retries=retries))
62
-
63
- try:
64
- response = session.get(TEMP_EMAIL_API)
65
- if response.status_code == 200:
66
- email = response.json()[0]
67
- logging.info(f"Generated temp email: {email}")
68
- return email
69
- except requests.exceptions.SSLError as e:
70
- logging.error(f"SSL Error getting temp email: {e}")
71
- return None
72
-
73
- def register(email, password):
74
- for attempt in range(MAX_RETRIES):
75
- session = requests.Session()
76
- headers = {
77
- 'apikey': SUPABASE_API_KEY,
78
- 'authorization': f'Bearer {SUPABASE_API_KEY}',
79
- 'content-type': 'application/json'
80
- }
81
-
82
- code_verifier = generate_code_verifier()
83
- code_challenge = generate_code_challenge(code_verifier)
84
-
85
- payload = {
86
- 'email': email,
87
- 'password': password,
88
- 'code_challenge': code_challenge,
89
- 'code_challenge_method': 's256',
90
- 'data': {},
91
- 'gotrue_meta_security': {}
92
- }
93
-
94
- try:
95
- response = session.post(REGISTER_API_URL, headers=headers, json=payload)
96
-
97
- logging.info(f"Registration response status: {response.status_code}")
98
- logging.info(f"Registration response content: {response.text}")
99
-
100
- if response.status_code == 200:
101
- logging.info(f"Registered successfully with email: {email}")
102
- return True
103
- elif response.status_code == 429:
104
- logging.warning(f"Rate limit reached. Waiting {RATE_LIMIT_DELAY} seconds.")
105
- time.sleep(RATE_LIMIT_DELAY)
106
- else:
107
- logging.error(f"Failed to register with email: {email}. Response: {response.text}")
108
- return False
109
-
110
- except requests.exceptions.RequestException as e:
111
- logging.error(f"Request error during registration: {e}")
112
- if attempt < MAX_RETRIES - 1:
113
- logging.info(f"Retrying registration in {RETRY_DELAY} seconds...")
114
- time.sleep(RETRY_DELAY)
115
- else:
116
- logging.error("Max registration retries reached.")
117
- return False
118
-
119
- return False
120
-
121
- def save_account(email, password):
122
- try:
123
- session = requests.Session()
124
-
125
- # 首先进行认证
126
- auth_url = PASTE_API_URL
127
- auth_headers = {
128
- 'accept': '*/*',
129
- 'accept-language': 'zh-CN,zh;q=0.9',
130
- 'user-agent': 'Mozilla/5.0',
131
- 'x-password': PASTE_API_PASSWORD
132
- }
133
-
134
- # 获取现有内容
135
- logging.info(f"Authenticating with URL: {auth_url}")
136
- response = session.get(auth_url, headers=auth_headers)
137
-
138
- logging.info(f"Authentication response status: {response.status_code}")
139
- logging.info(f"Authentication response content: {response.text}")
140
-
141
- if response.status_code != 200:
142
- logging.error(f"Authentication failed, status code: {response.status_code}")
143
- return False
144
-
145
- # 从响应获取现有内容
146
- existing_data = response.json()
147
- existing_content = existing_data.get('content', '')
148
-
149
- # 构建新的内容
150
- if existing_content:
151
- new_content = f"{existing_content};{email}|{password}"
152
- else:
153
- new_content = f"{email}|{password}"
154
-
155
- logging.info(f"New content to upload: {new_content}")
156
-
157
- # 上传新内容
158
- upload_headers = {
159
- 'Authorization': 'Basic emhvdWRhbjp6aG91ZGFu',
160
- 'Content-Type': 'application/json'
161
- }
162
-
163
- upload_payload = {
164
- 'content': new_content
165
- }
166
-
167
- logging.info(f"Uploading to URL: {UPLOAD_URL}")
168
- upload_response = session.put(UPLOAD_URL, headers=upload_headers, json=upload_payload)
169
-
170
- logging.info(f"Upload response status: {upload_response.status_code}")
171
- logging.info(f"Upload response content: {upload_response.text}")
172
-
173
- if upload_response.status_code == 200:
174
- logging.info(f"Successfully uploaded account {email}")
175
- return True
176
- else:
177
- logging.error(f"Failed to upload account {email}. Status code: {upload_response.status_code}")
178
- return False
179
-
180
- except Exception as e:
181
- logging.error(f"Comprehensive error uploading account: {e}")
182
- return False
183
-
184
- def check_email(email):
185
- domain = email.split('@')[1]
186
- login = email.split('@')[0]
187
-
188
- # 获取消息ID
189
- mailbox_url = f"https://www.1secmail.com/api/v1/?action=getMessages&login={login}&domain={domain}"
190
-
191
- session = requests.Session()
192
- retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
193
- session.mount('https://', HTTPAdapter(max_retries=retries))
194
-
195
- logging.info(f"Checking email for {email}")
196
-
197
- time.sleep(10)
198
-
199
- for _ in range(20):
200
- try:
201
- response = session.get(mailbox_url)
202
- logging.info(f"Email check response status: {response.status_code}")
203
-
204
- if response.status_code == 200 and response.json():
205
- for message in response.json():
206
- if "Confirm Your Signup" in message.get('subject', ''):
207
- # 获取完整邮件内容
208
- message_url = f"https://www.1secmail.com/api/v1/?action=readMessage&login={login}&domain={domain}&id={message['id']}"
209
- message_response = session.get(message_url)
210
-
211
- if message_response.status_code == 200:
212
- full_message = message_response.json()
213
- logging.info(f"Full message content found: {full_message}")
214
-
215
- # 提取验证链接
216
- match = re.search(r'https?://chat\.notdiamond\.ai/auth/confirm\?[^\s]+', full_message.get('body', ''))
217
- if match:
218
- verification_link = match.group(0)
219
- logging.info(f"Verification link found: {verification_link}")
220
-
221
- # 解析 URL 并获取参数
222
- parsed_url = urlparse(verification_link)
223
- query_params = parse_qs(parsed_url.query)
224
-
225
- # 使用 Supabase API 进行验证
226
- verify_url = "https://spuckhogycrxcbomznwo.supabase.co/auth/v1/verify"
227
- headers = {
228
- 'apikey': SUPABASE_API_KEY,
229
- 'authorization': f'Bearer {SUPABASE_API_KEY}',
230
- 'content-type': 'application/json'
231
- }
232
-
233
- payload = {
234
- 'token_hash': query_params['token_hash'][0],
235
- 'type': 'signup' # 硬编码为 'signup'
236
- }
237
-
238
- verify_response = session.post(verify_url, headers=headers, json=payload)
239
-
240
- logging.info(f"Verification response status: {verify_response.status_code}")
241
-
242
- if verify_response.status_code == 200:
243
- logging.info(f"Email verified for {email}")
244
- return True
245
- else:
246
- logging.error(f"Failed to verify email for {email}: {verify_response.text}")
247
- return False
248
- else:
249
- logging.error(f"Failed to extract verification link from email for {email}")
250
- return False
251
- time.sleep(5)
252
- except Exception as e:
253
- logging.error(f"Error during email verification: {e}")
254
-
255
- logging.warning(f"No verification email found for {email}")
256
- return False
257
-
258
- def register_and_verify(num_accounts=1):
259
- successful_accounts = []
260
- with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
261
- futures = []
262
- for _ in range(num_accounts):
263
- email = get_temp_email()
264
- if email:
265
- futures.append(executor.submit(process_account, email))
266
- time.sleep(RETRY_DELAY)
267
-
268
- for future in concurrent.futures.as_completed(futures):
269
- result = future.result()
270
- if result:
271
- successful_accounts.append(result)
272
-
273
- return successful_accounts
274
-
275
- def process_account(email):
276
- try:
277
- # 使用固定密码
278
- password = generate_strong_password()
279
-
280
- if register(email, password):
281
- save_result = save_account(email, password)
282
- if not save_result:
283
- logging.error(f"Failed to save account {email}")
284
- return None
285
-
286
- if check_email(email):
287
- logging.info(f"Account fully processed: {email}")
288
- return {'email': email, 'password': password}
289
- except Exception as e:
290
- logging.error(f"Error processing account {email}: {e}")
291
- return None
292
-
293
- def main():
294
- num_accounts = 5 # 可以根据需要修改注册数量
295
- successful_accounts = register_and_verify(num_accounts)
296
-
297
- # 仅输出到控制台
298
- print(f"Successfully registered {len(successful_accounts)} accounts")
299
- for account in successful_accounts:
300
- print(f"Email: {account['email']}, Password: {account['password']}")
301
-
302
- if __name__ == "__main__":
303
- main()
 
1
+ import requests
2
+ from bs4 import BeautifulSoup
3
+ from requests.adapters import HTTPAdapter
4
+ from requests.packages.urllib3.util.retry import Retry
5
+ import uuid
6
+ import json
7
+ import time
8
+ import re
9
+ import hashlib
10
+ import base64
11
+ import random
12
+ import string
13
+ import os
14
+ import sys
15
+ from urllib.parse import quote, urlparse, parse_qs
16
+ import concurrent.futures
17
+ import logging
18
+
19
+ # 配置日志(仅控制台输出)
20
+ logging.basicConfig(
21
+ level=logging.DEBUG, # 改为DEBUG级别,获取更详细的日志
22
+ format='%(asctime)s - %(levelname)s - %(message)s',
23
+ stream=sys.stdout
24
+ )
25
+
26
+ # 获取环境变量
27
+ PASTE_API_URL = os.getenv('PASTE_API_URL')
28
+ PASTE_API_PASSWORD = os.getenv('PASTE_API_PASSWORD')
29
+
30
+ # 构建上传 URL
31
+ UPLOAD_URL = PASTE_API_URL.replace('/api/paste/', '/api/admin/paste/') + '/content'
32
+
33
+ # 新的临时邮箱API
34
+ TEMP_EMAIL_API = "https://www.1secmail.com/api/v1/?action=genRandomMailbox"
35
+
36
+ # 注册 API 地址
37
+ REGISTER_API_URL = "https://spuckhogycrxcbomznwo.supabase.co/auth/v1/signup?redirect_to=https%3A%2F%2Fchat.notdiamond.ai"
38
+
39
+ # Supabase API
40
+ SUPABASE_API_KEY = os.getenv('SUPABASE_API_KEY')
41
+
42
+ # 请求限制和重试相关配置
43
+ MAX_RETRIES = 3
44
+ RETRY_DELAY = 10 # 秒
45
+ RATE_LIMIT_DELAY = 60 # 秒
46
+
47
+ def generate_strong_password():
48
+ """固定密码为password123"""
49
+ return "password123"
50
+
51
+ def generate_code_verifier():
52
+ return base64.urlsafe_b64encode(uuid.uuid4().bytes).decode('utf-8').rstrip('=')
53
+
54
+ def generate_code_challenge(code_verifier):
55
+ code_challenge = hashlib.sha256(code_verifier.encode('utf-8')).digest()
56
+ return base64.urlsafe_b64encode(code_challenge).decode('utf-8').rstrip('=')
57
+
58
+ def get_temp_email():
59
+ session = requests.Session()
60
+ retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
61
+ session.mount('https://', HTTPAdapter(max_retries=retries))
62
+
63
+ try:
64
+ response = session.get(TEMP_EMAIL_API)
65
+ if response.status_code == 200:
66
+ email = response.json()[0]
67
+ logging.info(f"Generated temp email: {email}")
68
+ return email
69
+ except requests.exceptions.SSLError as e:
70
+ logging.error(f"SSL Error getting temp email: {e}")
71
+ return None
72
+
73
+ def register(email, password):
74
+ for attempt in range(MAX_RETRIES):
75
+ session = requests.Session()
76
+ headers = {
77
+ 'apikey': SUPABASE_API_KEY,
78
+ 'authorization': f'Bearer {SUPABASE_API_KEY}',
79
+ 'content-type': 'application/json'
80
+ }
81
+
82
+ code_verifier = generate_code_verifier()
83
+ code_challenge = generate_code_challenge(code_verifier)
84
+
85
+ payload = {
86
+ 'email': email,
87
+ 'password': password,
88
+ 'code_challenge': code_challenge,
89
+ 'code_challenge_method': 's256',
90
+ 'data': {},
91
+ 'gotrue_meta_security': {}
92
+ }
93
+
94
+ try:
95
+ response = session.post(REGISTER_API_URL, headers=headers, json=payload)
96
+
97
+ logging.info(f"Registration response status: {response.status_code}")
98
+ logging.info(f"Registration response content: {response.text}")
99
+
100
+ if response.status_code == 200:
101
+ logging.info(f"Registered successfully with email: {email}")
102
+ return True
103
+ elif response.status_code == 429:
104
+ logging.warning(f"Rate limit reached. Waiting {RATE_LIMIT_DELAY} seconds.")
105
+ time.sleep(RATE_LIMIT_DELAY)
106
+ else:
107
+ logging.error(f"Failed to register with email: {email}. Response: {response.text}")
108
+ return False
109
+
110
+ except requests.exceptions.RequestException as e:
111
+ logging.error(f"Request error during registration: {e}")
112
+ if attempt < MAX_RETRIES - 1:
113
+ logging.info(f"Retrying registration in {RETRY_DELAY} seconds...")
114
+ time.sleep(RETRY_DELAY)
115
+ else:
116
+ logging.error("Max registration retries reached.")
117
+ return False
118
+
119
+ return False
120
+
121
+ def save_account(email, password):
122
+ try:
123
+ session = requests.Session()
124
+
125
+ # 首先进行认证
126
+ auth_url = PASTE_API_URL
127
+ auth_headers = {
128
+ 'accept': '*/*',
129
+ 'accept-language': 'zh-CN,zh;q=0.9',
130
+ 'user-agent': 'Mozilla/5.0',
131
+ 'x-password': PASTE_API_PASSWORD
132
+ }
133
+
134
+ # 获取现有内容
135
+ logging.info(f"Authenticating with URL: {auth_url}")
136
+ response = session.get(auth_url, headers=auth_headers)
137
+
138
+ logging.info(f"Authentication response status: {response.status_code}")
139
+ logging.info(f"Authentication response content: {response.text}")
140
+
141
+ if response.status_code != 200:
142
+ logging.error(f"Authentication failed, status code: {response.status_code}")
143
+ return False
144
+
145
+ # 从响应获取现有内容
146
+ existing_data = response.json()
147
+ existing_content = existing_data.get('content', '')
148
+
149
+ # 构建新的内容
150
+ if existing_content:
151
+ new_content = f"{existing_content};{email}|{password}"
152
+ else:
153
+ new_content = f"{email}|{password}"
154
+
155
+ logging.info(f"New content to upload: {new_content}")
156
+
157
+ # 上传新内容
158
+ upload_headers = {
159
+ 'Authorization': 'Basic emhvdWRhbjp6aG91ZGFu',
160
+ 'Content-Type': 'application/json'
161
+ }
162
+
163
+ upload_payload = {
164
+ 'content': new_content
165
+ }
166
+
167
+ logging.info(f"Uploading to URL: {UPLOAD_URL}")
168
+ upload_response = session.put(UPLOAD_URL, headers=upload_headers, json=upload_payload)
169
+
170
+ logging.info(f"Upload response status: {upload_response.status_code}")
171
+ logging.info(f"Upload response content: {upload_response.text}")
172
+
173
+ if upload_response.status_code == 200:
174
+ logging.info(f"Successfully uploaded account {email}")
175
+ return True
176
+ else:
177
+ logging.error(f"Failed to upload account {email}. Status code: {upload_response.status_code}")
178
+ return False
179
+
180
+ except Exception as e:
181
+ logging.error(f"Comprehensive error uploading account: {e}")
182
+ return False
183
+
184
+ def check_email(email):
185
+ domain = email.split('@')[1]
186
+ login = email.split('@')[0]
187
+
188
+ # 获取消息ID
189
+ mailbox_url = f"https://www.1secmail.com/api/v1/?action=getMessages&login={login}&domain={domain}"
190
+
191
+ session = requests.Session()
192
+ retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
193
+ session.mount('https://', HTTPAdapter(max_retries=retries))
194
+
195
+ logging.info(f"Checking email for {email}")
196
+
197
+ time.sleep(10)
198
+
199
+ for _ in range(20):
200
+ try:
201
+ response = session.get(mailbox_url)
202
+ logging.info(f"Email check response status: {response.status_code}")
203
+
204
+ if response.status_code == 200 and response.json():
205
+ for message in response.json():
206
+ if "Confirm Your Signup" in message.get('subject', ''):
207
+ # 获取完整邮件内容
208
+ message_url = f"https://www.1secmail.com/api/v1/?action=readMessage&login={login}&domain={domain}&id={message['id']}"
209
+ message_response = session.get(message_url)
210
+
211
+ if message_response.status_code == 200:
212
+ full_message = message_response.json()
213
+ logging.info(f"Full message content found: {full_message}")
214
+
215
+ # 提取验证链接
216
+ match = re.search(r'https?://chat\.notdiamond\.ai/auth/confirm\?[^\s]+', full_message.get('body', ''))
217
+ if match:
218
+ verification_link = match.group(0)
219
+ logging.info(f"Verification link found: {verification_link}")
220
+
221
+ # 解析 URL 并获取参数
222
+ parsed_url = urlparse(verification_link)
223
+ query_params = parse_qs(parsed_url.query)
224
+
225
+ # 使用 Supabase API 进行验证
226
+ verify_url = "https://spuckhogycrxcbomznwo.supabase.co/auth/v1/verify"
227
+ headers = {
228
+ 'apikey': SUPABASE_API_KEY,
229
+ 'authorization': f'Bearer {SUPABASE_API_KEY}',
230
+ 'content-type': 'application/json'
231
+ }
232
+
233
+ payload = {
234
+ 'token_hash': query_params['token_hash'][0],
235
+ 'type': 'signup' # 硬编码为 'signup'
236
+ }
237
+
238
+ verify_response = session.post(verify_url, headers=headers, json=payload)
239
+
240
+ logging.info(f"Verification response status: {verify_response.status_code}")
241
+
242
+ if verify_response.status_code == 200:
243
+ logging.info(f"Email verified for {email}")
244
+ return True
245
+ else:
246
+ logging.error(f"Failed to verify email for {email}: {verify_response.text}")
247
+ return False
248
+ else:
249
+ logging.error(f"Failed to extract verification link from email for {email}")
250
+ return False
251
+ time.sleep(5)
252
+ except Exception as e:
253
+ logging.error(f"Error during email verification: {e}")
254
+
255
+ logging.warning(f"No verification email found for {email}")
256
+ return False
257
+
258
+ def register_and_verify(num_accounts=1):
259
+ successful_accounts = []
260
+ with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
261
+ futures = []
262
+ for _ in range(num_accounts):
263
+ email = get_temp_email()
264
+ if email:
265
+ futures.append(executor.submit(process_account, email))
266
+ time.sleep(RETRY_DELAY)
267
+
268
+ for future in concurrent.futures.as_completed(futures):
269
+ result = future.result()
270
+ if result:
271
+ successful_accounts.append(result)
272
+
273
+ return successful_accounts
274
+
275
+ def process_account(email):
276
+ try:
277
+ # 使用固定密码
278
+ password = generate_strong_password()
279
+
280
+ if register(email, password):
281
+ save_result = save_account(email, password)
282
+ if not save_result:
283
+ logging.error(f"Failed to save account {email}")
284
+ return None
285
+
286
+ if check_email(email):
287
+ logging.info(f"Account fully processed: {email}")
288
+ return {'email': email, 'password': password}
289
+ except Exception as e:
290
+ logging.error(f"Error processing account {email}: {e}")
291
+ return None
292
+
293
+ def main():
294
+ num_accounts = 5 # 可以根据需要修改注册数量
295
+ successful_accounts = register_and_verify(num_accounts)
296
+
297
+ # 仅输出到控制台
298
+ print(f"Successfully registered {len(successful_accounts)} accounts")
299
+ for account in successful_accounts:
300
+ print(f"Email: {account['email']}, Password: {account['password']}")
301
+
302
+ if __name__ == "__main__":
303
+ main()