A microservice for sending notifications with cascading delivery logic (Telegram → Email → SMS). If the primary channel is unavailable or an error occurs, the system automatically switches to the backup.
- Failover System: Guaranteed message delivery, even if one of the providers is down.
- Asynchronous: Processing via Celery + Redis, API is not blocked.
- Scalability: Fully containerized (Docker Compose).
- Clean Architecture: Strategy pattern for channels, data validation.
- Service Layer: Sending logic has been moved from
views.pyto the service layer. - Strategy Pattern: Implementing channels (Email, SMS, TG) through a common interface allows for easy addition of new communication methods (WhatsApp, Push) without changing the core code.
- Atomic Transactions: Using
transaction.on_commitensures that the task is sent to Celery only after a successful commit to the database, preventing race conditions. - Graceful Degradation: The system continues to operate even if one of the external services is unavailable.
- Python 3.12 + Django 5 + DRF
- Celery + Redis
- PostgreSQL 15
- Docker & Docker Compose
.
├── failover_notify/ # Project Configuration
│ ├── celery.py # Celery and Redis Settings
│ └── settings.py # Basic Django Settings
│
├── notifications/ # Main Application
│ ├── services/ # Business Logic
│ │ ├── channels.py # Sending Channels
│ │ └── tasks.py # Asynchronous Task with Retry
│ ├── admin.py # Admin Customization
│ ├── models.py # Models
│ ├── serializers.py # API Validation
│ ├── tests.py # Tests
│ └── views.py # API controllers
│
├── docker-compose.yml # Orchestration
├── Dockerfile # Build instructions
├── Makefile # Command shortcuts
├── setup.py # Auto-deployment script
└── requirements.txt # Dependencies
I've prepared an automated installation script that will build containers, set up a database, and create test data.
git clone <https://github.com/EdvardFarrow/django-failover-notify.git>
cd django-failover-notifypython setup.pyFollow the on-screen instructions
# 1. Create .env (see .env.example)
# 2. Run Docker
docker compose up -d --build
# 3. Apply Migrations
docker compose exec web python manage.py migrateAfter running the setup.py script, a test user with ID=1 will already be created in the database. This user has no Telegram ID to demonstrate channel switching.
Send the request:
curl -X POST http://localhost:8000/api/send/ \
-H "Content-Type: application/json" \
-d '{
"recipient": 1,
"message": "Test message with channel switching",
"channels_chain": ["telegram", "email", "sms"]
}'
``
**Expected behavior (see logs):**
* Attempt to send to Telegram -> Error (no ID).
* Attempt to send to email -> Success (or error if the emulated failure was successful).
* Attempt to send via SMS -> Success (if email failed).
View worker logs:
```Bash
docker compose logs -f workerThe admin panel has a convenient dashboard for tracking statuses. Sending attempt logs (channel, status, error) are displayed Inline — right inside the notification card.
Access: http://localhost:8000/admin/
(Login/password are created during installation)
The project is covered with tests (API endpoints + mocks for Celery).
docker compose exec web python manage.py testSending statuses and channels are visible (mixed email/SMS/Telegram).

Demonstration of the algorithm: Telegram attempt (error) -> Email (network error) -> SMS (success).

