A Telegram group bot with a toxic personality inspired by Wednesday Addams. Responds to messages with cold sarcasm, logical pressure, and psychological precision β powered by Groq LLM via a Cloudflare AI Gateway.
Author: Recluse β me@recluse.ru β t.me/recluseru License: Unlicense
- Features
- Architecture
- Requirements
- Installation
- Configuration
- Database
- Running
- Command Reference
- Superadmin Features
- Admin Settings Menu
- Personality System
- Project Structure
- Translations
- Responds in group chats with configurable frequency and toxicity level
- Random auto-replies are limited to fresh messages, so the bot does not necropost into old threads
- Detects logical fallacies and psychological weakness in messages
- Replies with sharp, wit-first sarcasm β never dumb insults
- Per-chat settings managed via inline keyboard (admins only)
- Conversation history with PostgreSQL-backed memory
- Background summarisation to keep context window lean
- Multilingual interface: English, Russian, Ukrainian
- Adaptive response language: if a message is clearly in another single language, the bot replies in that language
- Prompt-injection prefilter before any LLM call (
<system>,</system>,<\system>, plusai-injection-guardchecks) - Context sanitization before LLM call: history and reply-chain entries are filtered for injection and dropped if unsafe
- Tag guard also covers admin-tag variants (
<admin>,</admin>,<\admin>) including regex/escaped forms - Ordinary
https://...links no longer trigger false-positiveai-injection-guardblocks when they are just links - Normal emoji ZWJ sequences such as
π€·ββοΈno longer trigger false-positiveunicode_smugglingblocks - Dedicated injection event log:
logs/prompt_injection_events.logwith full chat/user/message payload - Superadmin PM alerts on every injection trigger with source and detailed reason
- Injection-like random group messages are silently dropped; explicit reactions remain in PM, commands, and direct replies to the bot
- Auto-registers chats on first message β no manual setup needed
- Superadmin PM notifications and broadcast system
- Cloudflare AI Gateway integration for observability and rate limiting
- Global error handler β no silent crashes
- Flood control handling β retries automatically on Telegram rate limits
- Multimodal support:
/explainworks on text, photos, voice messages /dont_touch_meopt-out for group chats: bot ignores selected users (except/explain)- Private
/settingsmenu: PM toxicity, dossier, global untouchable toggle, self-reset - PM hourly limits: text (10/h), media (5/h),
/explain(5/h) - Groq fallback model when primary is over capacity (503)
- Extended superadmin dashboards: runtime, activity counters, database sizes
Telegram ββ python-telegram-bot ββ handlers/
βββ commands_public.py
βββ commands_explain.py
βββ messages.py
βββ lifecycle.py
βββ superadmin.py
βββ language_select.py
βββ admin_menu/
βββ callbacks.py
βββ main_menu.py
βββ frequency_menu.py
βββ toxicity_menu.py
βββ simple_choice_menus.py
βββ user_management_menu.py
βββ router.py
ββ ai/
βββ client.py
βββ prompts.py
βββ responder.py
βββ summarizer.py
βββ transcriber.py
βββ vision.py
ββ db/
βββ pool.py
βββ migrations.py
βββ chat_settings.py
βββ history.py
βββ chats.py
βββ user_profiles.py
LLM requests go through:
bot β Cloudflare AI Gateway β Groq API β LLM model
- Python 3.12
- PostgreSQL 14+
- Cloudflare account with AI Gateway configured for Groq
- Groq API key
- Telegram bot token from @BotFather
git clone https://github.com/Recluse/toxic-bot
cd toxic-bot
python -m venv .venv
source .venv/bin/activate # Linux/Mac
# .venv\Scripts\activate # Windows
pip install -r requirements.txt
cp .env.example .env
# Edit .env with your credentials# Telegram
TELEGRAM_BOT_TOKEN=your_bot_token_here
# Groq
GROQ_API_KEY=your_groq_api_key_here
# Cloudflare AI Gateway
CF_ACCOUNT_ID=your_cloudflare_account_id
CF_GATEWAY_ID=your_gateway_id
# PostgreSQL
DATABASE_URL=postgresql://user:password@localhost:5432/toxicbot
# Superadmin Telegram user IDs (comma-separated)
SUPERADMIN_IDS=123456789,987654321
# Set automatically by setup_commands.py after first run β do not edit manually
# COMMANDS_REGISTERED=1All values are optional β shown with defaults:
[bot]
max_history_messages = 20
default_lang = en
[defaults]
toxicity_level = 3
freq_min = 5
freq_max = 15
reply_cooldown_sec = 60
reply_chain_depth = 5
min_words = 5
[groq]
model = openai/gpt-oss-120b # current Groq production text model
fallback_model = llama-3.3-70b-versatile # automatic fallback on 503/over-capacity
vision_model = meta-llama/llama-4-scout-17b-16e-instruct
whisper_model = whisper-large-v3-turbo
temperature = 0.85
max_tokens = 1024
top_p = 0.95
[summarizer]
model = llama-3.3-70b-versatile
max_tokens = 512
temperature = 0.3Migrations run automatically on every startup via db/migrations.py.
No manual SQL required. Tables created:
| Table | Purpose |
|---|---|
chat_settings |
Per-chat configuration (toxicity, frequency, lang) |
message_history |
Conversation message history per chat |
chats |
Membership tracking (joined, active, kicked) |
user_profiles / user_summaries |
Per-user psychological/behavioral summaries |
untouchable_users |
Per-chat ignore list |
global_untouchables |
Global opt-out list across all chats |
bot_metrics |
Persistent global counters for superadmin stats |
chat_metrics |
Per-chat activity counters for superadmin dashboards |
Chats are auto-registered on the first incoming message.
source .venv/bin/activate
python bot.py[Unit]
Description=Toxic Wednesday Telegram Bot
After=network.target postgresql.service
[Service]
User=youruser
WorkingDirectory=/home/youruser/toxic-bot
EnvironmentFile=/home/youruser/toxic-bot/.env
ExecStart=/home/youruser/toxic-bot/.venv/bin/python bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetsudo systemctl enable toxic-bot
sudo systemctl start toxic-bot
journalctl -u toxic-bot -fpython setup_commands.py
# Re-run after adding superadmin IDs or changing descriptions:
python setup_commands.py --force| Command | Where | Description |
|---|---|---|
/start |
PM + groups | Greeting from the bot |
/help |
PM + groups | Usage instructions |
/about |
PM + groups | Current personality settings for this chat |
/reset |
PM + groups | Clear your personal conversation history |
/dont_touch_me |
Groups | Add yourself to untouchables |
/settings |
PM | Open private settings menu |
| Command | Where | Description |
|---|---|---|
/toxic |
Groups | Reply to a message to force the bot to respond |
/settings |
Groups | Open the inline settings menu |
Admin commands are silently deleted if caller is not admin.
| Command | Where | Description |
|---|---|---|
/explain |
PM + groups | Scientific/factual analysis of text/photo/voice |
Superadmins (SUPERADMIN_IDS in .env). Commands work only in private chat with bot.
| Command | Description |
|---|---|
/sa_chats |
Group active spaces by groups/PMs/channels with per-chat activity, history, settings, and injection counters |
/sa_stats |
Grouped dashboard: runtime, scope split, traffic, top spaces, DB sizes |
/sa_broadcast |
Send message to all active groups (conversation) |
/cancel |
Abort in-progress broadcast |
/sa_chats enriches entries with live Telegram lookup by chat_id (name/title and @username) and falls back to DB data. It also shows tracked incoming messages, replies, history rows, distinct users, injection counters, and current chat settings for each space.
- Added to chat β title, chat ID, type
- Kicked from chat β title, chat ID, type
Group admins: /settings β inline keyboard. Changes apply immediately.
| Setting | Range / Options | Description |
|---|---|---|
| Toxicity level | 1β5 | 1=mild, 5=nuclear |
| Reply frequency | minβmax (random) | How often bot responds (adjustment step: 10) |
| User cooldown | 30/60/120/300 sec | Time between replies to same user |
/explain cooldown |
10β600 min (step 10) | Time between /explain requests per user in groups |
| Reply chain depth | 3/5/7/10 | Messages back in reply chain |
| Minimum words | 3/5/7/10 | Ignore shorter messages |
| User management | List/reset profiles | View/delete user summaries |
| Untouchables | List/remove users | Remove users from bot ignore list |
In private chat, /settings opens a personal menu:
- PM toxicity level
- global untouchable toggle
- dossier preview
- remove user data from DB
Wednesday Addams Γ analytical toxicity:
- Logical dissection β names fallacies, cites facts
- Psychological pressure β targets specific weaknesses
- Wit-first β precise, never generic insults
- Context-aware β uses history + user profiles
| Level | Name | Style |
|---|---|---|
| 1 | Cold Disappointment | Dry, distant observation |
| 2 | Logical Dissection | Forensic reasoning takedown |
| 3 | Psychological Pressure | Surgical insecurity probing (def) |
| 4 | Weaponised Wit | Compliment β twist β dagger |
| 5 | Nuclear Wednesday | Full verdict, documented |
toxic-bot/
βββ .env* # Secrets (not committed)
βββ .env.example # Template
βββ .gitignore
βββ README.{md,ru.md,uk.md}
βββ config.ini # Non-secret defaults
βββ config.py # Config loader dataclasses
βββ bot.py # Entrypoint, handlers, migrations
βββ setup_commands.py # Telegram command registration
βββ requirements.txt
βββ ai/
β βββ client.py # AsyncOpenAI β CF Gateway β Groq
β βββ prompts.py # 5 levels Γ 3 langs + injection guard
β βββ responder.py # Main get_reply() pipeline
β βββ summarizer.py # Background user profile summaries
β βββ transcriber.py # Voice β text (Whisper)
β βββ vision.py # Photo β base64 multimodal
βββ db/
β βββ pool.py # asyncpg pool
β βββ migrations.py # Idempotent DDL
β βββ chat_settings.py # Per-chat CRUD
β βββ history.py # Message history CRUD
β βββ chats.py # Chat tracking CRUD
β βββ metrics.py # Persistent bot counters
β βββ user_profiles.py # User psych profiles CRUD
β βββ untouchables.py # Untouchable users CRUD
βββ handlers/
β βββ commands_public.py # /start /help /about /reset /dont_touch_me /toxic
β βββ commands_explain.py # /explain (multimodal)
β βββ messages.py # Main handler + freq/cooldown logic
β βββ lifecycle.py # Join/leave + superadmin PMs
β βββ pm_settings.py # Private /settings menu
β βββ superadmin.py # /sa_* commands
β βββ language_select.py # Language picker
β βββ admin_menu/
β βββ callbacks.py # Callback constants
β βββ main_menu.py # Settings entry
β βββ frequency_menu.py # Freq min/max
β βββ toxicity_menu.py # Toxicity levels
β βββ simple_choice_menus.py# Cooldown/chain/minwords
β βββ user_management_menu.py# User profiles UI
β βββ untouchables_menu.py # Untouchables UI
β βββ router.py # Callback dispatcher
βββ i18n/
β βββ __init__.py # gettext(key, lang, **kwargs)
β βββ en.json
β βββ ru.json
β βββ ua.json
βββ utils/
βββ admin_check.py # is_chat_admin() + superadmin
βββ rate_limiter.py # Per-user cooldowns
βββ reply_chain.py # Reply chain collector
βββ tg_safe.py # Safe send/edit wrappers (RetryAfter, etc.)
*Not committed