Add Inbound Email API support - #251
Conversation
Add the public surface for the token-scoped Inbound Email API: the resource-tree interfaces (folders, inboxes, messages, threads), models, requests with the forward recipient validator, response types, and the thread-message visibility/direction string enums. Delivery status reuses the existing EmailLogStatus.
Add the internal resource implementations for the Inbound Email API (folders, inboxes, messages, threads) and expose them through MailtrapClient.Inbound(). Requests are posted flat and responses are deserialized directly, as the inbound endpoints use no data envelope. Add the inbound URL segments.
Add inbound threading fields (rfc_message_id, in_reply_to, references, thread_id) to email-log messages, inbound flags (inbound_enabled, inbound_verified) to sending domains, and the optional inbound_inbox_id to the webhook model and create/update requests. Add the inbound_receiving webhook type so inbound webhooks can be created and deserialized.
Add unit tests (constructor guards and resource URI construction) and integration tests (MockHttp URL/verb checks with JSON fixtures) for the inbound folders, inboxes, messages, and threads resources. Extend coverage for the surfaced fields: sending-domain inbound flags, and serialization tests for the webhook inbound_inbox_id / inbound_receiving type and the email-log threading fields.
Add a Mailtrap.Example.Inbound console project demonstrating the inbound folders, inboxes, messages, and threads resources (CRUD, pagination, reply/reply-all/forward), register it in the solution, and link it from the README.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
💤 Files with no reviewable changes (4)
📝 WalkthroughWalkthroughAdded a complete Inbound Email API to the .NET SDK. The change includes public models and resources, CRUD and messaging operations, pagination, webhook and domain fields, integration and unit tests, documentation, and an executable example project. ChangesInbound Email API
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Application
participant MailtrapClient
participant InboundResource
participant REST_API
Application->>MailtrapClient: Inbound()
MailtrapClient->>InboundResource: Create inbound resource
Application->>InboundResource: Access folders and inbox content
InboundResource->>REST_API: GET, POST, PATCH, or DELETE inbound resources
REST_API-->>Application: Return folders, inboxes, messages, threads, or send results
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@examples/Mailtrap.Example.Inbound/InboundReactor.cs`:
- Around line 25-37: Update Process to wrap resource creation and processing in
try/finally, tracking the successfully created InboundFolder and InboundInbox.
In the finally block, delete the inbox before the folder when each resource
exists, ensuring cleanup runs after failures as well as successful processing.
- Around line 90-110: Make the default flow in the inbound example read-only by
removing or gating the Reply, ReplyAll, Forward, and Delete calls behind
explicit configuration. If enabled, require recipients supplied through
user-controlled configuration rather than hardcoded addresses, and preserve the
existing message inspection behavior by default.
In `@README.md`:
- Around line 282-284: Update the “Inbound Email” README entry to limit the CRUD
claim to folders and inboxes, and describe messages and threads separately using
only their supported list, detail, delete, and send-action operations.
In `@tests/Mailtrap.IntegrationTests/Inbound/Threads/GetDetails_Success.json`:
- Around line 2-38: The detail fixture at
tests/Mailtrap.IntegrationTests/Inbound/Threads/GetDetails_Success.json must
include a third placeholder message for thread thr_1, using
ThreadMessageVisibilityStatus.Placeholder and matching the expected placeholder
shape, so its messages count aligns with message_count 3. The list fixture at
tests/Mailtrap.IntegrationTests/Inbound/Threads/List_Success.json requires no
direct change; use it as the reference for the expected placeholder entry.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 4020f6de-ab69-4a0e-92bd-3632764f4640
📒 Files selected for processing (95)
Mailtrap.slnREADME.mdexamples/Mailtrap.Example.Inbound/InboundReactor.csexamples/Mailtrap.Example.Inbound/Mailtrap.Example.Inbound.csprojexamples/Mailtrap.Example.Inbound/Program.csexamples/Mailtrap.Example.Inbound/Properties/launchSettings.jsonexamples/Mailtrap.Example.Inbound/appsettings.jsonsrc/Mailtrap.Abstractions/EmailLogs/Models/EmailLogMessage.cssrc/Mailtrap.Abstractions/GlobalSuppressions.cssrc/Mailtrap.Abstractions/GlobalUsings.cssrc/Mailtrap.Abstractions/IMailtrapClient.cssrc/Mailtrap.Abstractions/Inbound/IInboundFolderCollectionResource.cssrc/Mailtrap.Abstractions/Inbound/IInboundFolderResource.cssrc/Mailtrap.Abstractions/Inbound/IInboundInboxCollectionResource.cssrc/Mailtrap.Abstractions/Inbound/IInboundInboxContentResource.cssrc/Mailtrap.Abstractions/Inbound/IInboundInboxResource.cssrc/Mailtrap.Abstractions/Inbound/IInboundMessageCollectionResource.cssrc/Mailtrap.Abstractions/Inbound/IInboundMessageResource.cssrc/Mailtrap.Abstractions/Inbound/IInboundResource.cssrc/Mailtrap.Abstractions/Inbound/IInboundThreadCollectionResource.cssrc/Mailtrap.Abstractions/Inbound/IInboundThreadResource.cssrc/Mailtrap.Abstractions/Inbound/Models/InboundAttachment.cssrc/Mailtrap.Abstractions/Inbound/Models/InboundFolder.cssrc/Mailtrap.Abstractions/Inbound/Models/InboundInbox.cssrc/Mailtrap.Abstractions/Inbound/Models/InboundMessage.cssrc/Mailtrap.Abstractions/Inbound/Models/InboundThread.cssrc/Mailtrap.Abstractions/Inbound/Models/InboundThreadMessage.cssrc/Mailtrap.Abstractions/Inbound/Models/SendMessageResult.cssrc/Mailtrap.Abstractions/Inbound/Models/ThreadMessageDirection.cssrc/Mailtrap.Abstractions/Inbound/Models/ThreadMessageVisibilityStatus.cssrc/Mailtrap.Abstractions/Inbound/Requests/CreateInboundFolderRequest.cssrc/Mailtrap.Abstractions/Inbound/Requests/CreateInboundInboxRequest.cssrc/Mailtrap.Abstractions/Inbound/Requests/ForwardInboundMessageRequest.cssrc/Mailtrap.Abstractions/Inbound/Requests/ReplyInboundMessageRequest.cssrc/Mailtrap.Abstractions/Inbound/Requests/UpdateInboundFolderRequest.cssrc/Mailtrap.Abstractions/Inbound/Requests/UpdateInboundInboxRequest.cssrc/Mailtrap.Abstractions/Inbound/Responses/InboundMessagesListResponse.cssrc/Mailtrap.Abstractions/Inbound/Responses/InboundThreadsListResponse.cssrc/Mailtrap.Abstractions/Inbound/Validators/ForwardInboundMessageRequestValidator.cssrc/Mailtrap.Abstractions/SendingDomains/Models/SendingDomain.cssrc/Mailtrap.Abstractions/Webhooks/Models/Webhook.cssrc/Mailtrap.Abstractions/Webhooks/Models/WebhookType.cssrc/Mailtrap.Abstractions/Webhooks/Requests/CreateWebhookRequest.cssrc/Mailtrap.Abstractions/Webhooks/Requests/UpdateWebhookRequest.cssrc/Mailtrap/Core/Constants/UrlSegments.cssrc/Mailtrap/GlobalUsings.cssrc/Mailtrap/Inbound/InboundFolderCollectionResource.cssrc/Mailtrap/Inbound/InboundFolderResource.cssrc/Mailtrap/Inbound/InboundInboxCollectionResource.cssrc/Mailtrap/Inbound/InboundInboxContentResource.cssrc/Mailtrap/Inbound/InboundInboxResource.cssrc/Mailtrap/Inbound/InboundMessageCollectionResource.cssrc/Mailtrap/Inbound/InboundMessageResource.cssrc/Mailtrap/Inbound/InboundResource.cssrc/Mailtrap/Inbound/InboundThreadCollectionResource.cssrc/Mailtrap/Inbound/InboundThreadResource.cssrc/Mailtrap/MailtrapClient.cstests/Mailtrap.IntegrationTests/GlobalUsings.cstests/Mailtrap.IntegrationTests/Inbound/Folders/Create_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Folders/GetAll_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Folders/GetDetails_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Folders/Update_Success.jsontests/Mailtrap.IntegrationTests/Inbound/InboundFoldersIntegrationTests.cstests/Mailtrap.IntegrationTests/Inbound/InboundInboxesIntegrationTests.cstests/Mailtrap.IntegrationTests/Inbound/InboundMessagesIntegrationTests.cstests/Mailtrap.IntegrationTests/Inbound/InboundThreadsIntegrationTests.cstests/Mailtrap.IntegrationTests/Inbound/Inboxes/Create_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Inboxes/GetAll_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Inboxes/GetDetails_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Inboxes/Update_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Messages/Forward_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Messages/GetDetails_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Messages/List_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Messages/List_WithCursor_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Messages/ReplyAll_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Messages/Reply_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Threads/GetDetails_Success.jsontests/Mailtrap.IntegrationTests/Inbound/Threads/List_Success.jsontests/Mailtrap.IntegrationTests/SendingDomains/GetDetails_Success.jsontests/Mailtrap.IntegrationTests/SendingDomains/SendingDomainIntegrationTests.cstests/Mailtrap.IntegrationTests/TestConstants/UrlSegmentsTestConstants.cstests/Mailtrap.UnitTests/EmailLogs/EmailLogMessageThreadingFieldsTests.cstests/Mailtrap.UnitTests/GlobalUsings.cstests/Mailtrap.UnitTests/Inbound/InboundFolderCollectionResourceTests.cstests/Mailtrap.UnitTests/Inbound/InboundFolderResourceTests.cstests/Mailtrap.UnitTests/Inbound/InboundInboxCollectionResourceTests.cstests/Mailtrap.UnitTests/Inbound/InboundInboxContentResourceTests.cstests/Mailtrap.UnitTests/Inbound/InboundInboxResourceTests.cstests/Mailtrap.UnitTests/Inbound/InboundMessageCollectionResourceTests.cstests/Mailtrap.UnitTests/Inbound/InboundMessageResourceTests.cstests/Mailtrap.UnitTests/Inbound/InboundResourceTests.cstests/Mailtrap.UnitTests/Inbound/InboundThreadCollectionResourceTests.cstests/Mailtrap.UnitTests/Inbound/InboundThreadResourceTests.cstests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cstests/Mailtrap.UnitTests/Webhooks/WebhookInboundFieldsTests.cs
The inbound SendMessageInput has no subject field - reply/reply_all derive it (Re: prefix) and forward uses Fwd:. Drop the erroneous subject from the reply/forward request models, example, and tests.
Summary
Adds Inbound Email API support to the .NET SDK, matching the released Node, Ruby, MCP, PHP, Python, and Java SDKs. Exposed as
client.Inbound()— token-scoped (noaccountId), hanging off the rootMailtrapClientlikeOrganization().The resource tree mirrors the API's own (irregular) routing:
Inbox management is folder-scoped (
/api/inbound/folders/{fid}/inboxes/{id}); messages and threads are top-level inbox-scoped (/api/inbound/inboxes/{iid}/...), so an inbox is reachable two ways — matching the API.Also carries the other fields that ship with the Inbound Email API:
EmailLogMessage:RfcMessageId,InReplyTo,References,ThreadIdSendingDomain:InboundEnabled,InboundVerifiedWebhook/CreateWebhookRequest/UpdateWebhookRequest:InboundInboxId, plus a newWebhookType.InboundReceivingNotes
data/resource envelope, so requests post flat and responses deserialize directly — no request/response DTOs (unlike webhooks).Reply/ReplyAlltakeReplyInboundMessageRequest;ForwardtakesForwardInboundMessageRequest, which validates a non-emptyTo(the one universally-enforced rule). Reply body is not validated client-side, consistent with the other SDKs.StringEnumconvention:ThreadMessageVisibilityStatus,ThreadMessageDirection;DeliveryStatusreuses the existingEmailLogStatus.EmailAddressandAttachmentmodels..Instance.Summary by CodeRabbit