7 KiB
| name | description | version | author | license | metadata | prerequisites | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| mail-auto-draft | Build and deploy a Himalaya-based inbound email auto-reply workflow with self-reply protection, Reply-To aware recipient selection, and systemd user timers. | 1.0.0 | jozrftamson | MIT |
|
|
Mail Auto-Draft with Himalaya
Build a practical local inbound email automation workflow that:
- reads new mail from INBOX via Himalaya
- classifies simple inbound requests
- automatically replies only to safe standard cases
- avoids self-reply loops
- runs continuously via systemd user timers
This skill is intentionally optional. It is highly useful for users who want mailbox automation, but it depends on local mail account setup, machine-specific deployment choices, and provider-specific operational details.
When to Use
Use this skill when the user wants to automate replies to inbound email on their own mailbox, especially on Ubuntu/Linux with Himalaya.
Typical requests:
- "Automatically answer simple incoming emails"
- "Set up a local email auto-responder with Gmail and Himalaya"
- "Keep it running in the background every minute"
- "Make it safe enough for production"
This skill is for user-owned mailboxes, not agent-owned inboxes like AgentMail.
Quick Reference
Typical flow:
- configure Himalaya for the mailbox
- create or adapt
process_inbox.pyandconfig.yaml - test in draft mode
- enable auto-send only for safe whitelisted categories
- run continuously with a
systemd --usertimer
Requirements
- Himalaya CLI installed
- Python 3 with
pyyamlandrequests - A working IMAP/SMTP account in
~/.config/himalaya/config.toml - A local project directory containing:
process_inbox.pyconfig.yamlprompts/system_prompt.txtprompts/user_prompt.txt
Recommended Project Files
Minimum structure:
process_inbox.pyconfig.yamlconfig.example.yamlREADME.mdSCHNELLSTART_AND_INSTALLATION.mddeploy/systemd/mail-auto-draft.servicedeploy/systemd/mail-auto-draft.timerprompts/
Local runtime dirs:
drafts/logs/data/runtime/
Safe Defaults
For production, prefer:
require_unseen: truerequire_new_in_inbox: truerequire_whitelist: truerequire_high_confidence: trueconfidence_thresholdaround70to85forbid_sensitive_categoriesincludes:sensibelindividuellunklarignorieren
Critical Safety Rules
1. Always define own addresses
In config.yaml:
own_addresses:
- your-address@example.com
This prevents self-reply loops when your own replies appear in INBOX.
2. Prefer Reply-To over From
When selecting the reply recipient:
- use
Reply-Toif present - otherwise use
From - if the generated reply template has empty
To:, backfill it before sending
3. Ignore own-sender mail
Any inbound mail whose sender matches own_addresses should be ignored with a reason like self_sender.
4. Do not auto-send uncertain categories
Keep these as draft-only or blocked:
sensibelindividuellunklarignorieren
5. Treat Gmail Sent append failures carefully
On Gmail, SMTP may succeed while Himalaya still exits non-zero because append to Sent fails. If stderr includes both:
cannot add IMAP messageFolder doesn't exist
then treat it as likely sent and avoid duplicate resend.
Himalaya Config Notes
For Gmail, use an app password, not the normal password.
Recommended pattern:
- keep the app password out of the project repo
- store it in a local secret file such as:
~/.config/mail-auto-draft/secrets.env
Example local secret file:
GMAIL_APP_PASSWORD='YOUR_APP_PASSWORD'
Example auth command in ~/.config/himalaya/config.toml:
backend.auth.cmd = "sh -lc '. /home/USER/.config/mail-auto-draft/secrets.env && printf %s \"$GMAIL_APP_PASSWORD\"'"
message.send.backend.auth.cmd = "sh -lc '. /home/USER/.config/mail-auto-draft/secrets.env && printf %s \"$GMAIL_APP_PASSWORD\"'"
Continuous Background Processing
Prefer a systemd --user oneshot service plus timer over an infinite Python loop.
Example service template:
[Unit]
Description=Process inbox and auto-reply via Himalaya
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
WorkingDirectory=__PROJECT_DIR__
ExecStart=/usr/bin/flock -n __PROJECT_DIR__/runtime/process_inbox.lock /usr/bin/python3 __PROJECT_DIR__/process_inbox.py --limit 5
Example timer template:
[Unit]
Description=Run mail auto-draft every minute
[Timer]
OnBootSec=2min
OnUnitActiveSec=60s
Persistent=true
Unit=mail-auto-draft.service
[Install]
WantedBy=timers.target
Procedure
1. Verify dependencies
himalaya --version
python3 -c "import yaml, requests"
python3 -m py_compile process_inbox.py
2. Test in draft mode first
python3 process_inbox.py --mode draft --limit 5
Review:
- generated drafts
logs/mail_actions.jsonl
3. Switch to auto mode only after review
python3 process_inbox.py --mode auto --limit 1
4. Enable timer-based background processing
systemctl --user daemon-reload
systemctl --user enable --now mail-auto-draft.timer
systemctl --user start mail-auto-draft.service
Useful Runtime Commands
Status:
systemctl --user status mail-auto-draft.timer --no-pager
systemctl --user status mail-auto-draft.service --no-pager
Logs:
journalctl --user -u mail-auto-draft.service -n 50 --no-pager
Manual run:
python3 process_inbox.py --limit 1
Example Workflow
Example use case:
- a user wants automatic replies for simple inbound messages such as information requests, lightweight appointment requests, or simple acknowledgements
- Hermes helps configure Himalaya and the local processing script
- the workflow only auto-sends safe standard categories
- anything uncertain stays out of the auto-send path
Troubleshooting
It replies to itself repeatedly
Check:
own_addressesis configured- self-sender mail is ignored
- only new/unseen mail is processed
Replies go to the wrong recipient
Check:
- recipient selection prefers
Reply-To - fallback uses
From - empty
To:in reply templates is repaired before send
It sends to newsletters or bulk mail
Tighten:
- subject keyword filters
- header ignore rules
- whitelist-only auto-send
- high confidence requirement
Himalaya says send failed but recipient got the email
This is often the Gmail IMAP append issue after SMTP success. Verify recipient delivery before resending.
Verification
A successful setup should show:
- inbound external mail gets processed
chosen_reply_recipientis logged correctly- own mail is ignored with
self_sender - background timer runs every minute
- no repeated self-reply loops
References
references/production-checklist.mdreferences/setup-commands.md