Skip to content

Commit f537935

Browse files
committed
docs: update README with comprehensive feature list and workflow diagram
- Enhanced feature list with organized sections: Core Monitoring, Restriction & Unrestriction, New Member Protection, Admin Tools - Added missing config variables: CAPTCHA_ENABLED, CAPTCHA_TIMEOUT_SECONDS, NEW_USER_PROBATION_HOURS, NEW_USER_VIOLATION_THRESHOLD, LOGFIRE_ENABLED, LOGFIRE_TOKEN, LOG_LEVEL - Updated architecture section with all current handlers and services - Completely redesigned Mermaid workflow diagram to include: * Captcha verification flow with timeout handling * Anti-spam enforcement for new users on probation * URL whitelisting and violation tracking * Admin verification commands (/verify, /unverify) * Forwarded message handling for inline verify/unverify buttons * Callback handlers for button interactions * Captcha recovery on bot restart - Reflects current state from latest commits including anti-spam, captcha, and verification features
1 parent 868dba0 commit f537935

1 file changed

Lines changed: 108 additions & 36 deletions

File tree

README.md

Lines changed: 108 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
11
# PythonID Group Management Bot
22

3-
A Telegram bot that monitors group messages and warns users who don't have a public profile picture or username set.
3+
A comprehensive Telegram bot for managing group members with profile verification, captcha challenges, and anti-spam protection.
44

55
## Features
66

7-
- Monitors all text messages in a configured group
7+
### Core Monitoring
8+
- Monitors all messages in a configured group
89
- Checks if users have a public profile picture
910
- Checks if users have a username set
1011
- Sends warnings to a dedicated topic (thread) for non-compliant users
1112
- **Warning topic protection**: Only admins and the bot can post in the warning topic
12-
- **DM unrestriction flow**: Restricted users can DM the bot to get unrestricted after completing their profile
13+
14+
### Restriction & Unrestriction
1315
- **Progressive restriction**: Optional mode to restrict users after multiple warnings (message-based)
1416
- **Time-based auto-restriction**: Automatically restricts users after X hours from first warning
1517
- **Scheduled job**: Background scheduler checks and enforces time-based restrictions every 5 minutes
18+
- **DM unrestriction flow**: Restricted users can DM the bot to get unrestricted after completing their profile
19+
20+
### New Member Protection
21+
- **Captcha verification**: New members must verify they're human before joining (optional)
22+
- **Captcha timeout recovery**: Automatically recovers pending verifications after bot restart
23+
- **New user probation**: New members restricted from sending links/forwarded messages for 3 days (configurable)
24+
- **Anti-spam enforcement**: Tracks violations and restricts spammers after threshold
25+
26+
### Admin Tools
27+
- **/verify command**: Whitelist users with hidden profile pictures (DM only)
28+
- **/unverify command**: Remove users from verification whitelist (DM only)
29+
- **Inline verification**: Forward messages to bot for quick verify/unverify buttons
30+
- **Automatic clearance**: Sends notification when verified users' warnings are cleared
1631

1732
## Requirements
1833

@@ -204,61 +219,89 @@ PythonID/
204219

205220
## Bot Workflow
206221

207-
The following diagram illustrates the complete bot workflow including message handling, restriction logic, DM unrestriction, background scheduler jobs, and captcha verification:
222+
The following diagram illustrates the complete bot workflow including captcha verification, anti-spam protection, profile monitoring, restriction logic, DM unrestriction, admin verification, and background scheduler jobs:
208223

209224
```mermaid
210225
flowchart TD
211226
Start([Bot Starts]) --> Init[Initialize Database & Config]
212227
Init --> FetchAdmins[Fetch Group Admin IDs]
213-
FetchAdmins --> StartJobs[Start JobQueue Scheduler<br/>5-minute interval]
228+
FetchAdmins --> RecoverCaptcha{Captcha<br/>Enabled?}
229+
RecoverCaptcha -->|Yes| RecoverPending[Recover Pending Captchas]
230+
RecoverCaptcha -->|No| StartJobs
231+
RecoverPending --> StartJobs[Start JobQueue Scheduler<br/>5-minute interval]
214232
StartJobs --> Poll[Poll for Updates]
215233
216234
Poll --> UpdateType{Update Type?}
217235
218236
%% New Member Flow
219-
UpdateType -->|New Member| CheckCaptcha{Captcha<br/>Enabled?}
220-
CheckCaptcha -->|Yes| SendCaptcha[Send Captcha to User]
221-
SendCaptcha --> WaitCaptcha[Wait for Answer]
222-
WaitCaptcha --> CaptchaAnswer{Correct<br/>Answer?}
223-
CaptchaAnswer -->|Yes| UnrestrictMember[Unrestrict Member]
224-
CaptchaAnswer -->|No| KickMember[Kick Member]
225-
CaptchaAnswer -->|Timeout| KickMember
226-
CheckCaptcha -->|No| Continue[Continue Monitoring]
237+
UpdateType -->|New Member| CheckCaptchaEnabled{Captcha<br/>Enabled?}
238+
CheckCaptchaEnabled -->|No| StartProbation[Start Probation Only]
239+
CheckCaptchaEnabled -->|Yes| RestrictAndChallenge[Restrict & Send Captcha]
240+
RestrictAndChallenge --> StorePending[(Store Pending Validation)]
241+
StorePending --> ScheduleTimeout[Schedule Timeout Job]
242+
ScheduleTimeout --> WaitCaptcha[Wait for Verification]
243+
244+
WaitCaptcha --> CaptchaAnswer{User<br/>Action?}
245+
CaptchaAnswer -->|Correct Button| CancelTimeout[Cancel Timeout Job]
246+
CancelTimeout --> UnrestrictMember[Unrestrict Member]
247+
UnrestrictMember --> StartProbationAfter[Start Probation]
248+
CaptchaAnswer -->|Wrong User| ShowError[Show Error Message]
249+
CaptchaAnswer -->|Timeout| KickMember[Keep Restricted]
250+
KickMember --> UpdateMessage[Update Challenge Message]
227251
228-
%% Group Message Flow
229-
UpdateType -->|Group Message| TopicGuard{In Warning<br/>Topic?}
252+
%% Anti-Spam Flow (New User Probation)
253+
UpdateType -->|Group Message| CheckProbation{User On<br/>Probation?}
254+
CheckProbation -->|No| CheckBot
255+
CheckProbation -->|Yes| CheckExpired{Probation<br/>Expired?}
256+
CheckExpired -->|Yes| ClearProbation[(Clear Probation)]
257+
CheckExpired -->|No| CheckViolation{Forward/Link/<br/>External Reply?}
258+
259+
CheckViolation -->|No| End1([Continue])
260+
CheckViolation -->|Yes| CheckWhitelisted{URL<br/>Whitelisted?}
261+
CheckWhitelisted -->|Yes| End1
262+
CheckWhitelisted -->|No| DeleteSpam[Delete Message]
263+
DeleteSpam --> IncrementViolation[(Increment Violation)]
264+
IncrementViolation --> ViolationCount{Violation<br/>Count?}
265+
266+
ViolationCount -->|First| SendSpamWarning[Send Probation Warning]
267+
ViolationCount -->|< Threshold| End2([Done])
268+
ViolationCount -->|>= Threshold| RestrictSpammer[Restrict User]
269+
RestrictSpammer --> SendSpamRestriction[Send Restriction Notice]
270+
271+
%% Group Message Flow - Topic Guard
272+
CheckBot{From Bot?}
273+
CheckBot -->|Yes| End3([Ignore])
274+
CheckBot -->|No| TopicGuard{In Warning<br/>Topic?}
230275
TopicGuard -->|Yes| IsAdmin{Is Admin<br/>or Bot?}
231276
IsAdmin -->|No| DeleteMsg[Delete Message]
232-
IsAdmin -->|Yes| ProcessMsg[Process Message]
233-
TopicGuard -->|No| CheckBot{From Bot?}
277+
IsAdmin -->|Yes| End4([Allow])
234278
235-
CheckBot -->|Yes| End1([Ignore])
236-
CheckBot -->|No| CheckWhitelist{User<br/>Whitelisted?}
237-
238-
CheckWhitelist -->|Yes| End2([Allow])
279+
%% Group Message Flow - Profile Check
280+
TopicGuard -->|No| CheckWhitelist{User<br/>Whitelisted?}
281+
CheckWhitelist -->|Yes| End5([Allow])
239282
CheckWhitelist -->|No| CheckProfile[Check User Profile:<br/>Photo + Username]
240283
241284
CheckProfile --> ProfileComplete{Profile<br/>Complete?}
242-
ProfileComplete -->|Yes| End3([Allow])
285+
ProfileComplete -->|Yes| End6([Allow])
243286
ProfileComplete -->|No| CheckMode{Restriction<br/>Mode?}
244287
245288
%% Warning Mode
246289
CheckMode -->|Warning Only| SendWarning[Send Warning to Topic<br/>Time threshold mentioned]
247-
SendWarning --> End4([Done])
290+
SendWarning --> End7([Done])
248291
249292
%% Progressive Restriction Mode
250293
CheckMode -->|Progressive| CheckCount{Message<br/>Count?}
251294
CheckCount -->|First Message| SendFirstWarning[Send Warning with<br/>Message & Time Thresholds]
252295
SendFirstWarning --> IncrementDB[(Store Warning in DB<br/>with timestamp)]
253-
IncrementDB --> End5([Done])
296+
IncrementDB --> End8([Done])
254297
255298
CheckCount -->|2 to N-1| SilentIncrement[(Silent: Increment Count)]
256-
SilentIncrement --> End6([Done])
299+
SilentIncrement --> End9([Done])
257300
258-
CheckCount -->| Threshold| RestrictUser[Apply Restriction<br/>Mute Permissions]
301+
CheckCount -->|>= Threshold| RestrictUser[Apply Restriction<br/>Mute Permissions]
259302
RestrictUser --> MarkRestricted[(Mark as Restricted<br/>in Database)]
260303
MarkRestricted --> SendRestrictionMsg[Send Restriction Notice<br/>with DM Link]
261-
SendRestrictionMsg --> End7([Done])
304+
SendRestrictionMsg --> End10([Done])
262305
263306
%% DM Flow
264307
UpdateType -->|Private Message| CheckInGroup{User in<br/>Group?}
@@ -301,30 +344,48 @@ flowchart TD
301344
NextUser -->|Yes| CheckKicked
302345
NextUser -->|No| EndJob
303346
304-
%% Command Handlers
347+
%% Command Handlers - Verify/Unverify
305348
UpdateType -->|/verify Command| CheckAdminVerify{Is Admin?}
306349
CheckAdminVerify -->|No| DenyVerify[Send: Admin Only]
307350
CheckAdminVerify -->|Yes| AddWhitelist[(Add User to<br/>Photo Whitelist)]
308-
AddWhitelist --> SendVerifySuccess[Send: User Verified]
351+
AddWhitelist --> UnrestrictVerified[Unrestrict User]
352+
UnrestrictVerified --> DeleteWarnings[(Delete Warning Records)]
353+
DeleteWarnings --> CheckWarningsExist{Had<br/>Warnings?}
354+
CheckWarningsExist -->|Yes| SendClearance[Send Clearance Notification<br/>to Warning Topic]
355+
CheckWarningsExist -->|No| SendVerifySuccess[Send: User Verified]
356+
SendClearance --> SendVerifySuccess
309357
310358
UpdateType -->|/unverify Command| CheckAdminUnverify{Is Admin?}
311359
CheckAdminUnverify -->|No| DenyUnverify[Send: Admin Only]
312360
CheckAdminUnverify -->|Yes| RemoveWhitelist[(Remove from Whitelist)]
313361
RemoveWhitelist --> SendUnverifySuccess[Send: User Unverified]
314362
363+
%% Forwarded Message Handler
364+
UpdateType -->|Forwarded Message<br/>in DM| CheckAdminForward{Is Admin?}
365+
CheckAdminForward -->|No| DenyForward[Send: Admin Only]
366+
CheckAdminForward -->|Yes| ExtractUser{Extract<br/>User Info?}
367+
ExtractUser -->|Success| SendButtons[Send Verify/Unverify Buttons]
368+
ExtractUser -->|Failed| SendExtractError[Send: Cannot Extract User]
369+
370+
%% Callback Handlers
371+
UpdateType -->|Verify Button| ProcessVerify[Process Verify Callback]
372+
ProcessVerify --> AddWhitelist
373+
UpdateType -->|Unverify Button| ProcessUnverify[Process Unverify Callback]
374+
ProcessUnverify --> RemoveWhitelist
375+
315376
classDef processNode fill:#1a1a2e,stroke:#16213e,color:#eee
316377
classDef decisionNode fill:#0f3460,stroke:#16213e,color:#eee
317378
classDef dataNode fill:#16213e,stroke:#0f3460,color:#eee
318379
classDef actionNode fill:#533483,stroke:#16213e,color:#eee
319380
classDef endNode fill:#e94560,stroke:#16213e,color:#eee
320381
classDef startNode fill:#1a5f7a,stroke:#16213e,color:#eee
321382
322-
class Init,FetchAdmins,StartJobs,Poll,CheckProfile,CheckDMProfile,ProcessMsg,SendCaptcha,WaitCaptcha processNode
323-
class UpdateType,TopicGuard,IsAdmin,CheckBot,CheckWhitelist,ProfileComplete,CheckMode,CheckCount,CheckInGroup,CheckPendingCaptcha,DMProfileComplete,CheckBotRestricted,CheckCurrentStatus,HasExpired,CheckKicked,NextUser,CheckAdminVerify,CheckAdminUnverify,CaptchaAnswer decisionNode
324-
class IncrementDB,SilentIncrement,MarkRestricted,ClearRecord,ClearRecord2,QueryDB,ClearKicked,MarkTimeRestricted,AddWhitelist,RemoveWhitelist dataNode
325-
class DeleteMsg,SendWarning,SendFirstWarning,RestrictUser,SendRestrictionMsg,SendNotInGroup,SendCaptchaRedirect,SendMissing,SendNoRestriction,SendAlreadyUnrestricted,UnrestrictUser,SendSuccess,ApplyTimeRestriction,SendTimeNotice,SchedulerJob,SendVerifySuccess,SendUnverifySuccess,DenyVerify,DenyUnverify,UnrestrictMember,KickMember,Continue actionNode
326-
class End1,End2,End3,End4,End5,End6,End7,EndJob endNode
327-
class Start,StartNode startNode
383+
class Init,FetchAdmins,RecoverPending,StartJobs,Poll,CheckProfile,CheckDMProfile,RestrictAndChallenge,StorePending,ScheduleTimeout,WaitCaptcha,StartProbation,StartProbationAfter processNode
384+
class UpdateType,RecoverCaptcha,TopicGuard,IsAdmin,CheckBot,CheckWhitelist,ProfileComplete,CheckMode,CheckCount,CheckInGroup,CheckPendingCaptcha,DMProfileComplete,CheckBotRestricted,CheckCurrentStatus,HasExpired,CheckKicked,NextUser,CheckAdminVerify,CheckAdminUnverify,CaptchaAnswer,CheckCaptchaEnabled,CheckProbation,CheckExpired,CheckViolation,CheckWhitelisted,ViolationCount,CheckWarningsExist,CheckAdminForward,ExtractUser decisionNode
385+
class IncrementDB,SilentIncrement,MarkRestricted,ClearRecord,ClearRecord2,QueryDB,ClearKicked,MarkTimeRestricted,AddWhitelist,RemoveWhitelist,IncrementViolation,ClearProbation,DeleteWarnings dataNode
386+
class DeleteMsg,SendWarning,SendFirstWarning,RestrictUser,SendRestrictionMsg,SendNotInGroup,SendCaptchaRedirect,SendMissing,SendNoRestriction,SendAlreadyUnrestricted,UnrestrictUser,SendSuccess,ApplyTimeRestriction,SendTimeNotice,SchedulerJob,SendVerifySuccess,SendUnverifySuccess,DenyVerify,DenyUnverify,UnrestrictMember,KickMember,UpdateMessage,CancelTimeout,ShowError,DeleteSpam,SendSpamWarning,RestrictSpammer,SendSpamRestriction,UnrestrictVerified,SendClearance,DenyForward,SendButtons,SendExtractError,ProcessVerify,ProcessUnverify actionNode
387+
class End1,End2,End3,End4,End5,End6,End7,End8,End9,End10,EndJob,StartProbation endNode
388+
class Start startNode
328389
```
329390

330391
## How It Works
@@ -338,14 +399,18 @@ The bot is organized into clear modules for maintainability:
338399
- `message.py`: Monitors group messages and sends warnings/restrictions
339400
- `dm.py`: Handles DM unrestriction flow
340401
- `topic_guard.py`: Protects warning topic from unauthorized messages
402+
- `captcha.py`: Captcha verification for new members
403+
- `anti_spam.py`: Anti-spam enforcement for users on probation
404+
- `verify.py`: /verify and /unverify command handlers
341405
- **services/**: Business logic and utilities
342406
- `scheduler.py`: JobQueue background job that runs every 5 minutes for time-based auto-restrictions
343407
- `user_checker.py`: Profile validation (photo + username check)
344408
- `bot_info.py`: Caches bot metadata to avoid repeated API calls
345409
- `telegram_utils.py`: Shared telegram utilities (user status checks, etc.)
410+
- `captcha_recovery.py`: Captcha timeout recovery on bot restart
346411
- **database/**: Data persistence
347412
- `service.py`: Database operations with SQLite
348-
- `models.py`: Data models using SQLModel
413+
- `models.py`: Data models using SQLModel (UserWarning, PhotoVerificationWhitelist, PendingCaptchaValidation, NewUserProbation)
349414
- **config.py**: Environment configuration using Pydantic
350415
- **constants.py**: Centralized message templates and utilities for consistent formatting across handlers
351416

@@ -410,8 +475,15 @@ When a restricted user DMs the bot (or sends `/start`):
410475
| `RESTRICT_FAILED_USERS` | Enable progressive restriction mode | `false` |
411476
| `WARNING_THRESHOLD` | Messages before restriction (message-based) | `3` |
412477
| `WARNING_TIME_THRESHOLD_MINUTES` | Minutes before auto-restriction (time-based) | `180` (3 hours) |
478+
| `CAPTCHA_ENABLED` | Enable captcha verification for new members | `false` |
479+
| `CAPTCHA_TIMEOUT_SECONDS` | Seconds before kicking unverified members | `120` (2 minutes) |
480+
| `NEW_USER_PROBATION_HOURS` | Hours new users can't send links/forwards | `72` (3 days) |
481+
| `NEW_USER_VIOLATION_THRESHOLD` | Spam violations before restriction | `3` |
413482
| `DATABASE_PATH` | SQLite database path | `data/bot.db` |
414483
| `RULES_LINK` | Link to group rules message | `https://t.me/pythonID/290029/321799` |
484+
| `LOGFIRE_ENABLED` | Enable Logfire logging integration | `true` |
485+
| `LOGFIRE_TOKEN` | Logfire API token (optional) | None |
486+
| `LOG_LEVEL` | Logging level (DEBUG/INFO/WARNING/ERROR) | `INFO` |
415487

416488
### Restriction Modes
417489

0 commit comments

Comments
 (0)