Skip to content

Repository files navigation

toxic-bot

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


Table of Contents


Features

  • 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>, plus ai-injection-guard checks)
  • 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-positive ai-injection-guard blocks when they are just links
  • Normal emoji ZWJ sequences such as πŸ€·β€β™‚οΈ no longer trigger false-positive unicode_smuggling blocks
  • Dedicated injection event log: logs/prompt_injection_events.log with 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: /explain works on text, photos, voice messages
  • /dont_touch_me opt-out for group chats: bot ignores selected users (except /explain)
  • Private /settings menu: 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

Architecture

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

Requirements

  • Python 3.12
  • PostgreSQL 14+
  • Cloudflare account with AI Gateway configured for Groq
  • Groq API key
  • Telegram bot token from @BotFather

Installation

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

Configuration

.env

# 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=1

config.ini

All 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.3

Database

Migrations 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.


Running

Development

source .venv/bin/activate
python bot.py

systemd (production)

[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.target
sudo systemctl enable toxic-bot
sudo systemctl start toxic-bot
journalctl -u toxic-bot -f

Register bot commands (one-time)

python setup_commands.py

# Re-run after adding superadmin IDs or changing descriptions:
python setup_commands.py --force

Command Reference

Public (all chats)

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

Admin (group admins only)

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.

Explain (reply to message)

Command Where Description
/explain PM + groups Scientific/factual analysis of text/photo/voice

Superadmin Features

Superadmins (SUPERADMIN_IDS in .env). Commands work only in private chat with bot.

Commands

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.

Automatic PM notifications

  • Added to chat β€” title, chat ID, type
  • Kicked from chat β€” title, chat ID, type

Admin Settings Menu

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

Personality System

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

Project Structure

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


Translations

About

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.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages