Skip to content

feat: one-off import of past mail from IMAP folders - #20

Merged
TobiasMende merged 12 commits into
mainfrom
feat/imap-backfill
Oct 28, 2026
Merged

TobiasMende merged 12 commits into
mainfrom
feat/imap-backfill

Conversation

@TobiasMende

Copy link
Copy Markdown
Member

Adds a Mail Import: a one-off import of past mail from chosen folders of an IMAP Email Account into Communications.

  • Scan reads headers of the chosen folders (subfolders included, optional date range) in resumable background jobs, read-only (BODY.PEEK, read-only selects).
  • Review lists addresses that are no Contact yet: create a Contact (optionally linked to a company), add the address to an existing Contact, or ignore it site-wide.
  • Import imports only mails with at least one Contact, as Closed and seen Communications (Sent when the sender is an own address). Deduplicated by Message-ID (or account, folder and UID), never creates contacts on its own, 25 MB per mail.
  • Import-only mailboxes are normal Email Accounts with Enable Incoming off, so they are never polled.
  • Only System Managers and users with the account in their User Emails can run imports.
  • New hooks for apps: mailsync_own_address, mailsync_address_suggestion, mailsync_contact_link_doctype. mailsync_recipient_links and mailsync_mail_read also run for imported mails. frappe.flags.mailsync_import is set while an imported Communication is inserted.

Design: docs/superpowers/specs/2026-10-28-imap-backfill-design.md, plan: docs/superpowers/plans/2026-10-28-imap-backfill.md.

Tests cover scan, review, import, jobs and access, plus an end-to-end run against GreenMail that checks no mail gets \Seen.

🤖 Generated with Claude Code

TobiasMende and others added 12 commits October 28, 2026 09:04
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cess

- isolate each scanned mail, accept long Message-IDs and 8-bit or folded headers
- accept addresses Frappe's email check rejects in the review and ignore list
- log failing hooks instead of stopping the job
- index import messages and check Message-IDs per chunk
- store UIDs as Long Int
- lock account and dates after the first scan, drop mails of removed folders
- delete an import with its rows, narrow permissions, POST only for bulk ignore
- clear error when the IMAP login fails, row lock on start, restart stale jobs from the form

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TobiasMende
TobiasMende merged commit 9718e9e into main Oct 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant