Skip to content

Commit 8723f01

Browse files
author
clawdbot
committed
docs: update README and AGENTS.md for multi-group support
1 parent 3a38890 commit 8723f01

2 files changed

Lines changed: 78 additions & 15 deletions

File tree

AGENTS.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Overview
44

5-
Indonesian Telegram bot for group profile enforcement (photo + username), captcha verification, and anti-spam protection. Built with python-telegram-bot v20+, SQLModel, Pydantic, and Logfire.
5+
Indonesian Telegram bot for multi-group profile enforcement (photo + username), captcha verification, and anti-spam protection. Built with python-telegram-bot v20+, SQLModel, Pydantic, and Logfire.
66

77
## Commands
88

@@ -40,6 +40,7 @@ PythonID/
4040
│ ├── main.py # Entry point + handler registration (priority groups!)
4141
│ ├── config.py # Pydantic settings (get_settings() cached)
4242
│ ├── constants.py # Indonesian templates + URL whitelists (528 lines)
43+
│ ├── group_config.py # Multi-group config (GroupConfig, GroupRegistry)
4344
│ ├── handlers/ # Telegram update handlers
4445
│ │ ├── captcha.py # New member verification flow
4546
│ │ ├── verify.py # Admin /verify, /unverify commands
@@ -57,7 +58,7 @@ PythonID/
5758
│ └── database/
5859
│ ├── models.py # SQLModel schemas (4 tables)
5960
│ └── service.py # DatabaseService singleton (645 lines)
60-
├── tests/ # pytest-asyncio (18 files, 100% coverage)
61+
├── tests/ # pytest-asyncio (18 files, 99% coverage)
6162
└── data/bot.db # SQLite (auto-created, WAL mode)
6263
```
6364

@@ -71,17 +72,19 @@ PythonID/
7172
| Change config | `config.py` | Pydantic BaseSettings with env vars |
7273
| Add URL whitelist | `constants.py``WHITELISTED_URL_DOMAINS` | Suffix-based matching |
7374
| Add Telegram whitelist | `constants.py``WHITELISTED_TELEGRAM_PATHS` | Lowercase, exact path match |
75+
| Multi-group config | `group_config.py` | GroupConfig model, GroupRegistry, groups.json loading |
7476

7577
## Code Map (Key Files)
7678

7779
| File | Lines | Role |
7880
|------|-------|------|
79-
| `database/service.py` | 645 | **Complexity hotspot** - handles warnings, captcha, probation state |
80-
| `constants.py` | 528 | Templates + massive whitelists (Indonesian tech community) |
81-
| `handlers/captcha.py` | 365 | New member join → restrict → verify → unrestrict lifecycle |
82-
| `handlers/verify.py` | 344 | Admin verification commands + inline button callbacks |
83-
| `handlers/anti_spam.py` | 327 | Probation enforcement with URL whitelisting |
84-
| `main.py` | 293 | Entry point, logging, handler registration, JobQueue setup |
81+
| `group_config.py` | 250 | Multi-group config, registry, JSON loading, .env fallback |
82+
| `database/service.py` | 671 | **Complexity hotspot** - handles warnings, captcha, probation state |
83+
| `constants.py` | 530 | Templates + massive whitelists (Indonesian tech community) |
84+
| `handlers/captcha.py` | 375 | New member join → restrict → verify → unrestrict lifecycle |
85+
| `handlers/verify.py` | 358 | Admin verification commands + inline button callbacks |
86+
| `handlers/anti_spam.py` | 326 | Probation enforcement with URL whitelisting |
87+
| `main.py` | 315 | Entry point, logging, handler registration, JobQueue setup |
8588

8689
## Architecture Patterns
8790

@@ -98,6 +101,13 @@ group=1 # message_handler: Runs LAST, profile compliance check
98101
- `get_database()` — DatabaseService, lazy init
99102
- `BotInfoCache` — Class-level cache for bot username/ID
100103

104+
### Multi-Group Support
105+
- `GroupConfig` — Pydantic model for per-group settings (warning thresholds, captcha, probation)
106+
- `GroupRegistry` — O(1) lookup by group_id, manages all monitored groups
107+
- `groups.json` — Per-group config file; falls back to `.env` for single-group mode
108+
- `get_group_config_for_update()` — Helper to resolve config for incoming Telegram updates
109+
- Exception-isolated loops — Per-group API calls wrapped in try/except to prevent cross-group failures
110+
101111
### State Machine (Progressive Restriction)
102112
```
103113
1st violation → Warning with threshold info
@@ -179,3 +189,7 @@ if user.id not in admin_ids:
179189
- JobQueue auto-restriction job runs every 5 minutes (first run after 5 min delay)
180190
- Bot uses `allowed_updates=["message", "callback_query", "chat_member"]`
181191
- Captcha uses both `ChatMemberHandler` (for "Hide Join" groups) and `MessageHandler` fallback
192+
- Multi-group: handlers use `get_group_config_for_update()` instead of `settings.group_id`
193+
- Captcha callback data encodes group_id: `captcha_verify_{group_id}_{user_id}` to avoid ambiguity
194+
- Scheduler iterates all groups with per-group exception isolation
195+
- DM handler scans all groups in registry for user membership and unrestriction

README.md

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ A comprehensive Telegram bot for managing group members with profile verificatio
55
## Features
66

77
### Core Monitoring
8-
- Monitors all messages in a configured group
8+
- Monitors all messages in one or more configured groups
9+
- **Multi-group support**: Manage multiple groups from a single bot instance with isolated per-group settings via `groups.json`
910
- Checks if users have a public profile picture
1011
- Checks if users have a username set
1112
- Sends warnings to a dedicated topic (thread) for non-compliant users
@@ -101,6 +102,49 @@ WARNING_TIME_THRESHOLD_MINUTES=180
101102
RULES_LINK=https://t.me/yourgroup/rules
102103
```
103104

105+
### 6. Multi-Group Configuration (Optional)
106+
107+
To manage multiple groups from a single bot instance, use a `groups.json` configuration file:
108+
109+
```bash
110+
cp groups.json.example groups.json
111+
```
112+
113+
Add `GROUPS_CONFIG_PATH=groups.json` to your `.env` file, then edit `groups.json`:
114+
115+
```json
116+
[
117+
{
118+
"group_id": -1001234567890,
119+
"warning_topic_id": 123,
120+
"restrict_failed_users": false,
121+
"warning_threshold": 3,
122+
"warning_time_threshold_minutes": 180,
123+
"captcha_enabled": false,
124+
"captcha_timeout_seconds": 120,
125+
"new_user_probation_hours": 72,
126+
"new_user_violation_threshold": 3,
127+
"rules_link": "https://t.me/pythonID/290029/321799"
128+
},
129+
{
130+
"group_id": -1009876543210,
131+
"warning_topic_id": 456,
132+
"restrict_failed_users": true,
133+
"warning_threshold": 5,
134+
"warning_time_threshold_minutes": 60,
135+
"captcha_enabled": true,
136+
"captcha_timeout_seconds": 180,
137+
"new_user_probation_hours": 168,
138+
"new_user_violation_threshold": 2,
139+
"rules_link": "https://t.me/mygroup/rules"
140+
}
141+
]
142+
```
143+
144+
When `groups.json` is present, per-group settings override the `.env` defaults. Each group can have its own warning thresholds, captcha settings, probation rules, and rules link.
145+
146+
**Backward compatibility**: If no `groups.json` is configured (i.e., `GROUPS_CONFIG_PATH` is not set), the bot falls back to single-group mode using `GROUP_ID`, `WARNING_TOPIC_ID`, and other settings from `.env`.
147+
104148
## Installation
105149

106150
```bash
@@ -150,12 +194,12 @@ uv run pytest -v
150194
### Test Coverage
151195

152196
The project maintains comprehensive test coverage:
153-
- **Coverage**: 99% (1,216 statements)
154-
- **Tests**: 404 total
155-
- **Pass Rate**: 100% (404/404 passed)
197+
- **Coverage**: 99% (1,396 statements)
198+
- **Tests**: 442 total
199+
- **Pass Rate**: 100% (442/442 passed)
156200
- **All modules**: 100% coverage including JobQueue scheduler integration, captcha verification, and anti-spam enforcement
157-
- Services: `bot_info.py` (100%), `scheduler.py` (100%), `user_checker.py` (100%), `telegram_utils.py` (100%), `captcha_recovery.py` (100%)
158-
- Handlers: `anti_spam.py` (100%), `captcha.py` (100%), `check.py` (100%), `dm.py` (100%), `message.py` (100%), `topic_guard.py` (100%), `verify.py` (100%)
201+
- Services: `bot_info.py` (100%), `group_config.py` (97%), `scheduler.py` (100%), `user_checker.py` (100%), `telegram_utils.py` (100%), `captcha_recovery.py` (100%)
202+
- Handlers: `anti_spam.py` (100%), `captcha.py` (100%), `check.py` (98%), `dm.py` (100%), `message.py` (100%), `topic_guard.py` (100%), `verify.py` (100%)
159203
- Database: `service.py` (100%), `models.py` (100%)
160204
- Config: `config.py` (100%)
161205
- Constants: `constants.py` (100%)
@@ -192,13 +236,16 @@ PythonID/
192236
│ ├── test_scheduler.py # JobQueue scheduler tests
193237
│ ├── test_telegram_utils.py
194238
│ ├── test_topic_guard.py
239+
│ ├── test_group_config.py
195240
│ ├── test_user_checker.py
196-
│ └── test_verify_handler.py
241+
│ ├── test_verify_handler.py
242+
│ └── test_whitelist.py
197243
└── src/
198244
└── bot/
199245
├── main.py # Entry point with JobQueue integration
200246
├── config.py # Pydantic settings
201247
├── constants.py # Shared constants
248+
├── group_config.py # Multi-group configuration (GroupConfig, GroupRegistry)
202249
├── handlers/
203250
│ ├── anti_spam.py # Anti-spam handler for probation users
204251
│ ├── captcha.py # Captcha verification handler
@@ -412,6 +459,7 @@ The bot is organized into clear modules for maintainability:
412459
- `service.py`: Database operations with SQLite
413460
- `models.py`: Data models using SQLModel (UserWarning, PhotoVerificationWhitelist, PendingCaptchaValidation, NewUserProbation)
414461
- **config.py**: Environment configuration using Pydantic
462+
- **group_config.py**: Multi-group configuration management (GroupConfig model, GroupRegistry for O(1) lookup, groups.json loading with .env fallback)
415463
- **constants.py**: Centralized message templates and utilities for consistent formatting across handlers
416464

417465
### Group Message Monitoring
@@ -484,6 +532,7 @@ When a restricted user DMs the bot (or sends `/start`):
484532
| `LOGFIRE_ENABLED` | Enable Logfire logging integration | `true` |
485533
| `LOGFIRE_TOKEN` | Logfire API token (optional) | None |
486534
| `LOG_LEVEL` | Logging level (DEBUG/INFO/WARNING/ERROR) | `INFO` |
535+
| `GROUPS_CONFIG_PATH` | Path to `groups.json` for multi-group support | None (single-group mode from `.env`) |
487536

488537
### Restriction Modes
489538

0 commit comments

Comments
 (0)