Skip to content

Commit 150ec91

Browse files
authored
refactor: modularize verification cog
Refactored the Verification cog from a single monolithic file into a clean, modular package structure to improve maintainability. The cog is now organized into focused modules with clear responsibilities: verification/ ├── verification.py Main cog (commands, listeners, sync) └── helpers/ ├── __init__.py Centralized re-exports ├── constants.py All constants and default data ├── utils.py Emoji normalization + challenge generator ├── embeds.py All embed builders ├── data_manager.py JSON file I/O ├── modals.py All modals ├── verify_views.py User-facing views ├── setup_views.py Setup wizard └── menu_views.py .verifymenu views Benefits: - Single Responsibility per file - Easier to extend — adding an embed only touches embeds.py - No circular imports - Testable in isolation - Main file reduced from ~1800 to ~500 lines - Backwards-compatible via helpers/__init__.py No functional changes. All commands, events, and user flows tested and working.
1 parent 7ffa89b commit 150ec91

14 files changed

Lines changed: 2570 additions & 0 deletions

‎verification/LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 ToHubLab
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎verification/README.md‎

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
# Verification Cog for Red-DiscordBot
2+
3+
A Red-DiscordBot cog that verifies new members via a button or reaction, challenges them with a math or text task, and grants a role — with a full setup wizard, custom emoji support, security checks, and a live management menu.
4+
5+
---
6+
7+
## ✨ Features
8+
9+
| Feature | Description |
10+
|---|---|
11+
| ⚙️ **Interactive Setup Wizard** | 4-step wizard: channel → role → mode → confirm — one single message, no spam |
12+
| 🔘 **Button Mode** | Users verify via a button directly on a message the bot posts |
13+
| 💬 **Reaction Mode** | Use any existing message — the bot adds a reaction emoji to trigger verification |
14+
| 🎨 **Emoji Picker** | Choose from 24 standard emojis — or extend them via a JSON data file |
15+
| 🧮 **Math Challenges** | Random addition, subtraction, and multiplication problems |
16+
| ✍️ **Text Challenges** | Prompts like `Type 'ToHubLab' to verify` or `Write 'Color' to verify` |
17+
| 🎭 **Auto Role Assignment** | Grants the configured verification role upon success |
18+
| ⏳ **3-Strike Lockout** | Wrong answers lock the user out for 10 minutes with a live progress bar |
19+
| 🔐 **Security Check** | If the role is manually removed, users answer 2 security questions to re-verify |
20+
| 🧹 **Auto-Cleanup** | Setup, status, reset, and cancel messages auto-delete after a few seconds |
21+
| 🔄 **Background Sync** | Every 5 minutes, reactions and roles are synced to prevent drift |
22+
| 📊 **Live Status Menu** | `.verifymenu` shows the current config with buttons to change things |
23+
| 📋 **Verified Users List** | `.verifysetup verified` — ephemeral, paginated (5 per page), with Prev/Next |
24+
| 📁 **JSON Data File** | Emoji options, text challenges, and security questions all live in one file |
25+
| 🔧 **Persistent Buttons** | Verification buttons keep working after bot restarts |
26+
| 🔒 **Admin Only** | Configuration commands require `Manage Server` |
27+
| 🐙 **Credits** | Built-in link to [ToHubLab on GitHub](https://github.com/ToHubLab) |
28+
29+
---
30+
31+
## 📦 Installation
32+
33+
```text
34+
[p]repo add ToHubLab-Cogs https://github.com/ToHubLab/ToHubLab-Cogs
35+
```
36+
37+
```text
38+
[p]cog install ToHubLab-Cogs verification
39+
```
40+
41+
```text
42+
[p]load verification
43+
```
44+
45+
---
46+
47+
## 🚀 Quick Start
48+
49+
```text
50+
[p]verifysetup start
51+
```
52+
53+
Follow the wizard:
54+
55+
1. **Select the verification channel**
56+
2. **Select the role** to grant on success
57+
3. **Choose a mode**:
58+
- 📝 *Send new message* — bot posts a message with a **Verify** button
59+
- 💬 *Use existing message* — pick a message ID and a reaction emoji
60+
4. **Confirm & Create**
61+
62+
Then verify your setup with:
63+
64+
```text
65+
[p]verifysetup status
66+
```
67+
68+
---
69+
70+
## 🛠️ Commands
71+
72+
| Command | Description |
73+
|---|---|
74+
| `[p]verifysetup start` | Runs the interactive setup wizard |
75+
| `[p]verifysetup status` | Shows the current config (auto-deletes after 8s) |
76+
| `[p]verifysetup reset` | Resets the setup and cleans up everything |
77+
| `[p]verifysetup cleanup [#channel]` | Deletes orphaned verification messages |
78+
| `[p]verifysetup reloaddata` | Reloads `verification_data.json` from disk |
79+
| `[p]verifysetup sync` | Manually runs the reaction/role sync |
80+
| `[p]verifysetup verified` | Paginated list of verified users (ephemeral, 5 per page) |
81+
| `[p]verifymenu` | Opens the interactive management menu |
82+
83+
All commands require **Manage Server** permission.
84+
85+
---
86+
87+
## 📁 Project Structure
88+
89+
The cog is organized into focused modules with clear responsibilities.
90+
The main cog file handles commands and events, while every helper lives
91+
in its own file under `helpers/`.
92+
93+
```text
94+
verification/
95+
├── __init__.py Package entry point
96+
├── info.json Cog metadata for Red
97+
├── verification.py Main cog (commands, listeners, sync)
98+
├── README.md This file
99+
├── LICENSE MIT License
100+
└── helpers/
101+
├── __init__.py Centralized re-exports
102+
├── constants.py All constants and default data
103+
├── utils.py Emoji normalization + challenge generator
104+
├── embeds.py All embed builders
105+
├── data_manager.py JSON file I/O (data + verified users)
106+
├── modals.py All modals
107+
├── verify_views.py User-facing views
108+
├── setup_views.py Setup wizard and its views
109+
└── menu_views.py .verifymenu views
110+
```
111+
112+
### Why modular?
113+
114+
- **Single Responsibility** — each file handles one concern
115+
- **Easier to extend** — adding an embed only touches `embeds.py`
116+
- **No circular imports** — helpers import strictly what they need
117+
- **Testable in isolation** — every helper can be unit-tested
118+
- **Cleaner cog** — `verification.py` stays small (~500 lines)
119+
120+
---
121+
122+
## 📁 Data Files
123+
124+
On first load, the cog creates two files in its data directory:
125+
126+
```text
127+
<Red-Daten-Ordner>/Verification/verification_data.json
128+
<Red-Daten-Ordner>/Verification/verified_users.json
129+
```
130+
131+
### `verification_data.json`
132+
133+
Contains all customizable content. Edit it and run
134+
`[p]verifysetup reloaddata` to apply changes.
135+
136+
```json
137+
{
138+
"emoji_options": [
139+
["✅", "Check Mark Button"],
140+
["👍", "Thumbs Up"]
141+
],
142+
"text_challenges": [
143+
["Write 'Color' to verify", "color"],
144+
["Type 'ToHubLab' to verify", "tohublab"]
145+
],
146+
"security_questions": [
147+
["How many letters are in the word 'verify'?", "6"],
148+
["What color is the sky on a clear day?", "blue"]
149+
]
150+
}
151+
```
152+
153+
### `verified_users.json`
154+
155+
A read-only mirror of verified user IDs per guild. It is written
156+
automatically after each successful verification.
157+
158+
```json
159+
{
160+
"1234567890": [111111111111111111, 222222222222222222]
161+
}
162+
```
163+
164+
---
165+
166+
## 🔑 Requirements
167+
168+
The bot needs the following permissions in the verification channel:
169+
170+
| Permission | Why |
171+
|---|---|
172+
| **Send Messages** | Post verification messages |
173+
| **Embed Links** | Embed support |
174+
| **Add Reactions** | Reaction mode |
175+
| **Read Message History** | Reaction mode + cleanup |
176+
| **Manage Messages** | Delete old setup/status messages |
177+
| **Manage Roles** | Grant the verification role |
178+
179+
> ⚠️ The verification role must be **below** the bot's highest role
180+
> in the server role hierarchy.
181+
182+
---
183+
184+
## 🎯 How It Works
185+
186+
### Button Mode
187+
188+
1. User clicks the **Verify** button on the verification message
189+
2. A modal opens with a math or text challenge
190+
3. Correct answer → role granted
191+
4. Wrong answer → failed attempt counted
192+
5. After 3 wrong answers → 10-minute lockout with progress bar
193+
194+
### Reaction Mode
195+
196+
1. User reacts with the configured emoji
197+
2. Bot posts a short prompt in the same channel with an **Enter Answer** button
198+
3. Button click opens the challenge modal
199+
4. Correct answer → role granted and reaction kept
200+
5. Wrong answer → reaction removed so the user can retry
201+
6. Cancel or timeout → reaction removed automatically
202+
203+
### Security Check
204+
205+
If an admin manually removes the verification role from a verified user,
206+
the next time they try to verify they must first answer **two security
207+
questions**. On success, they are removed from the verified list and can
208+
run through verification again.
209+
210+
### Background Sync
211+
212+
Every 5 minutes the cog reconciles the reaction list and the role list:
213+
214+
| Situation | Action |
215+
|---|---|
216+
| Member has the role but **no reaction** | Role is removed |
217+
| Member has a reaction but **no role** and is on the verified list | Reaction is removed |
218+
| Member has a reaction but **no role** and is mid-verification | Nothing (in progress) |
219+
220+
This prevents drift between the reaction counter and the actual role
221+
assignment.
222+
223+
---
224+
225+
## 🎨 Customization
226+
227+
Everything user-facing can be customized without touching the code:
228+
229+
- **Emojis** — add or remove entries in `emoji_options`
230+
- **Text challenges** — add custom prompts in `text_challenges`
231+
- **Security questions** — add your own questions in `security_questions`
232+
- **Timings** — edit the constants at the top of `helpers/constants.py`
233+
- **Embed colors** — adjust in `helpers/embeds.py`
234+
235+
After editing `verification_data.json`, run:
236+
237+
```text
238+
[p]verifysetup reloaddata
239+
```
240+
241+
---
242+
243+
## 🐛 Troubleshooting
244+
245+
| Problem | Solution |
246+
|---|---|
247+
| Users can't verify | Check that the verification role is **below** the bot's role |
248+
| Reaction mode not working | Make sure the bot has **Add Reactions** + **Read Message History** |
249+
| Counter stays at 1 | Run `[p]verifysetup sync` to reconcile |
250+
| Messages not deleting | Bot needs **Manage Messages** |
251+
| Data file not reloading | Run `[p]verifysetup reloaddata` |
252+
253+
---
254+
255+
## 🐙 Credits
256+
257+
Made by [ToHubLab](https://github.com/ToHubLab)
258+
259+
- **GitHub** — [github.com/ToHubLab](https://github.com/ToHubLab)
260+
- **Support & Updates** — [discord.finn-bot.rf.gd](http://discord.finn-bot.rf.gd)
261+
262+
---
263+
264+
## 📜 License
265+
266+
MIT — see [LICENSE](LICENSE) for details.

‎verification/__init__.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from .verification import Verification
2+
3+
4+
async def setup(bot):
5+
await bot.add_cog(Verification(bot))

‎verification/helpers/__init__.py‎

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""Helper modules for the Verification cog."""
2+
3+
from .constants import (
4+
DEFAULT_VERIFICATION_EMOJI,
5+
VERIFICATION_EMBED_TITLE,
6+
SETUP_AUTO_DELETE_SECONDS,
7+
CANCEL_AUTO_DELETE_SECONDS,
8+
MENU_TIMEOUT_SECONDS,
9+
SYNC_INTERVAL_MINUTES,
10+
CHALLENGE_TIMEOUT_SECONDS,
11+
VERIFIED_PAGE_SIZE,
12+
CREDIT_NAME,
13+
CREDIT_URL,
14+
CREDIT_LINE,
15+
DATA_FILE_NAME,
16+
VERIFIED_FILE_NAME,
17+
DEFAULT_EMOJI_OPTIONS,
18+
DEFAULT_TEXT_CHALLENGES,
19+
DEFAULT_SECURITY_QUESTIONS,
20+
)
21+
from .utils import normalize_emoji, generate_challenge
22+
from .embeds import (
23+
verification_embed,
24+
step1_embed,
25+
step2_embed,
26+
step3_embed,
27+
step4_embed,
28+
success_embed,
29+
error_embed,
30+
cancel_embed,
31+
status_embed,
32+
not_setup_embed,
33+
)
34+
from .data_manager import DataManager
35+
from .modals import (
36+
ChallengeModal,
37+
SecurityCheckModal,
38+
MessageIDModal,
39+
ChangeMessageModal,
40+
)
41+
from .verify_views import (
42+
VerifyView,
43+
ChannelChallengeStartView,
44+
SecurityCheckStartView,
45+
ContinueChallengeView,
46+
VerifiedPaginatorView,
47+
)
48+
from .setup_views import (
49+
SetupWizard,
50+
SetupChannelView,
51+
SetupRoleView,
52+
SetupModeView,
53+
SetupConfirmView,
54+
ReactionSetupView,
55+
NotSetupView,
56+
)
57+
from .menu_views import (
58+
VerificationMenuView,
59+
EmojiChangeView,
60+
ConfirmResetView,
61+
)
62+
63+
__all__ = [
64+
# constants
65+
"DEFAULT_VERIFICATION_EMOJI", "VERIFICATION_EMBED_TITLE",
66+
"SETUP_AUTO_DELETE_SECONDS", "CANCEL_AUTO_DELETE_SECONDS",
67+
"MENU_TIMEOUT_SECONDS", "SYNC_INTERVAL_MINUTES",
68+
"CHALLENGE_TIMEOUT_SECONDS", "VERIFIED_PAGE_SIZE",
69+
"CREDIT_NAME", "CREDIT_URL", "CREDIT_LINE",
70+
"DATA_FILE_NAME", "VERIFIED_FILE_NAME",
71+
"DEFAULT_EMOJI_OPTIONS", "DEFAULT_TEXT_CHALLENGES", "DEFAULT_SECURITY_QUESTIONS",
72+
# utils
73+
"normalize_emoji", "generate_challenge",
74+
# embeds
75+
"verification_embed", "step1_embed", "step2_embed", "step3_embed", "step4_embed",
76+
"success_embed", "error_embed", "cancel_embed", "status_embed", "not_setup_embed",
77+
# data
78+
"DataManager",
79+
# modals
80+
"ChallengeModal", "SecurityCheckModal", "MessageIDModal", "ChangeMessageModal",
81+
# views
82+
"VerifyView", "ChannelChallengeStartView", "SecurityCheckStartView",
83+
"ContinueChallengeView", "VerifiedPaginatorView",
84+
# setup
85+
"SetupWizard", "SetupChannelView", "SetupRoleView", "SetupModeView",
86+
"SetupConfirmView", "ReactionSetupView", "NotSetupView",
87+
# menu
88+
"VerificationMenuView", "EmojiChangeView", "ConfirmResetView",
89+
]

0 commit comments

Comments
 (0)