Initial commit - Excommunicado Discord bot (XCOM stealth isolation)
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
# Excommunicado
|
||||
|
||||
**Excommunicado** is a Discord moderation bot designed to combat channel flooding and spam without resorting to bans or kicks.
|
||||
|
||||
In **stealth mode**, offending users **do not realize** they have been moved. They continue to see the entire server normally. Their public messages are silently deleted and forwarded to the shared **XCOM Lounge** room, where selected staff members can also be present to converse with them. Normal members never see the spam or the moderated room. This creates the illusion of a normal experience while containing the violation.
|
||||
|
||||
## Table of Contents
|
||||
- [Features](#features)
|
||||
- [Philosophy & Use Cases](#philosophy--use-cases)
|
||||
- [Requirements](#requirements)
|
||||
- [Installation & Quick Start](#installation--quick-start)
|
||||
- [Detailed Command Reference](#detailed-command-reference)
|
||||
- [Configuration](#configuration)
|
||||
- [How Isolation Works (Technical)](#how-isolation-works-technical)
|
||||
- [Architecture & Code Structure](#architecture--code-structure)
|
||||
- [Customization](#customization)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Security Best Practices](#security-best-practices)
|
||||
- [Extending the Bot](#extending-the-bot)
|
||||
- [License](#license)
|
||||
|
||||
## Features
|
||||
- **Slash commands only** (modern Discord UX)
|
||||
- `/xcom-setup` – one-time server initialization
|
||||
- `/xcom @user [reason]` – excommunicate a user (manual or via auto-detection)
|
||||
- `/xcom-release @user` – restore full access
|
||||
- `/xcom-list` – view all currently XCOM users with reasons and timestamps
|
||||
- **Automatic flood protection** – detects ≥5 messages within 8 seconds and auto-excommunicates
|
||||
- **Absolution Points** – users earn points for good behavior in the xcom-lounge; staff can absolve early
|
||||
- **Shared hidden channel** `xcom-lounge` with 5-second slowmode
|
||||
- **Persistent state** – JSON storage survives bot restarts
|
||||
- **Rich embeds + DM notifications** for offenders and staff logs
|
||||
- **Graceful permission handling** and role hierarchy checks
|
||||
- Zero bans/kicks – users stay in the server
|
||||
|
||||
## Philosophy & Use Cases
|
||||
Excommunicado solves the "ban vs. mute" dilemma for flooders:
|
||||
- Bans encourage alt accounts.
|
||||
- Timeouts/mutes still allow the user to see the server and feel excluded.
|
||||
- Excommunication gives the user a dedicated space to talk to moderators while completely removing their ability to disrupt public channels.
|
||||
|
||||
Ideal for:
|
||||
- High-traffic community servers
|
||||
- Gaming clans with strict chat rules
|
||||
- Support servers where users sometimes vent excessively
|
||||
- Any server that values retention over punishment
|
||||
|
||||
## Requirements
|
||||
- Python ≥ 3.10
|
||||
- discord.py ≥ 2.4.0 + python-dotenv
|
||||
- Discord bot with **privileged intents** enabled:
|
||||
- Server Members Intent
|
||||
- Message Content Intent
|
||||
- Bot permissions on invite: `Manage Roles`, `Manage Channels`, `Send Messages`, `Embed Links`, `Read Message History` (Administrator recommended for initial setup)
|
||||
- Role hierarchy: Bot role must sit **above** the `Excommunicado` role
|
||||
|
||||
## Installation & Quick Start
|
||||
|
||||
### 1. Prepare the project
|
||||
```
|
||||
cd ~/Excommunicado # or your chosen folder
|
||||
```
|
||||
|
||||
### 2. Install dependencies
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 3. Configure environment
|
||||
cp `.env.example` → `.env` and populate:
|
||||
```env
|
||||
DISCORD_TOKEN=your_token_here
|
||||
GUILD_ID=123456789012345678 # optional – speeds up command registration during development
|
||||
LOG_CHANNEL_ID=987654321098765432 # optional – receives audit embeds
|
||||
```
|
||||
|
||||
### 4. Create & invite the bot (Discord Developer Portal)
|
||||
1. https://discord.com/developers/applications → New Application → Bot
|
||||
2. Enable the two privileged intents under the Bot tab
|
||||
3. Generate a token (copy to `.env`)
|
||||
4. OAuth2 → URL Generator → `bot` + `applications.commands` scopes + required permissions
|
||||
5. Invite the bot to your target guild
|
||||
|
||||
### 5. Run the bot
|
||||
```powershell
|
||||
python bot.py
|
||||
```
|
||||
|
||||
You should see:
|
||||
```
|
||||
✅ Logged in as Excommunicado#1234 ...
|
||||
Excommunicado bot is ready (XCOM stealth isolation mode).
|
||||
[COG] Moderation (Excommunicado) loaded.
|
||||
```
|
||||
|
||||
### 6. Run `/xcom-setup` in Discord
|
||||
(Requires Manage Server permission)
|
||||
|
||||
This creates:
|
||||
- `Excommunicado` role (dark red color)
|
||||
- `xcom-lounge` text channel (hidden, slowmode 5s)
|
||||
|
||||
### 7. Manual role lockdown (critical for older non-stealth setups)
|
||||
After setup, the `Excommunicado` role is only a marker. Do **not** deny View on public channels (stealth mode keeps the user seeing the full server). The `xcom-lounge` is already hidden from @everyone.
|
||||
|
||||
### 8. Test the flow
|
||||
```
|
||||
/xcom @SomeSpammer Flooding with repeated messages
|
||||
```
|
||||
The user is stealthily XCOM'd. Their messages are forwarded to the shared room. They receive a DM and a staff log is sent (if configured).
|
||||
|
||||
## Detailed Command Reference
|
||||
|
||||
### `/xcom-setup`
|
||||
- **Permission**: Manage Server
|
||||
- **Purpose**: Idempotent creation of role + channel
|
||||
- **Output**: Embed explaining next manual steps
|
||||
|
||||
### `/xcom <user> [reason]`
|
||||
- **Permission**: Manage Roles
|
||||
- **Parameters**:
|
||||
- `user` (required) – target member
|
||||
- `reason` (optional) – default "Flooding the channel"
|
||||
- **Effects**:
|
||||
- Assigns `Excommunicado` role
|
||||
- Records in `data/xcom_config.json`
|
||||
- Posts welcome embed in `xcom-lounge`
|
||||
- DMs the user
|
||||
- Logs to staff channel (if set)
|
||||
- **Edge cases**: Already under XCOM, bot, self-target, missing hierarchy → clear ephemeral error
|
||||
|
||||
### `/xcom-release <user>`
|
||||
- **Permission**: Manage Roles
|
||||
- **Effects**: Removes role + record. The `[XCOM]` nickname mark **remains** until an admin runs `/xcom-unmark`.
|
||||
|
||||
### `/xcom-unmark <user>`
|
||||
- **Permission**: Manage Roles
|
||||
- **Effects**: Removes the permanent `[XCOM]` nickname prefix.
|
||||
|
||||
### `/xcom-vow <text>`
|
||||
- **Permission**: None (user must be under XCOM)
|
||||
- **Effects**: Posts the user's vow in the xcom-lounge for staff to see.
|
||||
|
||||
### `/xcom-witness @staff @target`
|
||||
- **Permission**: Manage Roles
|
||||
- **Effects**: Gives the staff member the Excommunicado role so they can join the shared lounge.
|
||||
|
||||
### `/xcom-absolve @user`
|
||||
- **Permission**: Manage Roles
|
||||
- **Effects**: If the user has ≥10 absolution points (earned by positive participation in the lounge), removes the role early. The mark remains.
|
||||
|
||||
### `/xcom-list`
|
||||
- **Permission**: Manage Roles
|
||||
- **Output**: Embed listing up to 15 users with reason + date (truncated if more)
|
||||
|
||||
All commands are ephemeral where possible to keep chat clean.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
| Variable | Required | Description |
|
||||
|-------------------|----------|------------------------------------------|
|
||||
| `DISCORD_TOKEN` | Yes | Bot token |
|
||||
| `GUILD_ID` | No | Guild for faster slash command sync |
|
||||
| `LOG_CHANNEL_ID` | No | Channel that receives action embeds |
|
||||
|
||||
### Tunable Constants (in `bot.py`)
|
||||
```python
|
||||
FLOOD_THRESHOLD = 5
|
||||
FLOOD_WINDOW_SECONDS = 5
|
||||
```
|
||||
Change and restart to adjust sensitivity.
|
||||
|
||||
### Data File
|
||||
`data/xcom_config.json` (auto-created):
|
||||
```json
|
||||
{
|
||||
"123456789": {
|
||||
"xcom_role_id": 111111111,
|
||||
"xcom_channel_id": 222222222,
|
||||
"isolated_users": {
|
||||
"333333333": {
|
||||
"reason": "Auto-detected flooding...",
|
||||
"timestamp": "2026-06-08T12:34:56.789012+00:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## How Isolation Works (Technical) — Stealth Mode
|
||||
1. On `/xcom-setup`, the bot creates:
|
||||
- `Excommunicado` role (marker only)
|
||||
- `xcom-lounge` channel (hidden from @everyone, visible to Excommunicado role holders)
|
||||
2. When a user is excommunicated (manually or automatically):
|
||||
- They receive the `Excommunicado` role (grants access to the shared room)
|
||||
- **No view permissions are removed** from public channels — the user continues to see the full server and does not realize anything changed.
|
||||
3. On every message the isolated user sends outside `xcom-lounge`:
|
||||
- The message is **instantly deleted** (public never sees the spam)
|
||||
- The content is forwarded to the shared `xcom-lounge` room
|
||||
- Staff members who also hold the `Excommunicado` role can see and reply in the same room
|
||||
4. The offender experiences normal server browsing + "their messages just go to the moderated lounge where staff are"
|
||||
5. `/xcom-release` removes the role — full normal behavior is restored instantly
|
||||
|
||||
This design ensures the violation holder shares the room with real staff members while never realizing they have been isolated.
|
||||
|
||||
## Architecture & Code Structure
|
||||
```
|
||||
Excommunicado/
|
||||
├── bot.py # Entry point, flood detector (on_message), ExcommunicadoBot class
|
||||
├── requirements.txt
|
||||
├── .env.example
|
||||
├── README.md # This file (full documentation)
|
||||
├── utils/
|
||||
│ ├── config.py # JSON load/save helpers + isolated user CRUD
|
||||
│ └── __init__.py
|
||||
├── cogs/
|
||||
│ ├── moderation.py # All slash commands + helper functions
|
||||
│ └── __init__.py
|
||||
└── data/
|
||||
└── xcom_config.json
|
||||
```
|
||||
|
||||
Key flows:
|
||||
- `on_message` → rate-limit deque → auto call to `get_or_create_*` + `add_roles`
|
||||
- Commands → permission checks → role/channel helpers → config persistence → DM + embed
|
||||
|
||||
## Customization
|
||||
- Change role name/color in `get_or_create_xcom_role`
|
||||
- Change channel name/slowmode in `get_or_create_xcom_channel`
|
||||
- Add more commands by creating additional cogs
|
||||
- Integrate with existing mod bots via webhooks or shared log channel
|
||||
|
||||
## Troubleshooting
|
||||
- **"Missing Permissions" on role assign** → Bot role not high enough in hierarchy
|
||||
- **Commands not appearing** → Restart bot after `GUILD_ID` change; wait 1h for global sync
|
||||
- **Isolated user messages still appear publicly** → The stealth suppression logic in on_message is not triggering (check that the user has the Excommunicado role or is in the isolated_users JSON)
|
||||
- **Auto-detection too sensitive** → Increase `FLOOD_WINDOW_SECONDS` or threshold
|
||||
- **JSON corrupted** → Delete `data/xcom_config.json` (bot will recreate)
|
||||
|
||||
## Security Best Practices
|
||||
- Never commit `.env` or the token
|
||||
- Use a dedicated bot account (not your personal account)
|
||||
- Give the bot the minimum permissions required
|
||||
- Regularly audit `data/xcom_config.json` for old entries
|
||||
- Give trusted staff the `Excommunicado` role so they can share the moderated room with XCOM users and respond naturally
|
||||
|
||||
## Extending the Bot
|
||||
Example: add a `/xcom-stats` command counting total excommunications.
|
||||
|
||||
1. Add new `@app_commands.command` in `moderation.py`
|
||||
2. Use `get_isolated_users` to aggregate data
|
||||
3. Register in `setup()`
|
||||
|
||||
The modular cog design makes extension trivial.
|
||||
|
||||
## License
|
||||
Internal moderation tool. Free to modify and use within your communities.
|
||||
|
||||
---
|
||||
|
||||
**Excommunicado** – Excommunicate the flood, keep the member.
|
||||
```
|
||||
(End of full documentation)
|
||||
|
||||
Made to keep your server clean without destroying community members.
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
- `/xcom @Spammer42 Spamming links and flooding`
|
||||
- `/xcom-list`
|
||||
- `/xcom-release @Spammer42`
|
||||
|
||||
The user is now under XCOM in the shared moderated room — problem contained.
|
||||
Reference in New Issue
Block a user