autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
101
skills/telegram-mass-join/references/join-executor-patterns.md
Normal file
101
skills/telegram-mass-join/references/join-executor-patterns.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Join Executor Patterns
|
||||
|
||||
## Script: `join_assigned.py`
|
||||
|
||||
### Key Constants
|
||||
```python
|
||||
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
|
||||
```python
|
||||
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:
|
||||
```python
|
||||
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:
|
||||
```python
|
||||
ss = string_sessions.get(phone) or string_sessions.get(name)
|
||||
```
|
||||
|
||||
### Progress Persistence
|
||||
```python
|
||||
# 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
|
||||
Reference in New Issue
Block a user