No description
  • Python 97.2%
  • Dockerfile 1.9%
  • Nix 0.9%
Find a file
xAndy b9666098b1
All checks were successful
Renovate / renovate (push) Successful in 8s
chore: enable Renovate automerge
2026-02-27 21:50:47 +00:00
.forgejo/workflows chore(deps): update https://github.com/renovatebot/github-action action to v46.1.2 2026-02-26 16:42:42 +00:00
src/mail2tg feat: add option to send Telegram messages silently 2026-02-22 17:38:39 +00:00
tests fix: use BODY.PEEK to prevent marking IMAP messages as read 2026-02-22 14:42:55 +00:00
.dockerignore initial POC 2026-02-16 14:31:01 +00:00
.env.example infrastructure: add CI/CD, IMAP security options, and dev tools 2026-02-16 22:47:10 +00:00
.gitignore fix: improve email header decoding, HTML stripping, and encoding handling 2026-02-17 23:46:18 +00:00
.python-version initial POC 2026-02-16 14:31:01 +00:00
AGENTS.md docs: update docs for spam detection, state file rename, and new settings 2026-02-21 10:43:05 +00:00
Dockerfile fix: redeclare ARGs after FROM in Dockerfile for multi-stage build 2026-02-22 14:11:21 +00:00
flake.lock initial POC 2026-02-16 14:31:01 +00:00
flake.nix style: apply ruff linting and formatting and add ruff to flake.nix 2026-02-17 13:20:52 +00:00
pyproject.toml Performance and code quality improvements 2026-02-20 13:54:46 +00:00
README.md feat: add option to send Telegram messages silently 2026-02-22 17:38:39 +00:00
renovate.json chore: enable Renovate automerge 2026-02-27 21:50:47 +00:00
uv.lock Performance and code quality improvements 2026-02-20 13:54:46 +00:00

mail2tg

Forward IMAP emails to Telegram.

Docker Usage

Run the Container

To run the container with persistence for the seen UIDs, create a .env file and run:

docker pull git.broken.equipment/xandy/mail2tg:latest && \
docker run -d \
  --name mail2tg \
  --env-file .env \
  -v $(pwd)/state.json:/app/state.json \
  git.broken.equipment/xandy/mail2tg:latest

Testing with Dev Image

For testing the latest development build:

docker run -d \
  --name mail2tg \
  --env-file .env \
  -v $(pwd)/state.json:/app/state.json \
  git.broken.equipment/xandy/mail2tg:dev

Example .env File

IMAP_HOST=imap.example.com
IMAP_PORT=993
IMAP_USER=user@example.com
IMAP_PASSWORD=password
IMAP_FOLDER=INBOX
IMAP_SECURITY=ssl
TELEGRAM_TOKEN=your_bot_token
TELEGRAM_CHAT_ID=your_chat_id
CHECK_INTERVAL=60
STATE_FILE=state.json
TIMEZONE=Europe/Berlin

Environment Variables

Variable Description Default
IMAP_HOST IMAP server hostname (Required)
IMAP_PORT IMAP server port 993
IMAP_USER IMAP username (Required)
IMAP_PASSWORD IMAP password (Required)
IMAP_FOLDER IMAP folder to monitor INBOX
IMAP_SECURITY IMAP security (ssl, none) ssl
TELEGRAM_TOKEN Telegram Bot API Token (Required)
TELEGRAM_CHAT_ID Telegram Chat ID (Required)
TELEGRAM_SILENT Send messages without notification False
CHECK_INTERVAL Polling interval in seconds 60
STATE_FILE Path to the UID state file state.json
TIMEZONE Timezone for email parsing Europe/Berlin
SUMMARY Show summary instead of full email text True
SUMMARY_LENGTH Length of summary (characters) 200
LLM_SPAM_DETECTION Enable LLM-based spam detection False
LLM_PROVIDER_URL LLM provider API URL (Required if spam detection enabled)
LLM_MODEL LLM model name (Required if spam detection enabled)
LLM_API_KEY LLM provider API key (Required if spam detection enabled)
LLM_SPAM_THRESHOLD Skip emails with score >= threshold 80
LLM_RETRY_DELAY Delay before retrying failed LLM requests (seconds) 60
LLM_PROMPT_TEMPLATE_PATH Path to custom prompt template (uses default)

LLM Spam Detection

mail2tg can use an LLM to detect spam emails and skip sending them to Telegram.

How It Works

When enabled, each new email is analyzed by the LLM which returns a spam score from 0 (not spam) to 100 (definitely spam). If the score meets or exceeds the threshold, the email is skipped.

Example .env Configuration

LLM_SPAM_DETECTION=true
LLM_PROVIDER_URL=https://api.openai.com/v1
LLM_MODEL=gpt-4o-mini
LLM_API_KEY=your_api_key
LLM_SPAM_THRESHOLD=80

Custom Prompt Template

You can provide a custom prompt template by setting LLM_PROMPT_TEMPLATE_PATH to a file path. The template supports these placeholders:

  • {sender} - Email sender
  • {subject} - Email subject
  • {date} - Email date
  • {headers} - Email headers
  • {envelope_from} - Envelope from address
  • {body} - Email body (truncated to 5000 chars)

The default template instructs the LLM to use the set_spamscore tool to return a score.

Getting Telegram API Details

  1. Bot Token:

    • Message @BotFather on Telegram.
    • Use the /newbot command and follow the instructions.
    • You will receive an API token (e.g., 123456789:ABCdefGHIjklMNOpqrsTUVwxyZ).
  2. Chat ID:

    • Start a chat with your new bot or add it to a group.
    • Send a message to the bot/group.
    • Use a bot like @GetIDsBot or visit https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates to find the id field in the JSON response.
    • Note: Group IDs usually start with a hyphen (e.g., -100123456789).

Persistence

The STATE_FILE stores the last 100 seen email UIDs to prevent duplicate notifications and handle moved emails. Ensure this file is mounted as a volume to keep track of seen emails across container restarts. The default state file is state.json (JSON format).

Development

Running Tests

Tests require environment variables. Run with:

IMAP_HOST=localhost IMAP_USER=user IMAP_PASSWORD=pass TELEGRAM_TOKEN=token TELEGRAM_CHAT_ID=id uv run pytest

Or with nix: nix develop --command pytest