Polls a personal Outlook.com inbox and prints every new email's body + attachments on a wired Windows printer. Runs as a Scheduled Task on the office PC. Uses Microsoft Graph + delegated OAuth (PKCE — no client secret to manage).
- Download
mailpress-installer.zipfrom the latest GitHub Release (or the artifact of abuild on windowsworkflow run if no release is tagged yet). - Unzip it on the office PC, e.g. into
C:\mailpress\. You'll see:mailpress.exe ← double-click this print-files.ps1 ← PowerShell print helper (must sit next to the exe) INSTALL.txt ← step-by-step install guide - Double-click
mailpress.exe. The setup wizard runs on first launch:- picks the printer
- walks through the one-time Azure app registration
- runs the consent flow in your browser
- asks how often to check for new mail
- does a test print
- installs itself as a Scheduled Task
- Done. Send a test email to the office inbox and confirm it prints.
The one step Microsoft doesn't let an installer automate is creating the Azure app registration itself — the wizard prints the exact links and steps.
Useful if Node 18+ is already on the office PC.
git clone https://github.com/Turetsky/mailpress.git
cd mailpress
node cli.mjs # launches the wizard if no config
The Scheduled Task installed by the wizard will point at node cli.mjs
in this case, so the source tree has to stay where you cloned it.
mailpress # poll forever (or run wizard if not configured)
mailpress --setup # re-run the interactive setup wizard
mailpress --test # interactive: switch printer, test print any file
mailpress --once # process current unread and exit
mailpress --doctor # run health checks and report what's broken
mailpress --consent # just re-do the OAuth consent (token died)
mailpress --uninstall # remove the Scheduled Task
mailpress --help
--test opens an interactive menu where you can:
- print the mailpress test page
- print any file you specify (drop in a path to a .docx / .xlsx / .pdf to verify Word/Excel/PDF conversion works through the Print verb)
- switch the active printer (saves to config.local.json)
- change how often mailpress checks for new mail (30s — 15min, custom)
- send the test page to every installed printer at once
Useful when the printer changes, a driver flakes, or you just want to confirm the spool still works without sending real email.
mailpress polls Outlook every pollIntervalMs (default 5 min,
configurable in the wizard or via --test). Microsoft Graph supports
push via subscriptions (webhooks) and Outlook supports IMAP IDLE,
both giving ~5-second latency. They're not wired up because the extra
setup (a public HTTPS endpoint for webhooks, or a separate IMAP client
with reconnect logic) isn't worth the ~30-second improvement over a
1-minute poll for an office printer. The code that would change is
lib/poll.mjs — see the comment at the top of that file.
Exit codes:
0— success (or--oncecompleted)1— generic failure (seemailpress.log)2— fatal auth failure; re-runmailpress --consentor--setup
Set MAILPRESS_DEBUG=1 for verbose logs. Set MAILPRESS_HOME=<dir> to
override where config + token + logs live (defaults to the exe's folder).
The wizard writes a detailed log to mailpress-setup.log next to the
exe. The polling loop writes mailpress.log. Both are gitignored. If
something breaks, run mailpress --doctor first — it identifies which
subsystem failed (config, token, Graph API, printer presence, scheduled
task) and what to do about each.
Common cases:
- "refresh token failed / invalid_grant" — token expired or was
revoked. Run
mailpress --consent. - "printer not found" — the printer name changed in Windows. Run
mailpress --setupand pick it again. - "AADSTS50011: redirect URI does not match" — the redirect URI in
the Azure app registration doesn't match
http://localhost:8765. Edit the app's Authentication page to add that exact URI. - "AADSTS65001: consent_required" — the API permissions weren't added to the app registration. Add Mail.ReadWrite, Mail.Send, User.Read, and offline_access under API permissions and re-run setup.
- Refresh token missing on consent —
offline_accesspermission isn't included. Add it under API permissions.
node scripts/build.mjs
Produces dist/mailpress.exe (or dist/mailpress on non-Windows) using
Node's Single Executable Applications. Needs Node >= 20.12.
CI builds on every push and publishes the exe to GitHub Releases on
version tags (v*).
cli.mjs # entry point — arg parsing, routing, top-level catch
lib/
config.mjs # load/save/validate config.local.json
log.mjs # leveled console + file logger
prompt.mjs # readline wrapper + polling-interval picker
outlook.mjs # Microsoft Graph client + token refresh + HTML→text
oauth.mjs # interactive OAuth consent flow (PKCE, MS endpoints)
printer.mjs # Windows printer enumeration + printing + test print
task.mjs # Windows Scheduled Task install/uninstall
poll.mjs # main polling loop
doctor.mjs # diagnostic mode
wizard.mjs # first-run interactive setup
test.mjs # post-install test menu (--test)
print-files.ps1 # PowerShell helper: print one or more files
assets/
icon.svg # source icon (envelope on slant + speed lines)
icon.ico # multi-size .ico embedded into mailpress.exe
scripts/build.mjs # Node SEA build pipeline (icon embed via resedit)
.github/workflows/release.yml # CI builds + tag releases