A lightweight Go daemon that monitors an IMAP mailbox, processes unread emails with external programs, and automatically marks them as read on success.
imapproc connects to an IMAP server (e.g., Gmail), watches for new messages using IMAP IDLE, and invokes a custom executable for each unread email. The raw RFC 2822 message is piped to your program's stdin. If the program exits successfully (code 0), the email is marked as read (or deleted, if configured).
This project was built using AI tools, but was closely monitored and tested throughout development. All commits by AI agents are clearly marked with the agent's name in the commit message. Significant effort has been invested in unit testing, integration testing, and manual testing to ensure code quality and reliability. This codebase was built for personal use and will be used to process and access personal emails and Gmail account data. I trust this code with my email infrastructure and personal data.
- Process incoming emails with custom logic
- Integrate with email workflows and automation systems
- Build email-to-action pipelines
make buildConfigure imapproc using either a YAML config file or command-line flags.
./imapproc.yaml~/.imapproc.yaml/etc/imapproc/config.yaml
addr: imap.gmail.com:993
user: you@gmail.com
pass: your-app-password
mailbox: INBOX
exec: /usr/local/bin/process-email
# Action after successful processing: "seen" (default), "delete", or "move"
on_success: seen
# Process all unread messages once and exit without entering IMAP IDLE.
# Useful for cron-style one-shot invocations.
once: false--config string Path to config file
--addr string IMAP server address (e.g. imap.gmail.com:993)
--user string IMAP username
--pass string IMAP password
--mailbox string Mailbox to monitor (default: INBOX)
--exec string Program to run for each unread message
--on-success string Action on success: "seen" (default), "delete", or "move"
--on-success-target string Destination mailbox when --on-success=move (default: "Trash")
--once Process all unread messages once and exit (skip IDLE)
--idle-refresh-interval duration How often to refresh IMAP IDLE (default: 25m)
--reconnect Reconnect automatically when the connection is lost
--reconnect-initial-delay dur Initial backoff delay before first reconnect (default: 5s)
--reconnect-max-delay duration Maximum backoff delay between reconnects (default: 5m)
--web-enabled Enable the HTTP monitoring server
--web-addr string Listen address for the monitoring server (default: :8080)
--instance-name string Optional instance name shown in /api/health (default: "")
CLI flags override config file values. Positional arguments override --exec:
the first positional argument is the program to run, and any additional
positional arguments are passed as arguments to that program.
See imapproc.example.yaml for all available options and their defaults.
# Using a config file
imapproc
# Using CLI flags
imapproc --addr imap.gmail.com:993 --user me@gmail.com --pass mypass --mailbox INBOX /path/to/processor
# Using positional program argument
imapproc /usr/local/bin/process-email arg1 arg2
# One-shot: process current unread messages and exit (no IDLE loop)
imapproc --once- Connects to the IMAP server and authenticates
- Searches for all unread messages in the specified mailbox
- For each unread message, pipes the raw RFC 2822 content to your program
- On success (exit code 0), performs the configured
on_successaction (seen: marks as read;delete: expunges the message;move: moves to target mailbox) - If
onceis set, exits after the first pass without entering IDLE - Otherwise, uses IMAP IDLE to efficiently wait for new messages
- Continues until interrupted (Ctrl-C or SIGTERM)
- Go 1.25+ (for building)
- IMAP server access
- For Gmail: app-specific password
- Config file permissions — the config file contains your IMAP password in plain text. Restrict access:
chmod 600 imapproc.yaml. - CLI password flag — passing
--passon the command line exposes the password in the process list (ps aux). Prefer using a config file. - Exec handler — the subprocess invoked via
execruns with the same privileges as the daemon. Only pointexecat scripts you trust. - TLS — connections to the IMAP server always use TLS; plain-text connections are not supported.
Enable the built-in HTTP server with --web-enabled (or web_enabled: true in the config file):
imapproc --web-enabled --web-addr :8080GET /api/health — JSON health endpoint suitable for uptime monitors and health checks.
- Returns HTTP 200 when healthy, HTTP 503 when unhealthy.
- Reports connection status (
UP/DOWN), the outcome of the last processing pass, and cumulative message counters.
{
"status": "UP",
"instance_name": "myinstance",
"details": {
"connection": { "status": "UP", "healthy": true },
"lastPoll": { "healthy": true, "timestamp": "2025-06-15T12:00:00Z",
"messagesReceived": 3, "messagesSuccess": 3, "messagesFailed": 0 }
},
"stats": { "messagesReceived": 42, "messagesSuccess": 41, "messagesFailed": 1 }
}GET / — HTML status dashboard that auto-refreshes every 5 seconds.
The scripts/ directory contains helper scripts designed to work with imapproc as exec handlers. These scripts read raw RFC 2822 emails from stdin and can be used to integrate imapproc with external systems and workflows.
make test