3.1 KiB
3.1 KiB
Join Executor Patterns
Script: join_assigned.py
Key Constants
BATCH_SIZE = 5 # Accounts processed in parallel
BATCH_PAUSE = 15 # Seconds between batches (was 30, lowered for speed)
ACCOUNT_TIMEOUT = 120 # Hard timeout per account (was 60, 50×2.5s avg = 125s)
Error Classification
BAD_REASONS = {
'CHANNEL_PRIVATE', 'CHAT_WRITE_FORBIDDEN', 'CHANNEL_INVALID',
'USER_BANNED_IN_CHANNEL', 'INVITE_HASH_EXPIRED', 'INVITE_HASH_INVALID',
'CHAT_ID_INVALID', 'USERNAME_NOT_OCCUPIED', 'USERNAME_INVALID',
'CHAT_FORBIDDEN', 'CHAT_RESTRICTED',
}
Join Result Types
| Result | Meaning |
|---|---|
joined |
Successfully joined |
already |
Already a member (UserAlreadyParticipantError) |
flood_N |
Rate limited for N seconds (auto-waits) |
bad_* |
Chat is private/deleted/invalid |
err_* |
Unknown error (first 50 chars logged) |
err_timeout |
Individual chat operation timed out |
Account Status Types
| Status | Meaning |
|---|---|
ok |
All chats processed |
hard_timeout |
Account took >60s total |
no_stringsession |
No StringSession found |
timeout_connect |
connect() timed out |
crash: ... |
Exception during processing |
Async Flow
main() → for each batch of 5 accounts:
→ asyncio.gather(process_with_timeout(acc) for acc in batch)
→ process_with_timeout → asyncio.wait_for(process_account, timeout=60)
→ process_account:
→ client.connect() [10s timeout]
→ client.get_me() [5s timeout]
→ for each chat:
→ get_entity(username) [10s timeout]
→ JoinChannelRequest(entity) [10s timeout]
→ sleep(0.5-1.5s)
→ client.disconnect()
Account Lookup
Accounts are identified by index in the sorted OK list:
ok_accounts.sort(key=lambda a: a.get("phone", ""))
# ...
global_idx = i + idx
acc_key = f"account_{global_idx + 1}"
acc_chats = assignments.get(acc_key, [])
StringSession Lookup
Tries phone first, then name:
ss = string_sessions.get(phone) or string_sessions.get(name)
Progress Persistence
# Saved every batch:
{
"batch_num": 42,
"total_joined": 352,
"accounts_processed": 210
}
# Joined chats saved every 10 batches:
{
"baraholllkamariupol": {
"username": "baraholllkamariupol",
"id": "1856532726",
"title": "Барахолка...",
"participants": 21513,
"joined_by": "12894827641"
}
}
Performance Observations
- 50 chats/account × 120s timeout: ~28-36 joins per 58-account process
- ~25% of accounts succeed (ok), ~40% hard_timeout, ~20% timeout_connect, ~15% no_stringsession
- 50 chats × 2.5s avg = 125s → 120s is tight. Some accounts with slow connections hit hard_timeout
- timeout_connect accounts have network/DC issues — not recoverable per-run
- 3 parallel processes × 58 accounts: ~81 new joins, ~17 min runtime
- 0 flood, 0 bans — safe for mass operations
- BATCH_PAUSE=15s (was 30s) — sufficient to avoid rate limits, 2x faster
- Together with 3-way parallel: ~6x speedup vs original single 30s-pause process