autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
73
skills/bulk-account-registration/templates/aq_daemon.py
Normal file
73
skills/bulk-account-registration/templates/aq_daemon.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Continuous registration daemon — reads IMAP, registers via proxies"""
|
||||
import imaplib as imap_lib, email as eml, re, requests, time, itertools
|
||||
from pathlib import Path
|
||||
|
||||
POOL = Path(r"C:\Users\User\aiqianshu_keys.txt")
|
||||
PROXIES = [
|
||||
'http://gothbreach:G0thBr3ach2026!@[REDACTED-IP]:3128',
|
||||
'http://[REDACTED-IP]:8888',
|
||||
]
|
||||
proxy_cycle = itertools.cycle(PROXIES)
|
||||
|
||||
def reg_one(idx, code):
|
||||
proxy = next(proxy_cycle)
|
||||
uname = f'goth_aq{idx:04d}'
|
||||
mail = f'[REDACTED-NAME]+aq{idx:04d}@gmail.com'
|
||||
s = requests.Session()
|
||||
s.proxies = {'http': proxy, 'https': proxy}
|
||||
s.headers.update({'Content-Type': 'application/json'})
|
||||
try:
|
||||
r = s.post('https://aiqianshu.com/api/user/register', json={
|
||||
'username': uname, 'email': mail, 'password': 'Goth@2026xX',
|
||||
'verification_code': code, 'agreement': True}, timeout=30)
|
||||
if r.status_code == 200 and r.json().get('success'):
|
||||
r = s.post('https://aiqianshu.com/api/user/login', json={'username': mail, 'password': 'Goth@2026xX'})
|
||||
uid = r.json()['data']['id']
|
||||
r = s.post('https://aiqianshu.com/api/token/', headers={'New-Api-User': str(uid)},
|
||||
json={'name': uname, 'unlimited_quota': True, 'remain_quota': 999999999})
|
||||
r = s.get('https://aiqianshu.com/api/token/?status_only=true', headers={'New-Api-User': str(uid)})
|
||||
for it in r.json().get('data', {}).get('items', []):
|
||||
if it['name'] == uname:
|
||||
r = s.post('https://aiqianshu.com/api/token/batch/keys', headers={'New-Api-User': str(uid)},
|
||||
json={'ids': [it['id']]})
|
||||
key = r.json()['data']['keys'][str(it['id'])]
|
||||
with open(POOL, 'a') as f:
|
||||
f.write(f'{uname}|{mail}|{key}\n')
|
||||
return True
|
||||
return False
|
||||
except:
|
||||
return False
|
||||
|
||||
while True:
|
||||
existing = set()
|
||||
if POOL.exists():
|
||||
for line in POOL.read_text().strip().split('\n'):
|
||||
if '|' in line: existing.add(line.split('|')[0])
|
||||
m = imap_lib.IMAP4_SSL('imap.gmail.com')
|
||||
m.login('[REDACTED-NAME]@gmail.com', 'kzktblsnjbmhtnrh')
|
||||
m.select('INBOX')
|
||||
found = False
|
||||
for idx in range(59, 200):
|
||||
uname = f'goth_aq{idx:04d}'
|
||||
if uname in existing: continue
|
||||
mail = f'[REDACTED-NAME]+aq{idx:04d}@gmail.com'
|
||||
s, d = m.search(None, f'(TO "{mail}")')
|
||||
if d[0]:
|
||||
s, data = m.fetch(d[0].split()[-1], '(RFC822)')
|
||||
msg = eml.message_from_bytes(data[0][1])
|
||||
body = ''
|
||||
for p in msg.walk() if msg.is_multipart() else [msg]:
|
||||
if p.get_content_type() in ('text/html', 'text/plain'):
|
||||
b = p.get_payload(decode=True)
|
||||
if b: body += b.decode(p.get_content_charset() or 'utf-8', errors='replace')
|
||||
codes_found = re.findall(r'<strong[^>]*>\s*([a-zA-Z0-9]{4,8})\s*</strong>', body)
|
||||
if codes_found:
|
||||
ok = reg_one(idx, codes_found[-1])
|
||||
if ok:
|
||||
print(f'aq{idx:04d} OK')
|
||||
found = True
|
||||
existing.add(uname)
|
||||
time.sleep(0.5)
|
||||
m.logout()
|
||||
if not found: time.sleep(5)
|
||||
@@ -0,0 +1,132 @@
|
||||
"""
|
||||
Conol.ai Proxy Handler — OpenAI-compatible API on :8080
|
||||
Proxies requests to DashScope (deepseek-v4-pro) with conol.ai model names.
|
||||
Template — customize AUTH_TOKEN and backend before use.
|
||||
"""
|
||||
import http.server
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
import requests
|
||||
|
||||
AUTH_TOKEN = "YOUR_BEARER_TOKEN_HERE"
|
||||
PORT = 8080
|
||||
DASHSCOPE_KEY = os.environ.get("HERMES_DASHSCOPE_API_KEY", "")
|
||||
DASHSCOPE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"
|
||||
|
||||
# All 28 conol.ai agent-server models + extras
|
||||
CONOL_MODELS = [
|
||||
"claude-opus-4-8", "claude-fable-5", "claude-opus-4-7",
|
||||
"claude-sonnet-5", "claude-sonnet-4-6", "claude-haiku-4-5",
|
||||
"gpt-5.5", "gpt-5.5-pro", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna",
|
||||
"deepseek-v4-pro", "deepseek-v4-flash",
|
||||
"openrouter-fusion", "glm-5.2", "glm-5.1", "hy3",
|
||||
"kimi-k3", "kimi-k2.7-code",
|
||||
"qwen3.7-plus", "qwen3.7-max",
|
||||
"minimax-m3", "step-3.7-flash",
|
||||
"gemini-3.5-flash", "gemini-3.1-pro", "gemini-3.1-flash-lite",
|
||||
"grok-4.3", "mimo-v2.5", "mimo-v2.5-pro",
|
||||
"conol-agent", "gpt-4o"
|
||||
]
|
||||
|
||||
|
||||
class ProxyHandler(http.server.BaseHTTPRequestHandler):
|
||||
"""OpenAI-compatible proxy with Bearer auth and model mapping."""
|
||||
|
||||
def _check_auth(self):
|
||||
auth = self.headers.get("Authorization", "")
|
||||
return f"Bearer {AUTH_TOKEN}" in auth
|
||||
|
||||
def _json(self, code, data):
|
||||
self.send_response(code)
|
||||
self.send_header("Content-Type", "application/json")
|
||||
self.send_header("Access-Control-Allow-Origin", "*")
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(data).encode())
|
||||
|
||||
def do_OPTIONS(self):
|
||||
self.send_response(200)
|
||||
self.send_header("Access-Control-Allow-Origin", "*")
|
||||
self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
|
||||
self.send_header("Access-Control-Allow-Headers", "Authorization, Content-Type")
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
if not self._check_auth():
|
||||
return self._json(401, {"error": "Unauthorized"})
|
||||
|
||||
if self.path == "/v1/models":
|
||||
models = {
|
||||
"object": "list",
|
||||
"data": [{"id": m, "object": "model", "owned_by": "conol"} for m in CONOL_MODELS]
|
||||
}
|
||||
self._json(200, models)
|
||||
elif self.path == "/health":
|
||||
self._json(200, {
|
||||
"status": "ok",
|
||||
"backend": "dashscope",
|
||||
"model": "deepseek-v4-pro",
|
||||
"conol_models": len(CONOL_MODELS),
|
||||
"uptime": int(time.time())
|
||||
})
|
||||
else:
|
||||
self._json(404, {"error": "Not found"})
|
||||
|
||||
def do_POST(self):
|
||||
if not self._check_auth():
|
||||
return self._json(401, {"error": "Unauthorized"})
|
||||
|
||||
if self.path == "/v1/chat/completions":
|
||||
content_length = int(self.headers.get("Content-Length", 0))
|
||||
body = self.rfile.read(content_length)
|
||||
data = json.loads(body)
|
||||
|
||||
stream = data.get("stream", False)
|
||||
model = data.get("model", "conol-agent")
|
||||
messages = data.get("messages", [])
|
||||
max_tokens = data.get("max_tokens", 4096)
|
||||
temperature = data.get("temperature", 0.7)
|
||||
|
||||
payload = {
|
||||
"model": "deepseek-v4-pro",
|
||||
"messages": messages,
|
||||
"max_tokens": min(max_tokens, 4096),
|
||||
"temperature": temperature,
|
||||
"stream": stream
|
||||
}
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {DASHSCOPE_KEY}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
try:
|
||||
r = requests.post(DASHSCOPE_URL, json=payload, headers=headers, timeout=120, stream=stream)
|
||||
|
||||
if stream:
|
||||
self.send_response(r.status_code)
|
||||
self.send_header("Content-Type", "text/event-stream")
|
||||
self.end_headers()
|
||||
for chunk in r.iter_content(chunk_size=4096):
|
||||
if chunk:
|
||||
self.wfile.write(chunk)
|
||||
self.wfile.flush()
|
||||
else:
|
||||
resp_data = r.json()
|
||||
if "choices" in resp_data:
|
||||
resp_data["model"] = model
|
||||
self._json(r.status_code, resp_data)
|
||||
except Exception as e:
|
||||
self._json(500, {"error": str(e)})
|
||||
else:
|
||||
self._json(404, {"error": "Not found"})
|
||||
|
||||
def log_message(self, format, *args):
|
||||
if "/v1/" in str(args):
|
||||
print(f"[{time.strftime('%H:%M:%S')}] {args[0]}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(f"[PROXY] :{PORT} | Auth: Bearer {AUTH_TOKEN[:15]}... | {len(CONOL_MODELS)} models")
|
||||
server = http.server.HTTPServer(("0.0.0.0", PORT), ProxyHandler)
|
||||
server.serve_forever()
|
||||
149
skills/bulk-account-registration/templates/grok_clerk_api.py
Normal file
149
skills/bulk-account-registration/templates/grok_clerk_api.py
Normal file
@@ -0,0 +1,149 @@
|
||||
"""Grok (x.ai) registration via Clerk API — no browser, no Cloudflare, no CAPTCHA.
|
||||
|
||||
Pattern: Clerk publishable key extracted from page source as `castlePk`.
|
||||
Calls Clerk Frontend API directly + t-online.de IMAP for verification codes.
|
||||
|
||||
Usage: python grok_clerk_api.py 3
|
||||
"""
|
||||
import imaplib, email, re, json, random, string, time, sys, requests
|
||||
from pathlib import Path
|
||||
|
||||
EMAILS_FILE = "C:/Users/User/Desktop/_PROJECTS/GPT-AUTOREG/emails.txt"
|
||||
OUTPUT = "C:/Users/User/projects/vellum-account-farm/accounts/grok_accounts.json"
|
||||
CLERK_PK = "pk_p8GGWvD3TmFJZRsX3BQcqAv9aFVispNz"
|
||||
CLERK_BASE = "https://clerk.x.ai/v1/client"
|
||||
|
||||
def load_emails():
|
||||
emails = []
|
||||
with open(EMAILS_FILE, "r") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#") or line.startswith("---"):
|
||||
continue
|
||||
if ":" in line:
|
||||
user, pw = line.split(":", 1)
|
||||
emails.append((user.strip(), pw.strip()))
|
||||
return emails
|
||||
|
||||
def get_code_tonline(addr, pw, timeout=120):
|
||||
"""Poll t-online.de IMAP for verification code."""
|
||||
deadline = time.time() + timeout
|
||||
while time.time() < deadline:
|
||||
try:
|
||||
mail = imaplib.IMAP4_SSL("secureimap.t-online.de", 993)
|
||||
mail.login(addr, pw)
|
||||
mail.select("inbox")
|
||||
_, msgs = mail.search(None, "UNSEEN")
|
||||
if not msgs[0]:
|
||||
_, msgs = mail.search(None, "ALL")
|
||||
for num in msgs[0].split()[-5:]:
|
||||
_, data = mail.fetch(num, "(RFC822)")
|
||||
for part in data:
|
||||
if not isinstance(part, tuple): continue
|
||||
msg = email.message_from_bytes(part[1])
|
||||
body = ""
|
||||
if msg.is_multipart():
|
||||
for p in msg.walk():
|
||||
if p.get_content_type() in ("text/plain", "text/html"):
|
||||
pl = p.get_payload(decode=True)
|
||||
if pl: body += pl.decode(errors="ignore")
|
||||
else:
|
||||
pl = msg.get_payload(decode=True)
|
||||
if pl: body = pl.decode(errors="ignore")
|
||||
codes = re.findall(r"\b(\d{6,8})\b", body)
|
||||
if codes and codes[0] != "000000":
|
||||
mail.logout()
|
||||
return codes[0]
|
||||
links = re.findall(r"https://[^\s<>]*x\.ai[^\s<>]*confirm[^\s<>]*", body)
|
||||
if links:
|
||||
mail.logout()
|
||||
return "LINK:" + links[0]
|
||||
mail.logout()
|
||||
except Exception as e:
|
||||
print(f" [IMAP] {e}")
|
||||
time.sleep(5)
|
||||
return None
|
||||
|
||||
def register_one(email_addr, email_pw):
|
||||
pw = "".join(random.choices(string.ascii_letters + string.digits + "!@#$%^&*", k=16))
|
||||
s = requests.Session()
|
||||
s.headers.update({
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/[REDACTED-IP]",
|
||||
"Origin": "https://accounts.x.ai",
|
||||
"Referer": "https://accounts.x.ai/",
|
||||
"Content-Type": "application/json",
|
||||
})
|
||||
|
||||
# Step 1: Create sign-up
|
||||
print(f" Creating sign-up for {email_addr}...")
|
||||
r = s.post(f"{CLERK_BASE}/sign_ups", json={
|
||||
"email_address": email_addr,
|
||||
"password": pw,
|
||||
}, headers={"Clerk-Publishable-Key": CLERK_PK})
|
||||
if r.status_code != 200:
|
||||
print(f" [FAIL] Sign-up failed: {r.status_code} {r.text[:200]}")
|
||||
return None
|
||||
|
||||
data = r.json()
|
||||
signup_id = data.get("response", {}).get("id") or data.get("id")
|
||||
if not signup_id:
|
||||
print(f" [FAIL] No sign-up ID in response: {r.text[:200]}")
|
||||
return None
|
||||
|
||||
# Step 2: Prepare email verification
|
||||
r = s.post(f"{CLERK_BASE}/sign_ups/{signup_id}/prepare_verification", json={
|
||||
"strategy": "email_code",
|
||||
}, headers={"Clerk-Publishable-Key": CLERK_PK})
|
||||
print(f" Prepare verification: {r.status_code}")
|
||||
|
||||
# Step 3: Wait for code via IMAP
|
||||
code = get_code_tonline(email_addr, email_pw, timeout=120)
|
||||
if not code:
|
||||
print(" [FAIL] No code received")
|
||||
return None
|
||||
|
||||
if code.startswith("LINK:"):
|
||||
link = code[5:]
|
||||
print(f" Got link: {link[:80]}...")
|
||||
r = s.get(link, allow_redirects=True)
|
||||
print(f" Link result: {r.status_code}")
|
||||
else:
|
||||
# Step 4: Verify email code
|
||||
print(f" Verifying code: {code}...")
|
||||
r = s.post(f"{CLERK_BASE}/sign_ups/{signup_id}/attempt_verification", json={
|
||||
"strategy": "email_code",
|
||||
"code": code,
|
||||
}, headers={"Clerk-Publishable-Key": CLERK_PK})
|
||||
print(f" Verify: {r.status_code} {r.text[:200]}")
|
||||
|
||||
print(f" [OK] Done: {email_addr}")
|
||||
return {"email": email_addr, "password": pw, "site": "grok", "status": "active"}
|
||||
|
||||
def main():
|
||||
count = int(sys.argv[1]) if len(sys.argv) > 1 else 3
|
||||
emails = load_emails()
|
||||
print(f"=== GROK REG (Clerk API): {count} accounts from {len(emails)} emails ===")
|
||||
ok = []
|
||||
for i in range(min(count, len(emails))):
|
||||
addr, epw = emails[i]
|
||||
print(f"\n--- [{i+1}/{count}] {addr} ---")
|
||||
try:
|
||||
r = register_one(addr, epw)
|
||||
if r: ok.append(r)
|
||||
except Exception as e:
|
||||
print(f" [ERROR] {e}")
|
||||
if i < count - 1:
|
||||
d = random.randint(5, 15)
|
||||
print(f" Cooldown {d}s...")
|
||||
time.sleep(d)
|
||||
print(f"\n=== Done: {len(ok)}/{count} ===")
|
||||
if ok:
|
||||
out = Path(OUTPUT)
|
||||
out.parent.mkdir(parents=True, exist_ok=True)
|
||||
existing = json.loads(out.read_text()) if out.exists() else []
|
||||
existing.extend(ok)
|
||||
out.write_text(json.dumps(existing, indent=2))
|
||||
print(f"Saved: {out}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
119
skills/bulk-account-registration/templates/grok_live.py
Normal file
119
skills/bulk-account-registration/templates/grok_live.py
Normal file
@@ -0,0 +1,119 @@
|
||||
"""Grok reg — live residential proxies + t-online.de IMAP + Playwright."""
|
||||
import imaplib, email, re, json, random, time, sys
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
from playwright.sync_api import sync_playwright, TimeoutError as PwTimeout
|
||||
|
||||
EMAILS_FILE = "C:/Users/User/Desktop/_PROJECTS/GPT-AUTOREG/emails.txt"
|
||||
PROXY_FILE = "C:/Users/User/tmp/bpproxy_live.json"
|
||||
OUTPUT = "accounts/grok_accounts.json"
|
||||
|
||||
def load_proxies():
|
||||
with open(PROXY_FILE) as f:
|
||||
return json.load(f)
|
||||
|
||||
def parse_proxy(url):
|
||||
p = urlparse(url)
|
||||
return {"server": f"http://{p.hostname}:{p.port}", "username": p.username, "password": p.password}
|
||||
|
||||
def load_emails():
|
||||
emails = []
|
||||
with open(EMAILS_FILE, "r") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#") or line.startswith("---"):
|
||||
continue
|
||||
if ":" in line:
|
||||
user, pw = line.split(":", 1)
|
||||
emails.append((user.strip(), pw.strip()))
|
||||
return emails
|
||||
|
||||
def get_code_tonline(addr, pw, timeout=120):
|
||||
deadline = time.time() + timeout
|
||||
while time.time() < deadline:
|
||||
try:
|
||||
mail = imaplib.IMAP4_SSL("secureimap.t-online.de", 993)
|
||||
mail.login(addr, pw)
|
||||
mail.select("inbox")
|
||||
_, msgs = mail.search(None, "UNSEEN")
|
||||
if not msgs[0]:
|
||||
_, msgs = mail.search(None, "ALL")
|
||||
for num in msgs[0].split()[-10:]:
|
||||
_, data = mail.fetch(num, "(RFC822)")
|
||||
for part in data:
|
||||
if not isinstance(part, tuple): continue
|
||||
msg = email.message_from_bytes(part[1])
|
||||
body = ""
|
||||
if msg.is_multipart():
|
||||
for p in msg.walk():
|
||||
if p.get_content_type() in ("text/plain", "text/html"):
|
||||
pl = p.get_payload(decode=True)
|
||||
if pl: body += pl.decode(errors="ignore")
|
||||
else:
|
||||
pl = msg.get_payload(decode=True)
|
||||
if pl: body = pl.decode(errors="ignore")
|
||||
codes = re.findall(r"\b(\d{6,8})\b", body)
|
||||
if codes and codes[0] != "000000":
|
||||
mail.logout()
|
||||
return codes[0]
|
||||
mail.logout()
|
||||
except Exception as e:
|
||||
print(f" [IMAP] {e}")
|
||||
time.sleep(5)
|
||||
return None
|
||||
|
||||
def register_one(email_addr, email_pw, proxy_url):
|
||||
pw = "".join(random.choices("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*", k=16))
|
||||
proxy_cfg = parse_proxy(proxy_url)
|
||||
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True, proxy=proxy_cfg)
|
||||
page = browser.new_page()
|
||||
try:
|
||||
page.goto("https://accounts.x.ai/sign-up?redirect=grok-com", wait_until="networkidle", timeout=60000)
|
||||
body = page.inner_text("body")[:500]
|
||||
if "not available in your region" in body.lower():
|
||||
return None
|
||||
page.wait_for_selector("input[type=email]", state="visible", timeout=20000)
|
||||
page.locator("input[type=email]").first.fill(email_addr)
|
||||
time.sleep(1)
|
||||
page.locator("button:has-text('Continue')").first.click()
|
||||
time.sleep(3)
|
||||
pw_input = page.locator("input[type=password]").first
|
||||
if pw_input.is_visible():
|
||||
pw_input.fill(pw)
|
||||
time.sleep(0.5)
|
||||
page.locator("button:has-text('Continue')").first.click()
|
||||
time.sleep(3)
|
||||
page.wait_for_selector("input[type=text]:not([readonly])", state="visible", timeout=20000)
|
||||
code = get_code_tonline(email_addr, email_pw, timeout=120)
|
||||
if not code: return None
|
||||
page.locator("input[type=text]:not([readonly])").first.fill(code)
|
||||
time.sleep(0.5)
|
||||
page.locator("button:has-text('Verify')").first.click()
|
||||
time.sleep(5)
|
||||
if "grok.com" in page.url:
|
||||
return {"email": email_addr, "password": pw, "site": "grok", "status": "active"}
|
||||
finally:
|
||||
browser.close()
|
||||
|
||||
def main():
|
||||
count = int(sys.argv[1]) if len(sys.argv) > 1 else 1
|
||||
proxies = load_proxies()
|
||||
emails = load_emails()
|
||||
ok = []
|
||||
for i in range(min(count, len(emails))):
|
||||
addr, epw = emails[i]
|
||||
proxy_url = proxies[i % len(proxies)]
|
||||
r = register_one(addr, epw, proxy_url)
|
||||
if r: ok.append(r)
|
||||
if i < count - 1: time.sleep(random.randint(10, 20))
|
||||
if ok:
|
||||
out = Path(OUTPUT)
|
||||
out.parent.mkdir(parents=True, exist_ok=True)
|
||||
existing = json.loads(out.read_text()) if out.exists() else []
|
||||
existing.extend(ok)
|
||||
out.write_text(json.dumps(existing, indent=2))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
186
skills/bulk-account-registration/templates/parallel_autoreg.py
Normal file
186
skills/bulk-account-registration/templates/parallel_autoreg.py
Normal file
@@ -0,0 +1,186 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Parallel.ai Auto-Registration Script
|
||||
Uses t-online.de emails (IMAP) → magic link → create org → API key
|
||||
|
||||
Usage:
|
||||
python parallel_autoreg.py --count 5
|
||||
python parallel_autoreg.py --emails emails.txt --count 10 --output keys.json
|
||||
"""
|
||||
|
||||
import imaplib, ssl, time, re, json, sys, os
|
||||
import requests
|
||||
from urllib.parse import unquote
|
||||
from datetime import datetime, timezone
|
||||
from email.utils import parsedate_to_datetime
|
||||
import email as eml
|
||||
|
||||
# Config
|
||||
IMAP_HOST = 'imap.t-online.de'
|
||||
IMAP_PORT = 993
|
||||
PARALLEL_BASE = 'https://platform.parallel.ai'
|
||||
OUTPUT_FILE = 'parallel_keys.json'
|
||||
EMAILS_FILE = 'emails.txt' # Override with --emails
|
||||
|
||||
def create_ssl_context():
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
return ctx
|
||||
|
||||
def load_emails(filepath, limit=None):
|
||||
"""Load unique email:password pairs from file, deduplicating by email"""
|
||||
seen = set()
|
||||
emails = []
|
||||
with open(filepath, 'r', encoding='utf-8', errors='replace') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
line = line.replace(';', ':')
|
||||
parts = line.split(':')
|
||||
if len(parts) >= 2:
|
||||
email_addr = parts[0].strip().strip('"').strip("'")
|
||||
password = [REDACTED]].strip().strip('"').strip("'")
|
||||
if email_addr not in seen and '@t-online.de' in email_addr:
|
||||
seen.add(email_addr)
|
||||
emails.append((email_addr, password))
|
||||
if limit and len(emails) >= limit:
|
||||
break
|
||||
return emails
|
||||
|
||||
def send_magic_link(session, email_addr):
|
||||
"""Send magic link via Parallel API"""
|
||||
csrf = session.get(f"{PARALLEL_BASE}/api/auth/csrf").json()['csrfToken']
|
||||
r = session.post(f"{PARALLEL_BASE}/api/auth/signin/email",
|
||||
data={
|
||||
"email": email_addr,
|
||||
"csrfToken": csrf,
|
||||
"callbackUrl": f"{PARALLEL_BASE}/post-auth-sign-up"
|
||||
},
|
||||
allow_redirects=False)
|
||||
return r.status_code == 302
|
||||
|
||||
def poll_imap_for_link(email_addr, password, sent_time, max_attempts=12):
|
||||
"""Poll IMAP inbox for magic link, filtering by email date"""
|
||||
ctx = create_ssl_context()
|
||||
mail = imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT, ssl_context=ctx, timeout=10)
|
||||
mail.login(email_addr, password)
|
||||
|
||||
for attempt in range(max_attempts):
|
||||
time.sleep(2.5)
|
||||
mail.noop()
|
||||
mail.select('INBOX')
|
||||
status, messages = mail.search(None, 'ALL')
|
||||
msg_ids = messages[0].split() if messages[0] else []
|
||||
|
||||
for msg_id in reversed(msg_ids[-5:]):
|
||||
status, data = mail.fetch(msg_id, '(RFC822)')
|
||||
raw = data[0][1]
|
||||
msg = eml.message_from_bytes(raw)
|
||||
|
||||
date_str = msg.get('Date', '')
|
||||
try:
|
||||
msg_date = parsedate_to_datetime(date_str)
|
||||
except:
|
||||
msg_date = None
|
||||
|
||||
if b'Parallel' in raw and msg_date and msg_date > sent_time:
|
||||
for part in msg.walk():
|
||||
if part.get_content_type() == 'text/plain':
|
||||
body = part.get_payload(decode=True).decode('utf-8', errors='replace')
|
||||
links = re.findall(r'https://platform\.parallel\.ai/redirect\?to=[^\s"<>]+', body)
|
||||
if links:
|
||||
to_match = re.search(r'to=([^&]+)', links[0])
|
||||
callback_url = unquote(to_match.group(1))
|
||||
mail.logout()
|
||||
return callback_url
|
||||
|
||||
mail.logout()
|
||||
return None
|
||||
|
||||
def create_org_and_get_key(session, org_name="Research"):
|
||||
"""Create org and get API key"""
|
||||
r = session.post(f"{PARALLEL_BASE}/api/rpc/onboard/create-org-with-visibility",
|
||||
json={"orgName": org_name, "visibility": "private"})
|
||||
if r.status_code != 200:
|
||||
return None
|
||||
|
||||
r = session.post(f"{PARALLEL_BASE}/api/rpc/auth/get-my-api-key-and-session-details", json={})
|
||||
if r.status_code != 200:
|
||||
return None
|
||||
|
||||
data = r.json()
|
||||
api_key = [REDACTED]'data', {}).get('apiKey', '')
|
||||
org_id = data.get('data', {}).get('forOrgId', '')
|
||||
|
||||
return {
|
||||
'api_key': api_key,
|
||||
'org_id': org_id,
|
||||
'org_name': org_name,
|
||||
'base_url': data.get('data', {}).get('baseUrl', 'https://api.parallel.ai/'),
|
||||
}
|
||||
|
||||
def register_one(email_addr, password, org_name="Research"):
|
||||
"""Register one account"""
|
||||
session = requests.Session()
|
||||
|
||||
if not send_magic_link(session, email_addr):
|
||||
return {'error': 'Failed to send magic link'}
|
||||
|
||||
sent_time = datetime.now(timezone.utc)
|
||||
callback_url = poll_imap_for_link(email_addr, password, sent_time)
|
||||
if not callback_url:
|
||||
return {'error': 'No magic link received'}
|
||||
|
||||
session.get(callback_url, allow_redirects=True)
|
||||
|
||||
s = session.get(f"{PARALLEL_BASE}/api/auth/session").json()
|
||||
if not s or 'user' not in s:
|
||||
return {'error': 'Session not established'}
|
||||
|
||||
result = create_org_and_get_key(session, org_name)
|
||||
if not result:
|
||||
return {'error': 'Failed to create org/get key'}
|
||||
|
||||
result['email'] = email_addr
|
||||
result['session_user'] = s['user']['email']
|
||||
return result
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description='Parallel.ai Auto-Registration')
|
||||
parser.add_argument('--count', type=int, default=1)
|
||||
parser.add_argument('--emails', type=str, default=EMAILS_FILE)
|
||||
parser.add_argument('--output', type=str, default=OUTPUT_FILE)
|
||||
parser.add_argument('--org-name', type=str, default='Research')
|
||||
args = parser.parse_args()
|
||||
|
||||
emails = load_emails(args.emails, limit=args.count)
|
||||
print(f"Loaded {len(emails)} unique emails from {args.emails}")
|
||||
|
||||
results = []
|
||||
for i, (email_addr, password) in enumerate(emails):
|
||||
print(f"\n[{i+1}/{len(emails)}] {email_addr}")
|
||||
try:
|
||||
result = register_one(email_addr, password, args.org_name)
|
||||
if 'api_key' in result:
|
||||
print(f" ✅ API Key: {result['api_key'][:30]}...")
|
||||
results.append(result)
|
||||
else:
|
||||
print(f" ❌ {result.get('error', 'Unknown error')}")
|
||||
except Exception as e:
|
||||
print(f" ❌ Exception: {e}")
|
||||
|
||||
with open(args.output, 'w') as f:
|
||||
json.dump(results, f, indent=2)
|
||||
|
||||
if i < len(emails) - 1:
|
||||
time.sleep(3)
|
||||
|
||||
print(f"\n=== Done: {len(results)}/{len(emails)} keys → {args.output} ===")
|
||||
for r in results:
|
||||
print(f" {r['email']}: {r['api_key'][:40]}...")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
124
skills/bulk-account-registration/templates/parallel_proxy.py
Normal file
124
skills/bulk-account-registration/templates/parallel_proxy.py
Normal file
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Parallel API Key Rotator Proxy
|
||||
Rotates Parallel API keys for search/extract/task/monitor endpoints.
|
||||
Retries on 402 (no credit) and 429 (rate limit) with next key.
|
||||
|
||||
Usage:
|
||||
python parallel_proxy.py --port 8765 --keys parallel_api_keys.txt
|
||||
"""
|
||||
|
||||
import json, os, sys, time, threading
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
from urllib.parse import urlparse
|
||||
import requests
|
||||
|
||||
PARALLEL_BASE = "https://api.parallel.ai"
|
||||
|
||||
class KeyPool:
|
||||
def __init__(self, keys_file):
|
||||
self.keys = []
|
||||
self.lock = threading.Lock()
|
||||
self.stats = {}
|
||||
self.load_keys(keys_file)
|
||||
|
||||
def load_keys(self, keys_file):
|
||||
with open(keys_file, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
key = line.split('#')[0].strip()
|
||||
if key:
|
||||
self.keys.append(key)
|
||||
self.stats[key] = {'uses': 0, 'fails': 0, 'last_used': 0}
|
||||
print(f"Loaded {len(self.keys)} keys")
|
||||
|
||||
def get_key(self):
|
||||
with self.lock:
|
||||
if not self.keys:
|
||||
return None
|
||||
key = min(self.keys, key=lambda k: self.stats[k]['uses'])
|
||||
self.stats[key]['uses'] += 1
|
||||
self.stats[key]['last_used'] = time.time()
|
||||
return key
|
||||
|
||||
def mark_fail(self, key):
|
||||
with self.lock:
|
||||
if key in self.stats:
|
||||
self.stats[key]['fails'] += 1
|
||||
|
||||
def get_stats(self):
|
||||
with self.lock:
|
||||
total_uses = sum(s['uses'] for s in self.stats.values())
|
||||
total_fails = sum(s['fails'] for s in self.stats.values())
|
||||
return {
|
||||
'total_keys': len(self.keys),
|
||||
'total_uses': total_uses,
|
||||
'total_fails': total_fails,
|
||||
}
|
||||
|
||||
class ParallelAPI:
|
||||
def __init__(self, key_pool):
|
||||
self.pool = key_pool
|
||||
self.session = requests.Session()
|
||||
|
||||
def _call(self, endpoint, data, method='POST', retry=3):
|
||||
for attempt in range(retry):
|
||||
key = self.pool.get_key()
|
||||
if not key:
|
||||
return None, 503, {'error': 'No keys available'}
|
||||
|
||||
headers = {
|
||||
'Authorization': f'Bearer {key}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
url = f"{PARALLEL_BASE}{endpoint}"
|
||||
|
||||
try:
|
||||
if method == 'POST':
|
||||
r = self.session.post(url, headers=headers, json=data, timeout=30)
|
||||
else:
|
||||
r = self.session.get(url, headers=headers, params=data, timeout=30)
|
||||
|
||||
# 402/429 → try next key
|
||||
if r.status_code in (402, 429):
|
||||
self.pool.mark_fail(key)
|
||||
continue
|
||||
|
||||
# 200 with credit error body → try next key
|
||||
if r.status_code == 200:
|
||||
try:
|
||||
body = r.json()
|
||||
if body.get('type') == 'error' and 'credit' in body.get('error', {}).get('message', '').lower():
|
||||
self.pool.mark_fail(key)
|
||||
continue
|
||||
except:
|
||||
pass
|
||||
|
||||
if r.status_code >= 400:
|
||||
self.pool.mark_fail(key)
|
||||
return r.json() if r.text else {}, r.status_code, r.text
|
||||
|
||||
return r.json(), r.status_code, None
|
||||
except Exception as e:
|
||||
self.pool.mark_fail(key)
|
||||
continue
|
||||
|
||||
return None, 503, {'error': 'All keys exhausted'}
|
||||
|
||||
def search(self, queries, **kwargs):
|
||||
data = {"search_queries": queries if isinstance(queries, list) else [queries]}
|
||||
data.update(kwargs)
|
||||
return self._call('/v1/search', data)
|
||||
|
||||
def extract(self, urls, **kwargs):
|
||||
if isinstance(urls, str):
|
||||
urls = [urls]
|
||||
return self._call('/v1/extract', {"urls": urls, **kwargs})
|
||||
|
||||
def task(self, query, **kwargs):
|
||||
return self._call('/v1/task', {"query": query, **kwargs})
|
||||
|
||||
def monitor(self, url, **kwargs):
|
||||
return self._call('/v1/monitor', {"url": url, **kwargs})
|
||||
110
skills/bulk-account-registration/templates/proxy_forwarder.py
Normal file
110
skills/bulk-account-registration/templates/proxy_forwarder.py
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Локальный HTTP-форвардер для прокси с аутентификацией.
|
||||
Нужен когда инструмент (DrissionPage, etc.) не поддерживает user:pass в прокси.
|
||||
Принимает CONNECT/GET на 127.0.0.1:LOCAL_PORT, добавляет Proxy-Authorization: Basic,
|
||||
форвардит на UPSTREAM.
|
||||
|
||||
Использование:
|
||||
1. Заменить UPSTREAM_HOST, UPSTREAM_PORT, PROXY_USER, PROXY_PASS
|
||||
2. Запустить: python proxy_forwarder.py
|
||||
3. В конфиге браузера указать: http://127.0.0.1:9128
|
||||
"""
|
||||
|
||||
import http.server
|
||||
import urllib.request
|
||||
import base64
|
||||
import socket
|
||||
import select
|
||||
|
||||
UPSTREAM_HOST = 'residential-x.bpproxy.at'
|
||||
UPSTREAM_PORT = 1000
|
||||
PROXY_USER = b'bpuser-XXX'
|
||||
PROXY_PASS = b'PASS_hardsession-YYY'
|
||||
LOCAL_PORT = 9128
|
||||
|
||||
UPSTREAM = f'{UPSTREAM_HOST}:{UPSTREAM_PORT}'
|
||||
AUTH = base64.b64encode(PROXY_USER + b':' + PROXY_PASS).decode()
|
||||
|
||||
|
||||
class Proxy(http.server.BaseHTTPRequestHandler):
|
||||
timeout = 30
|
||||
|
||||
def do_GET(self):
|
||||
self._forward('GET')
|
||||
|
||||
def do_POST(self):
|
||||
self._forward('POST')
|
||||
|
||||
def do_HEAD(self):
|
||||
self._forward('HEAD')
|
||||
|
||||
def do_PUT(self):
|
||||
self._forward('PUT')
|
||||
|
||||
def _forward(self, method):
|
||||
try:
|
||||
url = self.path
|
||||
req = urllib.request.Request(url, method=method)
|
||||
req.add_header('Proxy-Authorization', f'Basic {AUTH}')
|
||||
for h, v in self.headers.items():
|
||||
if h.lower() not in ('host', 'proxy-connection', 'proxy-authorization'):
|
||||
req.add_header(h, v)
|
||||
if method in ('POST', 'PUT'):
|
||||
body = self.rfile.read(int(self.headers.get('Content-Length', 0)))
|
||||
req.data = body
|
||||
req.set_proxy(UPSTREAM, 'http')
|
||||
resp = urllib.request.urlopen(req, timeout=30)
|
||||
self.send_response(resp.status)
|
||||
for h, v in resp.getheaders():
|
||||
self.send_header(h, v)
|
||||
self.end_headers()
|
||||
self.wfile.write(resp.read())
|
||||
except Exception as e:
|
||||
self.send_error(502, str(e))
|
||||
|
||||
def do_CONNECT(self):
|
||||
host, port = self.path.split(':')
|
||||
port = int(port)
|
||||
try:
|
||||
remote = socket.create_connection(
|
||||
(UPSTREAM_HOST, UPSTREAM_PORT), timeout=10
|
||||
)
|
||||
connect_req = (
|
||||
f'CONNECT {host}:{port} HTTP/1.1\r\n'
|
||||
f'Host: {host}:{port}\r\n'
|
||||
f'Proxy-Authorization: Basic {AUTH}\r\n\r\n'
|
||||
)
|
||||
remote.send(connect_req.encode())
|
||||
resp = b''
|
||||
while b'\r\n\r\n' not in resp:
|
||||
resp += remote.recv(4096)
|
||||
if b'200' not in resp.split(b'\r\n')[0]:
|
||||
self.send_error(502, 'CONNECT failed')
|
||||
remote.close()
|
||||
return
|
||||
self.send_response(200, 'Connection Established')
|
||||
self.end_headers()
|
||||
self.connection.settimeout(30)
|
||||
remote.settimeout(30)
|
||||
socks = [self.connection, remote]
|
||||
while True:
|
||||
r, _, _ = select.select(socks, [], [], 30)
|
||||
if not r:
|
||||
break
|
||||
for s in r:
|
||||
try:
|
||||
d = s.recv(8192)
|
||||
if not d:
|
||||
return
|
||||
dst = remote if s is self.connection else self.connection
|
||||
dst.sendall(d)
|
||||
except Exception:
|
||||
return
|
||||
except Exception as e:
|
||||
self.send_error(502, str(e))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(f'[*] Proxy Forwarder: 127.0.0.1:{LOCAL_PORT} -> {UPSTREAM}', flush=True)
|
||||
httpd = http.server.HTTPServer(('127.0.0.1', LOCAL_PORT), Proxy)
|
||||
httpd.serve_forever()
|
||||
Reference in New Issue
Block a user