Catch Django exceptions and send formatted error reports to Telegram with optional database logging
Project description
django-telegram-notifier
Catch unhandled Django exceptions and send formatted error reports to Telegram — like a lightweight Sentry. Includes full traceback as a .py file attachment with syntax highlighting, optional database logging, and async support.
Features
- Automatic exception catching via middleware (sync & async)
- Formatted Telegram messages with emoji levels, request context, and traceback preview
- Full traceback as
.pyfile — Telegram renders Python syntax highlighting - Optional database logging — store every exception with request details, severity, status
- Decorator for wrapping individual functions/views
- Multi-chat support — send to multiple Telegram chats
- Proxy support for restricted environments
- Management command to clean up old exception logs
Quick Start
1. Install
pip install django-telegram-notifier
2. Get a Telegram Bot Token
- Open Telegram, search for @BotFather
- Send
/newbotand follow the prompts - Copy the bot token (e.g.
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11) - Send a message to your bot, then visit
https://api.telegram.org/bot<TOKEN>/getUpdatesto find yourchat_id
3. Configure
Add to your Django settings.py:
INSTALLED_APPS = [
# ...
"telegram_notifier",
]
MIDDLEWARE = [
# ... other middleware ...
"telegram_notifier.middleware.GlobalExceptionReporterMiddleware",
]
TELEGRAM_NOTIFIER = {
"BOT_TOKEN": "your-bot-token",
"CHAT_IDS": ["your-chat-id"],
}
4. Migrate (only if using database logging)
python manage.py migrate
That's it. Any unhandled exception will now send a notification to your Telegram chat.
Settings
All settings go inside the TELEGRAM_NOTIFIER dictionary in your Django settings:
TELEGRAM_NOTIFIER = {
# Required
"BOT_TOKEN": "your-bot-token",
"CHAT_IDS": ["chat-id-1", "chat-id-2"],
# Optional (defaults shown)
"ENVIRONMENT": None, # e.g. "production", "staging" — shown in messages
"PROXY": None, # e.g. "http://proxy:8080"
"MESSAGE_MAX_LENGTH": 4000, # max message length (Telegram limit)
"STORE_EXCEPTIONS": False, # save exceptions to database
"CLEANUP_DAYS": 30, # days to keep exception logs
}
| Setting | Type | Default | Description |
|---|---|---|---|
BOT_TOKEN |
str |
required | Telegram Bot API token |
CHAT_IDS |
list[str] |
required | Telegram chat IDs to send notifications to |
ENVIRONMENT |
str | None |
None |
Environment name shown in messages (e.g. "production") |
PROXY |
str | None |
None |
HTTP proxy URL for Telegram API requests |
MESSAGE_MAX_LENGTH |
int |
4000 |
Maximum message length before truncation |
STORE_EXCEPTIONS |
bool |
False |
Save exceptions to ExceptionLog model |
CLEANUP_DAYS |
int |
30 |
Days to keep exception logs (used by cleanup command) |
Usage
Middleware (recommended)
The middleware catches all unhandled exceptions automatically. Place it after Django's built-in middleware:
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"telegram_notifier.middleware.GlobalExceptionReporterMiddleware",
]
The middleware is async-capable — works with both WSGI and ASGI servers.
Decorator
Wrap individual functions or views:
from telegram_notifier import telegram_exception_notifier
@telegram_exception_notifier
def my_task():
# if this raises, it gets reported to Telegram
do_something_risky()
# Also works with async functions
@telegram_exception_notifier
async def my_async_task():
await do_something_risky()
Manual Reporting
Report exceptions programmatically:
from telegram_notifier import report_exception
try:
do_something()
except Exception as exc:
report_exception(exc, level="critical", severity="high")
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
exc |
Exception |
required | The exception to report |
request |
HttpRequest | None |
None |
Django request (adds path, method, body, user) |
body |
bytes | None |
None |
Request body |
level |
str | None |
"error" |
"debug", "info", "warning", "error", "critical" |
severity |
str | None |
None |
"low", "moderate", "high", "critical" |
Telegram Message Format
Each notification is sent as a document (.py file with full traceback) with a caption containing:
🔴 ValueError in production
Message: invalid literal for int()
Timestamp: 2026-03-11 12:30:45
▸ Traceback (preview)
value = int(user_input)
ValueError: invalid literal for int() with base 10: 'abc'
▸ Request
Path: /api/users/
Method: POST
Body: {"name": "test"}
User: admin@example.com
Level emojis: ⚪ debug · 🔵 info · 🟡 warning · 🔴 error · ⛔ critical
The attached .py file contains the complete traceback with Python syntax highlighting in Telegram.
Database Logging
Enable with "STORE_EXCEPTIONS": True. This creates an ExceptionLog entry for every reported exception.
ExceptionLog Fields
| Field | Type | Description |
|---|---|---|
exception_class |
CharField |
e.g. "ValueError" |
message |
TextField |
Exception message |
traceback |
TextField |
Full traceback |
level |
CharField |
debug, info, warning, error, critical |
severity |
CharField |
low, moderate, high, critical |
status |
CharField |
new, seen, resolved, ignored |
path |
CharField |
Request path |
method |
CharField |
HTTP method |
query_params |
JSONField |
Query string parameters |
body |
TextField |
Request body |
user_info |
CharField |
Authenticated user string |
ip_address |
GenericIPAddressField |
Client IP (with X-Forwarded-For support) |
headers |
JSONField |
Request headers (sensitive headers filtered) |
view_name |
CharField |
Django view name |
hostname |
CharField |
Server hostname |
environment |
CharField |
Environment from settings |
is_sent |
BooleanField |
Whether Telegram notification was sent |
created_at |
DateTimeField |
When the exception occurred |
Querying Exceptions
from telegram_notifier import ExceptionLog, Status, Level
# Unresolved errors
ExceptionLog.objects.filter(status=Status.NEW, level=Level.ERROR)
# Errors in the last 24 hours
from django.utils.timezone import now
from datetime import timedelta
ExceptionLog.objects.filter(created_at__gte=now() - timedelta(hours=24))
# Mark as resolved
ExceptionLog.objects.filter(pk=1).update(status=Status.RESOLVED)
Cleanup Command
Delete old exception logs:
# Use CLEANUP_DAYS setting (default: 30)
python manage.py cleanup_exceptions
# Override with custom days
python manage.py cleanup_exceptions --days=7
Schedule with cron for automatic cleanup:
0 3 * * * python /path/to/manage.py cleanup_exceptions
When to Use
| Scenario | Recommendation |
|---|---|
| Small/medium project, want instant error alerts | Use this |
| Need error notifications in Telegram groups | Use this |
| Want a lightweight alternative to Sentry | Use this |
| Team already uses Telegram for communication | Use this |
| Need detailed error analytics and dashboards | Use Sentry instead |
| Processing thousands of errors per minute | Use Sentry instead |
Requirements
- Python >= 3.11
- Django >= 5.2
- httpx >= 0.28.1
Development
git clone https://github.com/ganiyevuz/django-telegram-notifier.git
cd django-telegram-notifier
# Install dependencies
uv sync --group dev
# Copy env file and add your bot token
cp .env.example .env
# Run tests
pytest
# Run linter
ruff check .
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_telegram_notifier-0.1.0.tar.gz.
File metadata
- Download URL: django_telegram_notifier-0.1.0.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58b5b434bf37d380a9f4f71be0120aa13d598ebf7407759de87103b327a920c7
|
|
| MD5 |
a6ff66c7b0bdb83c904539e3cafb24e2
|
|
| BLAKE2b-256 |
43a09da645b3d95f2795ef28328f8ed55753a07f339aee84ce1bb770b447bcfb
|
File details
Details for the file django_telegram_notifier-0.1.0-py3-none-any.whl.
File metadata
- Download URL: django_telegram_notifier-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a368a084fcb3201cf4768d0c3b86942a2803fa85ad721fc90a1928c5e78ad3c
|
|
| MD5 |
c64cc7c569786f8eda551cc8e73abb75
|
|
| BLAKE2b-256 |
be3b5411f39feba77d107924e00b36527cc6600b91035d4e95c948c4e38b90ea
|