Metadata-Version: 2.4
Name: chrono_courier
Version: 1.0.2
Summary: A priority-based notification system for routing alerts and reports to Telegram and email.
Author-email: Mhd Zeid Mahfouz <mhd.zeid.mahfouz@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Zeid-M/chrono_courier
Project-URL: Issues, https://github.com/Zeid-M/chrono_courier/issues
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Flask==3.0.3
Requires-Dist: requests==2.32.3
Requires-Dist: dynaconf==3.2.4
Requires-Dist: Werkzeug==3.0.3
Requires-Dist: attrs==23.2.0
Requires-Dist: z-omni-logger==1.3.0
Requires-Dist: gunicorn==23.0.0
Dynamic: license-file

# ChronoCourier

A priority-based notification system for routing alerts and reports to Telegram and email.

## Description

ChronoCourier is a Flask-based notification service that receives alerts and reports over HTTP, validates and queues them, determines their configured destinations, and delivers them through Telegram and email.

Notifications are processed through priority queues so higher-priority tasks are handled first. Failed deliveries are moved to a separate retry flow, where they are delayed and retried without blocking newly received notifications. Each retry increases the task's priority value until the configured retry limit is reached.

## Features

- HTTP API for submitting alerts and reports
- API-key authentication and request validation
- Priority-based task processing
- Separate processing and retry queues
- Configurable retry delay and retry limit
- Telegram topic routing based on log type and message content
- Email routing based on report subject
- Support for email attachments
- JSON-aware formatting for alert messages
- Telegram MarkdownV2 formatting
- Queue monitoring through an HTTP endpoint
- Queue clearing endpoints for operational use
- Runtime configuration reload with validation and rollback
- Health-check endpoint
- Docker and Docker Compose support
- Development SMTP environment using MailHog and stunnel
- Configurable settings through Dynaconf
- Structured application logging through [OmniLogger](https://github.com/Zeid-M/omni_logger)

## Architecture

ChronoCourier uses three priority queues:

- **Processing Queue** — holds newly received alerts and reports.
- **Failure Queue** — stores tasks that failed delivery and are waiting for their retry time.
- **Failure Processing Queue** — holds retry tasks while they are being processed by the lazy worker.

Two background workers handle these queues:

- **Active Queue Worker** continuously processes newly received tasks.
- **Lazy Queue Worker** periodically moves retryable tasks into the failure-processing queue and processes them in batches.

For each task, ChronoCourier determines the configured Telegram and email destinations and attempts delivery independently. When delivery fails, the task is placed in the failure queue with a future retry timestamp. The retry count is represented by the task's priority value and is increased on each retry until the configured limit is reached.

## API

The service listens on port `5030` by default.

### Submit an alert

```bash
curl -X POST http://localhost:5030/alert \
  -F "api-key=key" \
  -F "subject=Test alert" \
  -F "content=Something went wrong" \
  -F "log_type=ERROR"
```

Alerts require:

- `api-key`
- `subject`
- `content`
- `log_type`

Alerts receive the highest initial priority.

### Submit a report

```bash
curl -X POST http://localhost:5030/report \
  -F "api-key=key" \
  -F "subject=Test report" \
  -F "content=Report content"
```

Reports require:

- `api-key`
- `subject`
- `content`

Reports can also include file attachments.

### Health check

```bash
curl http://localhost:5030/health
```

### Queue sizes

```bash
curl http://localhost:5030/queue_size
```

Returns the current sizes of the processing, failure, and failure-processing queues.

### Reload configuration

```text
GET /reload_settings
GET /reload_settings?confirm=yes
```

The first request displays a confirmation page. The second reloads and validates the configuration. If validation fails, the previous configuration is restored.

### Clear a queue

```text
GET /clear_<queue_type>_queue
GET /clear_<queue_type>_queue?confirm=yes
```

Supported queue types are:

- `processing`
- `failure`
- `failure_processing`

The endpoint first displays a confirmation page and only clears the queue when `confirm=yes` is supplied.

## Installation

ChronoCourier requires Python `3.11` or newer.

Install the latest released version from PyPI:

```bash
pip install chrono-courier
```

The package provides the `chrono_courier` command:

```bash
chrono_courier
```

Configuration must be available and valid before starting the service.

## Docker

ChronoCourier is available as a Docker image through GitHub Container Registry.

### Production image

Run with Docker Compose

The production Docker Compose configuration uses the published ChronoCourier image.

```bash
cd docker
docker compose up -d
```

ChronoCourier is available at:

```text
http://localhost:5030
```

> The container requires a valid ChronoCourier configuration. Configure the required environment variables or mount the appropriate configuration files before starting it.

### Development environment

The repository includes a Docker Compose environment for local development and integration testing.

The development environment starts:

- ChronoCourier
- MailHog
- stunnel

The MailHog + stunnel setup provides a local SMTP environment for testing TLS email delivery without using a real mail server.

Start the development environment with:

```bash
cd docker
docker compose -f docker-compose.dev.yaml up --build
```

ChronoCourier is available at:

```text
http://localhost:5030
```

MailHog's web interface is available at:

```text
http://localhost:8025
```

The development stunnel configuration exposes SMTP-over-TLS on ports `465` and `587`.

The certificates under `docker/stunnel/certs/` are intentionally self-signed test certificates and must never be used in production.

## Configuration

ChronoCourier uses [Dynaconf](https://www.dynaconf.com/) for application configuration.

The configuration covers:

- Flask host, port, API key, and debug mode
- Queue retry count and retry delay
- Lazy worker sleep interval
- SMTP server and sender credentials
- Email recipients and routing rules
- Telegram bot token and message limits
- Telegram topic IDs and routing rules

Example configuration files are provided under:

```text
src/chrono_courier/config/
```

Replace the example credentials and destination values before using ChronoCourier outside a local test environment.

## Development

A development Docker environment is provided to simplify local development and integration testing.

The repository also includes a request helper at:

```text
src/chrono_courier/helpers_scripts/send_request.py
```

which demonstrates how to submit alerts and reports to the service.

## License

ChronoCourier is licensed under the [MIT License](LICENSE).
