Skip to content

Repository files navigation

MailCatch 📬⚡

MailCatch — панель рассылок и прогрева

MailCatch — AI Ассистент

MailCatch — адаптивный предпросмотр письма

MailCatch — входящие письма и парсер OTP

MailCatch — высокопроизводительный автономный Catch-All почтовый сервер, парсер OTP-кодов и ссылок активации, а также движок массовых email-рассылок с автоматическим прогревом доменов (Warmup Engine) и встроенным AI-ассистентом на базе Python (FastAPI + aiosmtpd + SQLite WAL).

Python 3.10+ FastAPI License: MIT Database: SQLite WAL


🌟 Основные возможности

📥 1. Приём почты (Multi-Domain Catch-All SMTP)

  • Catch-All для неограниченного числа ящиков: сервер принимает входящие письма на любые адреса (*@yourdomain.com).
  • Защита от Open Relay: строгая проверка доменов назначения (550 5.7.1 Relaying denied).
  • Anti-Spoofing защита: блокировка внешних попыток подделки локальных адресов отправителя.
  • Ограничение DoS: лимит размера входящего письма (до 10 МБ).

🔍 2. Интеллектуальный парсинг OTP и ссылок активации

  • Многоуровневое распознавание кодов (OTP / PIN / Verification Code): точный поиск 4–8 значных кодов подтверждения.
  • Фильтрация ложных срабатываний: игнорирование номеров портов (8080, 3000), годов (1900-2099) и монотонных цифр (00000).
  • Поиск ссылок действий: автоматическое определение ссылок подтверждения аккаунта, верификации и сброса пароля (с фильтрацией ссылок отписки и соглашений).

🚀 3. Движок рассылок с адаптивным прогревом (Warmup Engine)

  • Интеллектуальный Warmup: плавное автоматическое увеличение скорости отправки по часам/дням для защиты репутации домена.
  • Human-like Delay Jitter: добавление случайной задержки между письмами для имитации естественной отправки.
  • Очередь повторных попыток (Retry Queue): классификация ошибок (4xx temporary vs 5xx permanent) с длинным экспоненциальным backoff (15 мин / 1 ч / 4 ч) — крупные шлюзы (Mimecast, Google, Microsoft) успевают снять троттлинг между попытками.
  • Распознавание «фактически постоянных» 4xx: Cloudflare 452 suppression и стабильные 454 Relay access denied не повторяются по 3 раза.
  • Шаблонизация: подстановка тегов {{EMAIL}}, {{NAME}}, {{HOOK}} и {{UNSUB_URL}} в текст и тему письма.

🔐 4. Доставляемость, DKIM и защита репутации

  • Прямая доставка по MX: автоматический поиск MX-серверов получателя с поддержкой RFC 5321 Fallback на A-записи.
  • Принудительный IPv4: исключение проблем с доставкой из-за неаутентифицированных IPv6-маршрутов.
  • Автоматическая DKIM RSA-2048 подпись: подписание исходящих писем приватным ключом, канонизация relaxed/relaxed (устойчива к нормализации писем промежуточными шлюзами).
  • Шифрование Opportunistic TLS (STARTTLS): сначала попытка с верификацией сертификата, при его проблемах — повтор без верификации, в крайнем случае — plaintext (статус транспорта логируется по каждому письму).
  • Трекинг открытий: генерация невидимого пикселя 1x1 (/t/{token}.png).
  • RFC 8058 One-Click Unsubscribe: заголовки List-Unsubscribe и List-Unsubscribe-Post для Gmail / Yahoo (ровно по одному на письмо). Ссылка в теле ведёт на страницу подтверждения: сама отписка выполняется только по кнопке/POST — префетчеры корпоративных сканеров ссылок не могут отписать получателя за него. Отписка действует глобально на все кампании.
  • Защита от инъекций в заголовки: тема/адреса/кастомные заголовки очищаются от CR/LF, не-ASCII темы кодируются по RFC 2047.
  • DNS-предпроверка при старте рассылки: фоновая проверка доменов получателей — исключаются только мёртвые домены (NXDOMAIN/NoNameservers); домены без MX, но с A-записью остаются отправителю (RFC 5321 §5.1 fallback).
  • Автоподавление жёстких отскоков: только отказы уровня получателя (5xx на RCPT, мёртвый домен) попадают в глобальный стоп-лист; сбои уровня отправителя (блоклисты, отказ в MAIL FROM, контент-фильтры) адрес не подавляют. Асинхронные NDN-баунсы, пришедшие на catch-all, тоже гасят адрес.
  • Краезащитная отправка без дублей: атомарный «клейм» получателя (sending) исключает двойную отправку при нескольких воркерах; зависшие после краха записи возвращаются в очередь при старте.
  • A/B-тестирование тем и текста: детерминированное деление аудитории и автоматический выбор победителя по open rate.

🤖 5. AI-ассистент (OpenAI-совместимый LLM, напр. Qwen)

  • Классификация входящих ответов: интерес / вопрос / отказ / отписка / баунс / прочее, с уверенностью и кратким резюме.
  • Авто-отписка по CAN-SPAM: запросы отписки обрабатываются мгновенно, адрес попадает в стоп-лист. При уверенности модели ниже 0.8 запрос сохраняется для ручного подтверждения, а не гасится автоматически.
  • Обработка NDN-баунсов: асинхронные отчёты о недоставке подавляют адрес-получателя (только из собственных кампаний — защита от поддельных NDN).
  • Черновики ответов лидам: сдержанный B2B-тон, язык ответа = язык входящего письма, отправка в один клик.
  • QA-гейт шаблонов: проверка письма на спам-триггеры, CAN-SPAM (почтовый адрес, отписка) и качество темы перед запуском.
  • Персонализация {{HOOK}}: AI-обогащение доменов получателей (краткая персональная подводка на основе сайта компании).

🗂 6. Менеджеры шаблонов и баз контактов

  • Шаблоны писем: сохранение, повторное использование, счётчик использований, адаптивный предпросмотр Desktop/Mobile с подстановкой тегов.
  • Базы контактов: сохранение списков получателей, повторное использование в новых рассылках, экспорт в TXT.
  • Стоп-лист: отписки, жёсткие отскоки и вручную исключённые адреса — автоматически вычитаются из любых новых рассылок.

💻 7. Веб-интерфейс и REST API

  • Современная темная панель управления (HTML5, CSS3, Jinja2, Vanilla JS).
  • Поддержка авторизации через HTTP Basic Auth и API Key (X-API-Key или ?api_key=...).
  • Встроенный Swagger UI (/docs) и ReDoc (/redoc) с возможностью работы в изолированной сети (offline assets).
  • Защита от брутфорса паролей и API-ключей (Rate Limiter с блокировкой IP).

🏗 Архитектура

mailcatch/
├── main.py                  # Точка входа (SMTP + FastAPI + фоновые воркеры)
├── mailcatch/
│   ├── web.py               # FastAPI веб-сервер, REST API и веб-панель
│   ├── smtp.py              # SMTP Catch-All сервер (aiosmtpd)
│   ├── parser.py            # Парсер MIME-сообщений, извлечение OTP и ссылок
│   ├── database.py          # SQLite WAL база данных и CRUD операции
│   ├── config.py            # Загрузка .env и глобальная конфигурация
│   ├── ai.py                # LLM-клиент: классификация, QA-гейт, {{HOOK}}, черновики
│   └── workers/
│       ├── sender.py        # Прямая отправка по MX + DKIM + Opportunistic TLS
│       ├── campaign_worker.py  # Воркер рассылок с Warmup, ретраями и отпиской
│       └── ai_worker.py     # Воркер AI: классификация, авто-отписка, обогащение
├── templates/               # Jinja2 HTML-шаблоны панели управления
├── static/                  # Статические файлы (CSS, JS, Swagger UI assets)
├── tests/                   # Функциональные тесты (изолированная БД в /tmp)
├── data/                    # Хранилище (БД SQLite, приватные ключи DKIM) - ИГНОРИРУЕТСЯ В GIT
├── requirements.txt         # Python-зависимости
├── Dockerfile               # Контейнеризация
├── docker-compose.yml       # Быстрый запуск в Docker
└── .env.example             # Шаблон конфигурации окружения

🚀 Быстрый старт

Вариант 1: Запуск через Docker Compose (Рекомендуется)

  1. Клонируйте репозиторий:

    git clone https://github.com/your-user/mailcatch.git
    cd mailcatch
  2. Создайте файл конфигурации .env:

    cp .env.example .env
    nano .env
  3. Сгенерируйте DKIM-ключи:

    mkdir -p data
    openssl genrsa -out data/dkim.private 2048
    openssl rsa -in data/dkim.private -pubout -out data/dkim.public
    chmod 600 data/dkim.private
  4. Запустите стек:

    docker-compose up -d

Вариант 2: Локальная установка / Сервер Ubuntu/Debian

  1. Системные зависимости:

    sudo apt update
    sudo apt install -y python3 python3-pip python3-venv openssl
  2. Создание виртуального окружения:

    cd /opt/mailcatch
    python3 -m venv venv
    source venv/bin/activate
    pip install -r requirements.txt
  3. Генерация DKIM-ключей:

    mkdir -p data
    openssl genrsa -out data/dkim.private 2048
    openssl rsa -in data/dkim.private -pubout -out data/dkim.public
    chmod 600 data/dkim.private
  4. Настройка конфигурации:

    cp .env.example .env
    nano .env
  5. Запуск:

    # Для приёма входящих писем на 25 порт требуются права root/sudo
    sudo /opt/mailcatch/venv/bin/python3 main.py

⚙️ Переменные окружения (.env)

Переменная По умолчанию Описание
MAILCATCH_USER admin Логин администратора для Web UI / Basic Auth
MAILCATCH_PASSWORD change_this_password Пароль администратора. С дефолтным значением приложение не стартует
MAILCATCH_API_KEY change_this_api_key Секретный ключ для доступа к REST API. С дефолтным значением приложение не стартует
MAILCATCH_ALLOW_INSECURE_DEFAULTS =1 — разрешить старт с дефолтными секретами (только для разработки)
CONFIGURED_DOMAINS example.com Список обслуживаемых доменов через запятую
PRIMARY_DOMAIN example.com Основной домен по умолчанию
TRACKING_BASE_URL http://127.0.0.1:8080 Публичный HTTPS URL для пикселей трекинга и отписки
SMTP_HOST 0.0.0.0 IP-адрес для прослушивания входящего SMTP
SMTP_PORT 25 Порт входящего SMTP сервера
WEB_HOST 127.0.0.1 IP-адрес для прослушивания Web UI / REST API
WEB_PORT 8080 Порт Web UI / REST API
TRUSTED_LOCAL_IPS 127.0.0.1,::1 Доверенные IP-адреса для Anti-Spoofing исключений
TRUSTED_PROXY_IPS 127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 Reverse-прокси, которым разрешено передавать заголовки клиентского IP (только от этих адресов читаются CF-Connecting-IP / X-Forwarded-For)
DKIM_SELECTOR mail Селектор DKIM-записи (например, mail._domainkey)
AI_ENABLED true Включение AI-ассистента (классификация, QA, {{HOOK}}, черновики)
DASHSCOPE_API_KEY API-ключ OpenAI-совместимого LLM-эндпоинта (Qwen / DashScope)
QWEN_BASE_URL https://dashscope.aliyuncs.com/compatible-mode/v1 Базовый URL LLM-эндпоинта
QWEN_MODEL qwen3.6-flash Модель для AI-функций
AI_DRAFT_CONTACTS Контактные данные, которые AI предлагает в черновиках ответов (необязательно)

🌐 Настройка DNS записей для доменов

Для обеспечения 100% доставляемости и валидной проверки SPF, DKIM и DMARC настройте DNS записи вашего домена (например, example.com, сервер с IP 1.2.3.4):

1. A-запись почтового хоста

mail.example.com.    IN    A    1.2.3.4

2. MX-запись (Приём входящей почты)

example.com.         IN    MX   10 mail.example.com.

3. SPF-запись (Разрешение отправки)

example.com.         IN    TXT  "v=spf1 ip4:1.2.3.4 ~all"

4. DKIM-запись (Цифровая подпись)

Получите публичный ключ:

grep -v '^-' data/dkim.public | tr -d '\n'

Создайте TXT запись с селектором mail:

mail._domainkey.example.com.  IN  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."

5. DMARC-запись (Политика подлинности)

_dmarc.example.com.  IN    TXT  "v=DMARC1; p=none; sp=none; rua=mailto:postmaster@example.com"

6. Reverse DNS (PTR)

У вашего VPS-провайдера установите PTR-запись для IP 1.2.3.4 -> mail.example.com.


🔌 Примеры использования REST API

1. Получение последнего OTP-кода (для автотестов и ботов)

curl -s "http://127.0.0.1:8080/api/messages/latest_code?to=user1@example.com" \
  -H "X-API-Key: your_api_key_here"

Ответ JSON:

{
  "status": "success",
  "data": {
    "id": 142,
    "recipient": "user1@example.com",
    "sender": "noreply@service.com",
    "subject": "Код подтверждения: 839104",
    "otp_code": "839104",
    "action_link": "https://service.com/verify?token=abc123xyz",
    "created_at": "2026-08-21 14:30:00"
  }
}

2. Одиночная отправка письма с DKIM

curl -X POST "http://127.0.0.1:8080/api/send" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "to_email": "client@gmail.com",
    "from_email": "support@example.com",
    "subject": "Тестовое сообщение с DKIM",
    "body_text": "Привет! Письмо отправлено и подписано через MailCatch.",
    "body_html": "<p>Привет! Письмо отправлено и подписано через <b>MailCatch</b>.</p>"
  }'

3. Создание массовой рассылки с прогревом (Warmup)

curl -X POST "http://127.0.0.1:8080/api/campaigns" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Прогрев домена #1",
    "from_email": "hello@example.com",
    "subject": "Здравствуйте, {{NAME}}!",
    "body_text": "Привет, {{NAME}}! Это проверка рассылки для {{EMAIL}}.",
    "body_html": "<p>Привет, <b>{{NAME}}</b>!</p>",
    "recipients": ["lead1@gmail.com", "lead2@yahoo.com"],
    "warmup_initial_rate": 5,
    "warmup_interval_minutes": 30,
    "warmup_ramp_step": 2,
    "warmup_ramp_interval_hours": 6,
    "delay_seconds_min": 15,
    "delay_seconds_max": 45
  }'

4. AI: QA-проверка шаблона перед запуском

curl -X POST "http://127.0.0.1:8080/api/ai/qa" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"subject": "Quick intro", "body_text": "Hello! ..."}'

5. AI: отправка сгенерированного черновика ответа

curl -X POST "http://127.0.0.1:8080/api/ai/inbound/42/send-reply" \
  -H "X-API-Key: your_api_key_here"

🔒 Безопасность

  • Не коммитьте директорию data/: она содержит базу данных с сообщениями и приватные RSA-ключи DKIM (.gitignore уже настроен).
  • Не коммитьте .env: используйте .env.example для шаблона.
  • Nginx Reverse Proxy: для публичного доступа к Web UI рекомендуется настроить проксирование через Nginx с Let's Encrypt SSL-сертификатом.

🧪 Тесты

python3 tests/test_message_build.py   # Сборка исходящих писем: заголовки, MIME, инъекции, RFC 2047
python3 tests/test_bounce_handling.py # Ошибки доставки, подавление, глобальная отписка, claim/NDN/гонки
python3 tests/test_ai.py              # AI-интеграция (изолированная БД, LLM выключен)
python3 tests/test_templates.py       # Шаблоны писем и их использование в кампаниях

📄 Лицензия

Проект распространяется под свободной лицензией MIT. Подробности в файле LICENSE.

About

A high-performance Catch-All SMTP server with │ automated OTP parsing, built-in REST API, and │ a Web UI for multi-domain mail management.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages