Skip to content

feat(inbound): MailgunInboundParser + DI registration#25

Open
mpge wants to merge 1 commit intofeat/inbound-email-controllerfrom
feat/mailgun-inbound-parser
Open

feat(inbound): MailgunInboundParser + DI registration#25
mpge wants to merge 1 commit intofeat/inbound-email-controllerfrom
feat/mailgun-inbound-parser

Conversation

@mpge
Copy link
Copy Markdown
Member

@mpge mpge commented Apr 24, 2026

Summary

Adds Mailgun as the second supported inbound provider alongside Postmark (from #24). Mailgun POSTs multipart/form-data with snake-case field names (sender / recipient / body-plain / body-html / Message-Id / In-Reply-To / References / attachments). The controller's signature already accepts any dictionary-shaped payload, so no controller changes needed — register the new parser and route via ?adapter=mailgun.

Notes

  • Mailgun's from is typically "Name <email>" — we extract the display name portion separately and fall back to the sender field for the email.
  • Mailgun hosts attachment content behind a URL (large attachments). We carry the URL through in DownloadUrl; a follow-up worker can fetch + persist out-of-band.
  • Malformed attachments JSON degrades gracefully (empty list, no exception propagation).

Dependencies

Test plan

  • 7 xUnit tests cover core field extraction, threading headers, provider-hosted attachment parsing, malformed attachments JSON, sender→from fallback, bare-email (no display name) handling, and the adapter name contract
  • CI green (won't trigger against stacked base until rebased)

Adds Mailgun as the second supported inbound provider alongside
Postmark. Mailgun POSTs multipart/form-data with snake-case field
names (sender / recipient / body-plain / body-html / Message-Id /
In-Reply-To / References / attachments). The controller's signature
already accepts any dictionary-shaped payload, so no controller
changes needed — just register the new parser and route via
?adapter=mailgun.

Notes:
- Mailgun's 'from' is typically 'Name <email>' — we extract the
  display name portion separately and fall back to the sender field
  for the email.
- Mailgun hosts attachment content behind a URL (large attachments).
  We carry the URL through in DownloadUrl; a follow-up worker can
  fetch + persist out-of-band.
- Malformed attachments JSON degrades gracefully (empty list, no
  exception propagation).

7 xUnit tests exercise core field extraction, threading headers,
provider-hosted attachment parsing, malformed attachment JSON,
sender→from fallback, bare-email (no display name) handling, and
the adapter name contract.
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