Skip to content

fire0clop/mail-ops-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mail-Ops Bot

Mail-Ops Bot

Email → ticket → Telegram support-desk automation.

Python 3.11+ IMAP IDLE Telegram Bot API matplotlib License: MIT

Portfolio demonstration — a clean, generic reimplementation of a support-desk automation I built for a client. It contains no client data: every mailbox, address, and token here is a placeholder (example.com, CHANGE_ME). Bring your own configuration via .env.

Overview

Mail-Ops Bot watches one or more IMAP mailboxes in near-real-time, turns inbound mail into tickets, tracks first-response SLA against your business hours, and posts events to a Telegram chat. It also produces a daily PDF dashboard. It is deliberately dependency-light and runs as a single long-lived process.

Features

  • Multi-account IMAP ingestion — connect to several mailboxes at once, each on its own worker thread.
  • Near-real-time delivery via IMAP IDLE — react to new mail without polling; re-issue IDLE before servers time out; reconnect with backoff.
  • Per-account UID cursors — durable, resumable, and reset automatically when the server's UIDVALIDITY changes.
  • MIME parsing — decode encoded headers/bodies, normalize Re:/Fwd: subjects, extract reply targets and @mentions, thread by normalized subject and References.
  • Ticket state machine — open/answer/close transitions, first-response-time tracking, Sent-folder watching to auto-mark answered, and JSON persistence with a forward-only schema-migration helper.
  • Work-hours / SLA gating — SLA timers only advance during configured business hours and workdays; compute the next working moment; escalate overdue tickets.
  • Telegram notifications — new-ticket, SLA-breach, and daily-summary messages plus the PDF as a document.
  • PDF dashboard — daily tickets opened/closed, average response time, and a per-mailbox breakdown rendered with matplotlib.
  • Clean concurrency — one worker per account + a maintenance worker, with signal-driven graceful shutdown.

Architecture

flowchart LR
    subgraph Mailboxes
        M1[(support@example.com)]
        M2[(billing@example.com)]
    end

    M1 -->|IMAP IDLE| W1[AccountWorker]
    M2 -->|IMAP IDLE| W2[AccountWorker]

    W1 --> P[MIME parse]
    W2 --> P
    P --> TS[(TicketStore\nJSON state)]

    TS --> SLA[SLA engine\nwork-hours + maintenance]
    SLA -->|new / overdue / summary| TG[[Telegram Bot API]]
    SLA -->|daily| PDF[[matplotlib PDF]]
    PDF --> TG
Loading

See docs/architecture.md for the component and concurrency notes.

Tech stack

Area Choice
Language Python 3.11+ (type hints, dataclasses, zoneinfo)
Mail imaplib + ssl with the certifi CA bundle, RFC 2177 IDLE
Notifications Telegram Bot API via requests
Reporting matplotlib (headless Agg backend)
Config python-dotenv + environment variables
Persistence Atomic JSON files (no external database)

Project structure

mail-ops-bot/
├── README.md
├── LICENSE
├── .gitignore
├── .env.example
├── requirements.txt
├── config.py               # env-driven settings (dataclasses)
├── mailops/
│   ├── __init__.py
│   ├── __main__.py         # entrypoint: spins up workers
│   ├── imap_client.py      # connect, select, IDLE reader, fetch
│   ├── mime.py             # decode headers, normalize subject, mentions
│   ├── tickets.py          # Ticket + TicketStore (JSON + migration)
│   ├── workhours.py        # is_workday, next_work_time, SLA helpers
│   ├── telegram.py         # Telegram Bot API client
│   ├── dashboard.py        # matplotlib PDF report
│   └── state.py            # atomic JSON state with dirty-tracking
└── docs/
    └── architecture.md

Getting started

# 1. Install dependencies (use a virtualenv)
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

# 2. Create your configuration from the template
cp .env.example .env
#    …then edit .env: set your IMAP accounts, Telegram token/chat, work hours.

# 3. Run the service
python -m mailops

The process runs until interrupted (Ctrl+C), flushing state on shutdown. State files are written under MAILOPS_STATE_DIR and PDFs under MAILOPS_REPORT_DIR (both gitignored).

Configuration

All configuration is environment-driven. See .env.example for the full annotated template.

Variable Description Example
MAILOPS_ACCOUNTS JSON array of IMAP accounts (host, port, username, password, inbox, sent). [{"name":"support","host":"imap.example.com",…}]
MAILOPS_ACCOUNT_N_* Numbered fallback vars when MAILOPS_ACCOUNTS is unset. MAILOPS_ACCOUNT_1_HOST=imap.example.com
TELEGRAM_BOT_TOKEN Bot token from @BotFather. CHANGE_ME
TELEGRAM_CHAT_ID Destination chat/channel id. CHANGE_ME
TELEGRAM_ENABLED Set false for a dry run (no messages sent). true
WORKHOURS_TIMEZONE IANA timezone for SLA math. Europe/Berlin
WORKHOURS_START / WORKHOURS_END Daily business-hours window (HH:MM). 09:00 / 18:00
WORKHOURS_WORKDAYS ISO weekdays that count (Mon=1…Sun=7). 1,2,3,4,5
SLA_FIRST_RESPONSE_MINUTES First-response SLA in business minutes. 120
TICKET_AUTO_CLOSE_HOURS Auto-close answered tickets after N business hours idle. 48
TICKET_RETENTION_DAYS Purge closed tickets after N days. 30
IMAP_IDLE_TIMEOUT_SECONDS Re-issue IDLE before the server drops it. 1500
MAINTENANCE_INTERVAL_SECONDS Maintenance loop cadence. 300
MAILOPS_STATE_DIR / MAILOPS_REPORT_DIR Output directories. ./state / ./reports
LOG_LEVEL DEBUG / INFO / WARNING / ERROR. INFO

License

MIT © 2026 Egor Fomenko

About

Multi-account IMAP IDLE support-desk automation — email → tickets → SLA tracking → Telegram alerts + PDF reports

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages