diff --git a/config.example.yml b/config.example.yml index 477bd02..62129df 100644 --- a/config.example.yml +++ b/config.example.yml @@ -11,6 +11,10 @@ poke_api_key: "your-api-key-here" # Agents can still use create_draft. Override per account with allow_send. allow_send: true +# Mark forwarded emails as read — set to true to mark emails as read after +# forwarding to Poke. Defaults to false. Override per account with mark_as_read. +mark_as_read: false + accounts: # iCloud Mail — login is @icloud.com, send as your custom domain # Generate an App-Specific Password: https://support.apple.com/en-us/102654 @@ -24,6 +28,7 @@ accounts: from_address: "you@yourdomain.com" # Override From: header (login is @icloud.com but send as custom domain) watch_folders: - INBOX + # mark_as_read: false # Keep emails unread after forwarding # Custom SMTP server — SMTP falls back to IMAP credentials if not specified # - id: work diff --git a/src/server.py b/src/server.py index 24bef33..e4123a6 100644 --- a/src/server.py +++ b/src/server.py @@ -194,10 +194,13 @@ def parse_accounts(config: dict) -> list[dict]: os.environ.get("SMTP_USERNAME", os.environ["IMAP_USERNAME"]), ), "watch_folders": ["INBOX"], + "mark_as_read": os.environ.get("MARK_AS_READ", "false").lower() + == "true", } ] global_allow_send = config.get("allow_send", True) + global_mark_as_read = config.get("mark_as_read", False) required = ("imap_host", "imap_username", "imap_password") for i, acc in enumerate(accounts): acc.setdefault("id", f"account-{i}") @@ -210,6 +213,7 @@ def parse_accounts(config: dict) -> list[dict]: acc.setdefault("smtp_password", acc.get("imap_password")) acc.setdefault("from_address", acc.get("smtp_username")) acc.setdefault("allow_send", global_allow_send) + acc.setdefault("mark_as_read", global_mark_as_read) for field in required: if field not in acc: raise RuntimeError( @@ -491,7 +495,8 @@ async def watch_folder( email_data = parse_email_message(raw) await forward_to_poke(email_data, account, webhook_url, api_key) - await asyncio.to_thread(client.set_flags, new_uids, [b"\\Seen"]) + if account.get("mark_as_read", False): + await asyncio.to_thread(client.set_flags, new_uids, [b"\\Seen"]) existing_unseen.update(new_uids) except asyncio.CancelledError: @@ -535,7 +540,8 @@ async def _poll_folder( continue email_data = parse_email_message(raw) await forward_to_poke(email_data, account, webhook_url, api_key) - await asyncio.to_thread(client.set_flags, uids, [b"\\Seen"]) + if account.get("mark_as_read", False): + await asyncio.to_thread(client.set_flags, uids, [b"\\Seen"]) except Exception as e: logger.warning("[%s/%s] Poll error: %s", account["id"], folder, e) raise # reconnect via outer loop