Skip to content

[_]: fix/auto reply and dedupe mails - #99

Merged
xabg2 merged 3 commits into
masterfrom
fix/auto-reply-and-dedupe-mails
Jul 24, 2026
Merged

[_]: fix/auto reply and dedupe mails#99
xabg2 merged 3 commits into
masterfrom
fix/auto-reply-and-dedupe-mails

Conversation

@xabg2

@xabg2 xabg2 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Implement automatic email replies with email deduplication to avoid duplicate messages when filtering emails from the Inbox and Sent folders. Additionally, allow specifying extra recipients in the To field when replying to an email.

Summary by CodeRabbit

  • New Features

    • Reply emails can now use explicitly specified “To” recipients.
    • Reply-all recipient handling provides clearer control over To and Cc addresses.
  • Bug Fixes

    • Improved reply recipient selection, including replies sent to yourself.
    • Email threads now avoid showing duplicate copies of the same message, preferring the Inbox version when available.
    • Messages without identifiers remain separate instead of being incorrectly merged.

@xabg2 xabg2 self-assigned this Jul 24, 2026
@xabg2 xabg2 added the enhancement New feature or request label Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@xabg2, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 35 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8e13c9a1-db0a-4781-a88f-07737c9ab84f

📥 Commits

Reviewing files that changed from the base of the PR and between 0bb81b7 and 08c4781.

📒 Files selected for processing (2)
  • src/modules/email/threading.ts
  • src/modules/infrastructure/jmap/jmap-mail.provider.ts
📝 Walkthrough

Walkthrough

Reply composition now accepts explicit To recipients and preserves self in derived To when applicable. JMAP thread retrieval now fetches message IDs and prefers Inbox copies when deduplicating messages.

Changes

Reply recipient handling

Layer / File(s) Summary
Explicit reply recipient flow
src/modules/email/email.dto.ts, src/modules/email/email.types.ts, src/modules/email/email.service.ts, src/modules/email/threading.ts, src/modules/email/threading.spec.ts
Reply DTOs expose optional To recipients, composeReply forwards them, and recipient derivation uses them or threading headers while deduplicating results and excluding self from Cc.

JMAP thread deduplication

Layer / File(s) Summary
Message-ID thread collapsing
src/modules/infrastructure/jmap/jmap-mail.provider.ts, src/modules/infrastructure/jmap/jmap-mail.provider.spec.ts
Thread retrieval requests message IDs, resolves Inbox, prefers Inbox copies for duplicate message IDs, and preserves messages without IDs separately.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

Reply recipient derivation

sequenceDiagram
  participant ReplyRequest
  participant EmailService
  participant RecipientDerivation
  participant ComposedReply
  ReplyRequest->>EmailService: submit reply with optional to
  EmailService->>RecipientDerivation: pass threading data and dto.to
  RecipientDerivation-->>EmailService: derive to and cc
  EmailService-->>ComposedReply: compose reply recipients
Loading

JMAP thread retrieval

sequenceDiagram
  participant JmapMailProvider
  participant JMAP
  participant InboxLookup
  participant DedupeByMessageId
  JmapMailProvider->>JMAP: fetch thread emails with messageId
  JmapMailProvider->>InboxLookup: resolve Inbox mailbox ID
  InboxLookup-->>JmapMailProvider: return Inbox mailbox ID
  JmapMailProvider->>DedupeByMessageId: deduplicate fetched emails
  DedupeByMessageId-->>JmapMailProvider: return selected copies
Loading

Possibly related PRs

Suggested reviewers: jzunigax2

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main changes: auto-reply support and mail deduplication.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/auto-reply-and-dedupe-mails

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@xabg2
xabg2 marked this pull request as ready for review July 24, 2026 10:55

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
src/modules/email/threading.ts (1)

36-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Flatten the nested ternary.

The new explicit-recipient branch nests the existing Reply-To/From ternary, which SonarCloud flags and makes the fallback semantics harder to review. Extract the threaded recipient list before selecting between explicit and derived recipients.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/modules/email/threading.ts` around lines 36 - 42, Refactor the recipient
selection around the to calculation to remove the nested ternary: first derive
the threaded recipient list from threading.parentReplyTo or
threading.parentFrom, then choose between uniqueAddresses(explicitTo) and that
derived list based on explicitTo.length. Preserve the existing
explicit-recipient and Reply-To/From fallback behavior.

Source: Linters/SAST tools

src/modules/email/threading.spec.ts (1)

143-167: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for explicit reply recipients.

These tests cover self-replies but do not exercise explicitTo, including precedence over Reply-To/From and duplicate removal. Add focused cases for the new recipient path, including the explicitly empty-list behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/modules/email/threading.spec.ts` around lines 143 - 167, Extend the
threading tests around deriveReplyRecipients with focused explicitTo cases:
verify explicit recipients take precedence over parent Reply-To/From, duplicate
recipients are removed, and an explicitly empty list remains empty rather than
falling back. Reuse the existing newThreadingHeaders, SELF, A, and B fixtures
and assert both to and cc results.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/modules/email/threading.ts`:
- Around line 36-42: Update the `to` selection in `composeReply` to distinguish
an omitted `explicitTo` value from a provided empty list; use
`uniqueAddresses(explicitTo)` whenever the list is provided, including `[]`, and
only fall back to `threading.parentReplyTo` or `threading.parentFrom` when it is
undefined.

In `@src/modules/infrastructure/jmap/jmap-mail.provider.ts`:
- Around line 1033-1035: Update dedupeByMessageId() so the trimmed
email.messageId value remains case-sensitive when used as the Map key; remove
the lowercasing while preserving trimming and existing missing-ID handling. Add
a regression case covering Message-IDs that differ only by case and ensure both
emails remain in the deduplicated result.
- Around line 644-646: Update getThread’s mailbox lookup to use a non-throwing
Inbox role resolution, yielding undefined when the account has no Inbox mailbox
instead of propagating an error. Pass that optional inboxMailboxId to
dedupeByMessageId so thread deduplication still runs for accounts without an
Inbox role.

---

Nitpick comments:
In `@src/modules/email/threading.spec.ts`:
- Around line 143-167: Extend the threading tests around deriveReplyRecipients
with focused explicitTo cases: verify explicit recipients take precedence over
parent Reply-To/From, duplicate recipients are removed, and an explicitly empty
list remains empty rather than falling back. Reuse the existing
newThreadingHeaders, SELF, A, and B fixtures and assert both to and cc results.

In `@src/modules/email/threading.ts`:
- Around line 36-42: Refactor the recipient selection around the to calculation
to remove the nested ternary: first derive the threaded recipient list from
threading.parentReplyTo or threading.parentFrom, then choose between
uniqueAddresses(explicitTo) and that derived list based on explicitTo.length.
Preserve the existing explicit-recipient and Reply-To/From fallback behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 67c9386f-f04e-47a2-b326-0386b77b6e73

📥 Commits

Reviewing files that changed from the base of the PR and between e0ec8ed and 0bb81b7.

📒 Files selected for processing (7)
  • src/modules/email/email.dto.ts
  • src/modules/email/email.service.ts
  • src/modules/email/email.types.ts
  • src/modules/email/threading.spec.ts
  • src/modules/email/threading.ts
  • src/modules/infrastructure/jmap/jmap-mail.provider.spec.ts
  • src/modules/infrastructure/jmap/jmap-mail.provider.ts

Comment thread src/modules/email/threading.ts Outdated
Comment thread src/modules/infrastructure/jmap/jmap-mail.provider.ts
Comment thread src/modules/infrastructure/jmap/jmap-mail.provider.ts
@sonarqubecloud

Copy link
Copy Markdown

@xabg2
xabg2 requested a review from apsantiso July 24, 2026 11:27
@xabg2
xabg2 merged commit f250b61 into master Jul 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants