email-to-print logo

email-to-print

Email a PDF to your printer. Self-hosted, no vendor cloud.

Developer ToolsSelf-HostedPythonMIT 117 5Health 73
GitHub

What is it?

What it is

A lightweight Python script that watches an IMAP folder for e‑mail attachments, checks the sender against an allowlist, converts non‑PDF files to PDF with LibreOffice, and hands printable files to CUPS for printing.

Why it exists

It provides a privacy‑first, self‑hosted alternative to vendor cloud print services, allowing a family to print documents via e‑mail without exposing data to third‑party servers or relying on printer firmware.

Who should use it

Home users, families, or small offices who want a simple, self-hosted way to print email attachments without relying on cloud print services, and are comfortable with basic Docker and Linux setup.

Who should avoid it

Enterprises or environments requiring strong security, advanced authentication, audit trails, or high-volume printing; users unwilling to run Docker or manage CUPS.

How it works

A quick walkthrough in plain English

How email-to-print works

Step 1 of 3

You interact with it

Open email-to-print, send a request, or connect it to your stack.

Features

IMAP mailbox polling
Sender allowlist validation
Automatic file conversion via LibreOffice (Word/Excel to PDF)
Email body rendering for text-based emails
CUPS integration for local printing
ProtonMail Bridge support via Docker
Size limits for attachments
Status confirmation emails for allowlisted senders
Health check endpoint
SPF/DKIM authentication check option

Advantages

  • Privacy-focused: avoids vendor cloud print services
  • Hardware agnostic: works with any CUPS-compatible printer
  • Self-hosted: no dependency on third-party service longevity
  • Minimalist: uses Python standard library for core logic
  • Robustness: uses folder-based deduplication instead of a database

Disadvantages

  • Security risk: From headers can be spoofed without SPF/DKIM enforcement
  • Complexity: requires managing a Docker environment and CUPS
  • Potential for duplicate prints if the process crashes during execution
  • Conversion quality: LibreOffice conversion may produce poor formatting for complex documents

Installation

cloud

Not specified

docker

1. Get your printer working in CUPS on the Docker host first. 2. cp.env.example.env and fill it in. 3. Create the filter at your mail provider that routes PRINT_TO mail into a dedicated folder, and set SOURCE_FOLDER to it. 4. If you're on Proton: docker compose run --rm protonmail-bridge init once to log in interactively. 5. docker compose up -d --build 6. Send yourself a test with DRY_RUN=true first.

native

Not specified

compose

1. Get your printer working in CUPS on the Docker host first. 2. cp.env.example.env and fill it in. 3. Create the filter at your mail provider that routes PRINT_TO mail into a dedicated folder, and set SOURCE_FOLDER to it. 4. If you're on Proton: docker compose run --rm protonmail-bridge init once to log in interactively. 5. docker compose up -d --build 6. Send yourself a test with DRY_RUN=true first.

FAQ

How do I configure the script to work with Gmail instead of ProtonMail?

Skip the ProtonMail Bridge service, set IMAP_HOST=imap.gmail.com, IMAP_PORT=993, IMAP_SSL=true, TLS_VERIFY=true, and use an app password for authentication. Use an alias like you+print@gmail.com with a provider filter that routes mail to the folder specified by SOURCE_FOLDER.

What happens if the sender is not on the allowed list?

The message is moved to a rejected folder and, by default, no reply is sent to avoid backscatter. If you want a rejection notice, you would need to modify the script; the current design sends confirmations only to allowed senders.

How does the system prevent duplicate prints?

After processing a message (printing or rejecting), the script moves it out of the watched folder. Since the script only processes messages present in that folder, a message won’t be seen again unless the script crashes between printing and moving, which would result in at-most-once duplication—a risk the author accepts.

Can I enable SPF/DKIM authentication checks to tighten sender verification?

Yes. Set REQUIRE_AUTH_PASS=true in .env. The script will then require an SPF or DKIM pass in the Authentication-Results header; failures are treated like unknown senders (message moved to rejected folder, no confirmation).

How do I print duplex or use A4 paper instead of US Letter?

Set MEDIA=a4 for A4 paper. For duplex, add SIDES=two-sided-long-edge (or two-sided-short-edge) in .env; these values are passed directly to the lp command.

What is the purpose of the MAX_ATTACH_MB setting and how does it work?

MAX_ATTACH_MB limits the size of any single attachment in bytes to prevent accidental huge files (e.g., a 200 MB scan) from being printed. It does not limit page count, so a large‑page PDF will still print all pages if it passes the size check.

Loading documentation…
View on GitHub

Featured in Videos

YouTube tutorials and walkthroughs for email-to-print

Alternatives

Similar projects ranked by category, topics, and text overlap.

Compare
email-to-print | MushyBook