Skip to content

Add Inbound Email v2 API support#117

Merged
mklocek merged 6 commits into
mainfrom
inbound-v2
Jul 24, 2026
Merged

Add Inbound Email v2 API support#117
mklocek merged 6 commits into
mainfrom
inbound-v2

Conversation

@mklocek

@mklocek mklocek commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Motivation

Add SDK support for the Inbound Email v2 API, and surface the inbound-related additions on existing endpoints. Mirrors the OpenAPI spec.

Changes

  • Inbound Email API — new token-scoped API classes (no account_id required):
    • InboundFoldersAPI — list, get, create, update, delete
    • InboundInboxesAPI (folder-scoped) — list, get, create (hosted & custom-domain), update, delete
    • InboundMessagesAPI (inbox-scoped) — list (cursor-paginated), get, delete, reply, reply_all, forward
    • InboundThreadsAPI (inbox-scoped) — list (cursor-paginated), get, delete
  • DTOs for folders, inboxes, messages (with typed attachments), threads (with typed thread messages), the paginated list responses, and the send result.
  • Email LogsEmailLogMessage gains rfc_message_id, in_reply_to, references, thread_id.
  • Sending DomainsSendingDomain gains inbound_enabled, inbound_verified.
  • Specs (DTO + VCR-based API specs), per-resource examples, and README entries.

Split into reviewable commits: existing-endpoint fields, DTOs, API classes, specs, cassettes, examples + README.

mklocek added 4 commits July 24, 2026 06:28
EmailLogMessage gains rfc_message_id, in_reply_to, references, and thread_id. SendingDomain gains inbound_enabled and inbound_verified.

Specs and VCR cassettes for both endpoints updated to cover the new fields. Cassette bodies were hand-edited rather than re-recorded, to avoid churning live resources and to keep the curated email-log fixture stable.
Struct DTOs for folders, inboxes, messages (with typed attachments), threads (with typed thread messages), the paginated list responses, and the reply/forward send result. Matches the OpenAPI spec.
InboundFoldersAPI (CRUD), InboundInboxesAPI (folder-scoped CRUD), InboundMessagesAPI (list/get/delete + reply/reply_all/forward) and InboundThreadsAPI (list/get/delete), wired into lib/mailtrap.rb.

Inbound is token-scoped, so these override initialize to take just a client (no account_id). Nested attachments and thread messages are built into typed structs, mirroring EmailLogsAPI's event handling.
Offline DTO specs for all inbound structs, and VCR-based API specs for folders, inboxes, messages and threads (happy paths plus ArgumentError and Mailtrap::Error cases). Cassettes to be recorded against the live API.
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 48 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 17d23397-019c-4078-b7b6-b503e15fe6e7

📥 Commits

Reviewing files that changed from the base of the PR and between a51f13f and e608358.

📒 Files selected for processing (37)
  • README.md
  • examples/inbound_folders_api.rb
  • examples/inbound_inboxes_api.rb
  • examples/inbound_messages_api.rb
  • examples/inbound_threads_api.rb
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_create/maps_response_data_to_an_InboundFolder_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_delete/returns_nil.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_delete/when_the_folder_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_get/maps_response_data_to_an_InboundFolder_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_get/when_the_folder_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_list/maps_response_data_to_InboundFolder_objects.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_update/maps_response_data_to_an_InboundFolder_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_create/maps_response_data_to_an_InboundInbox_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_delete/returns_nil.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_delete/when_the_inbox_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_get/maps_response_data_to_an_InboundInbox_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_get/when_the_inbox_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_list/maps_response_data_to_InboundInbox_objects.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_update/maps_response_data_to_an_InboundInbox_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_delete/returns_nil.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_forward/maps_response_data_to_an_InboundSendResult.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_get/maps_response_data_to_an_InboundMessage_with_attachments.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_get/when_the_message_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_list/maps_response_data_to_an_InboundMessagesListResponse.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_list/with_pagination_cursor/passes_last_id_and_returns_a_page.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_reply/maps_response_data_to_an_InboundSendResult.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_reply_all/maps_response_data_to_an_InboundSendResult.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_delete/returns_nil.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_delete/when_the_thread_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_get/maps_response_data_to_an_InboundThread_with_messages.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_get/when_the_thread_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_list/maps_response_data_to_an_InboundThreadsListResponse.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_list/with_pagination_cursor/passes_last_id_and_returns_a_page.yml
  • spec/mailtrap/inbound_folders_api_spec.rb
  • spec/mailtrap/inbound_inboxes_api_spec.rb
  • spec/mailtrap/inbound_messages_api_spec.rb
  • spec/mailtrap/inbound_threads_api_spec.rb
📝 Walkthrough

Walkthrough

Added inbound email support to the Ruby client through folder, inbox, message, and thread APIs. The change includes typed DTOs, CRUD and messaging operations, cursor pagination, attachment mapping, examples, compatibility fields, VCR fixtures, and RSpec coverage.

Changes

Inbound email functionality

Layer / File(s) Summary
Shared contracts and client wiring
lib/mailtrap.rb, lib/mailtrap/*, README.md, spec/mailtrap/email_logs_api_spec.rb, spec/mailtrap/sending_domains_api_spec.rb
Adds inbound API loading, pagination/send-result DTOs, RFC threading fields on email-log messages, inbound sending-domain fields, and README example links.
Folder and inbox management
lib/mailtrap/inbound_folder.rb, lib/mailtrap/inbound_folders_api.rb, lib/mailtrap/inbound_inbox.rb, lib/mailtrap/inbound_inboxes_api.rb, examples/inbound_folders_api.rb, examples/inbound_inboxes_api.rb, spec/mailtrap/inbound_*folder*, spec/mailtrap/inbound_*inbox*, spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/*, spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/*
Implements folder and folder-scoped inbox CRUD operations with option validation, typed mapping, error handling, runnable examples, and recorded request fixtures.
Message retrieval and sending workflows
lib/mailtrap/inbound_attachment.rb, lib/mailtrap/inbound_message.rb, lib/mailtrap/inbound_messages_api.rb, lib/mailtrap/inbound_messages_list_response.rb, lib/mailtrap/inbound_send_result.rb, examples/inbound_messages_api.rb, spec/mailtrap/inbound_message*, spec/mailtrap/inbound_messages*, spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/*
Adds cursor-paginated message listing, message retrieval and deletion, attachment conversion, reply/reply-all/forward actions, validation, examples, and VCR-backed tests.
Thread retrieval and lifecycle
lib/mailtrap/inbound_thread.rb, lib/mailtrap/inbound_thread_message.rb, lib/mailtrap/inbound_threads_api.rb, lib/mailtrap/inbound_threads_list_response.rb, examples/inbound_threads_api.rb, spec/mailtrap/inbound_thread*, spec/mailtrap/inbound_threads*, spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/*
Adds cursor-paginated thread listing, thread retrieval with nested typed messages and attachments, deletion, error handling, examples, and VCR-backed tests.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant InboundThreadsAPI
  participant MailtrapAPI
  Client->>InboundThreadsAPI: list or get inbox threads
  InboundThreadsAPI->>MailtrapAPI: GET threads endpoint with optional last_id
  MailtrapAPI-->>InboundThreadsAPI: thread payload with nested messages
  InboundThreadsAPI-->>Client: InboundThreadsListResponse or InboundThread
Loading

Possibly related PRs

Suggested reviewers: i7an, igordobryn

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.38% 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
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.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding Inbound Email v2 API support.
Description check ✅ Passed It includes the required Motivation and Changes sections and is specific; the test and images sections are omitted but not critical.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch inbound-v2

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.

@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: 5

🧹 Nitpick comments (1)
spec/mailtrap/inbound_thread_message_spec.rb (1)

16-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Expand DTO tests to cover the complete public contracts.

  • spec/mailtrap/inbound_thread_message_spec.rb#L16-L25: assert RFC/threading headers, addresses, bodies, attachments, and bounced_at.
  • spec/mailtrap/inbound_thread_spec.rb#L20-L32: assert last_received_at, last_sent_at, and last_message_id.
🤖 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 `@spec/mailtrap/inbound_thread_message_spec.rb` around lines 16 - 25, Expand
the DTO expectations in spec/mailtrap/inbound_thread_message_spec.rb lines 16-25
to cover RFC/threading headers, addresses, bodies, attachments, and bounced_at
in addition to the existing attributes. Also update
spec/mailtrap/inbound_thread_spec.rb lines 20-32 to assert last_received_at,
last_sent_at, and last_message_id, using the fixture values established by each
DTO.
🤖 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/inbound_messages_api.rb`:
- Around line 14-15: Update the message retrieval flow around messages.get to
check whether page.data contains a first message before accessing its id; handle
an empty inbox gracefully and only perform the remaining message operations when
a message is available.

In `@examples/inbound_threads_api.rb`:
- Around line 14-19: Guard the example calls to threads.get and threads.delete
by checking that page.data contains a first thread before dereferencing
page.data.first.id. Preserve the existing get/delete behavior when the page is
non-empty, and skip both operations for an empty page.

In
`@spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_list/maps_response_data_to_InboundInbox_objects.yml`:
- Line 71: Replace the recorded `@inbound-mailtrap.io` addresses with reserved
synthetic/local addresses in both fixture entries:
spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_list/maps_response_data_to_InboundInbox_objects.yml:71
and
spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_update/maps_response_data_to_an_InboundInbox_object.yml:71.
Keep the fixture response structure and inbox fields unchanged.

In
`@spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_get/maps_response_data_to_an_InboundMessage_with_attachments.yml`:
- Around line 73-80: Sanitize the cassette response data by replacing the S3
presigned raw_message_url and raw_message_expires_at with deterministic redacted
values, and replace opaque unsubscribe and open-tracking URLs in html_body and
text_body with fixed placeholders. Remove the exposed credentials, signatures,
tokens, and PII from repository history, and invalidate the existing capture if
it remains usable.

In
`@spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_get/maps_response_data_to_an_InboundThread_with_messages.yml`:
- Around line 72-79: Across the three listed fixture files and their indicated
ranges, address the repeated tickets-1a2b3c4d@inbound-mailtrap.io identity:
either document and test that it is intentional shared test setup, or replace it
consistently in every affected VCR JSON body with a reserved synthetic mailbox
address, preserving the fixture data structure and references.

---

Nitpick comments:
In `@spec/mailtrap/inbound_thread_message_spec.rb`:
- Around line 16-25: Expand the DTO expectations in
spec/mailtrap/inbound_thread_message_spec.rb lines 16-25 to cover RFC/threading
headers, addresses, bodies, attachments, and bounced_at in addition to the
existing attributes. Also update spec/mailtrap/inbound_thread_spec.rb lines
20-32 to assert last_received_at, last_sent_at, and last_message_id, using the
fixture values established by each DTO.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ab09e27-0db0-4c1a-bd3e-24e1faa00513

📥 Commits

Reviewing files that changed from the base of the PR and between c5831c1 and a51f13f.

📒 Files selected for processing (68)
  • README.md
  • examples/inbound_folders_api.rb
  • examples/inbound_inboxes_api.rb
  • examples/inbound_messages_api.rb
  • examples/inbound_threads_api.rb
  • lib/mailtrap.rb
  • lib/mailtrap/email_log_message.rb
  • lib/mailtrap/inbound_attachment.rb
  • lib/mailtrap/inbound_folder.rb
  • lib/mailtrap/inbound_folders_api.rb
  • lib/mailtrap/inbound_inbox.rb
  • lib/mailtrap/inbound_inboxes_api.rb
  • lib/mailtrap/inbound_message.rb
  • lib/mailtrap/inbound_messages_api.rb
  • lib/mailtrap/inbound_messages_list_response.rb
  • lib/mailtrap/inbound_send_result.rb
  • lib/mailtrap/inbound_thread.rb
  • lib/mailtrap/inbound_thread_message.rb
  • lib/mailtrap/inbound_threads_api.rb
  • lib/mailtrap/inbound_threads_list_response.rb
  • lib/mailtrap/sending_domain.rb
  • spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/maps_response_data_to_EmailLogMessage_with_events_and_raw_message_url.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/maps_response_data_to_EmailLogsListResponse_with_messages.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_create/maps_response_data_to_an_InboundFolder_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_delete/returns_nil.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_delete/when_the_folder_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_get/maps_response_data_to_an_InboundFolder_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_get/when_the_folder_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_list/maps_response_data_to_InboundFolder_objects.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundFoldersAPI/_update/maps_response_data_to_an_InboundFolder_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_create/maps_response_data_to_an_InboundInbox_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_delete/returns_nil.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_delete/when_the_inbox_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_get/maps_response_data_to_an_InboundInbox_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_get/when_the_inbox_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_list/maps_response_data_to_InboundInbox_objects.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundInboxesAPI/_update/maps_response_data_to_an_InboundInbox_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_delete/returns_nil.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_forward/maps_response_data_to_an_InboundSendResult.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_get/maps_response_data_to_an_InboundMessage_with_attachments.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_get/when_the_message_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_list/maps_response_data_to_an_InboundMessagesListResponse.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_list/with_pagination_cursor/passes_last_id_and_returns_a_page.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_reply/maps_response_data_to_an_InboundSendResult.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundMessagesAPI/_reply_all/maps_response_data_to_an_InboundSendResult.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_delete/returns_nil.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_delete/when_the_thread_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_get/maps_response_data_to_an_InboundThread_with_messages.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_get/when_the_thread_does_not_exist/raises_an_error.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_list/maps_response_data_to_an_InboundThreadsListResponse.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_InboundThreadsAPI/_list/with_pagination_cursor/passes_last_id_and_returns_a_page.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_SendingDomainsAPI/_create/maps_response_data_to_sending_domain_object.yml
  • spec/fixtures/vcr_cassettes/Mailtrap_SendingDomainsAPI/_get/maps_response_data_to_SendingDomain_object.yml
  • spec/mailtrap/email_logs_api_spec.rb
  • spec/mailtrap/inbound_attachment_spec.rb
  • spec/mailtrap/inbound_folder_spec.rb
  • spec/mailtrap/inbound_folders_api_spec.rb
  • spec/mailtrap/inbound_inbox_spec.rb
  • spec/mailtrap/inbound_inboxes_api_spec.rb
  • spec/mailtrap/inbound_message_spec.rb
  • spec/mailtrap/inbound_messages_api_spec.rb
  • spec/mailtrap/inbound_messages_list_response_spec.rb
  • spec/mailtrap/inbound_send_result_spec.rb
  • spec/mailtrap/inbound_thread_message_spec.rb
  • spec/mailtrap/inbound_thread_spec.rb
  • spec/mailtrap/inbound_threads_api_spec.rb
  • spec/mailtrap/inbound_threads_list_response_spec.rb
  • spec/mailtrap/sending_domains_api_spec.rb

Comment thread examples/inbound_messages_api.rb
Comment thread examples/inbound_threads_api.rb
# @attr_reader download_url [String, nil] Signed URL to download the attachment (only when fetched by ID)
# @attr_reader download_url_expires_at [String, nil] When the download URL expires (only when fetched by ID)
# rubocop:disable Lint/StructNewOverride -- +size+ is an API field that shadows Struct#size
InboundAttachment = Struct.new(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

BTW i wonder if it would make more sense to use Data
... Data doesn't even have size :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good thought — Data would be a nice fit semantically and would drop the Lint/StructNewOverride disable. The snag is construction: we build these from partial API responses via .new(**hash.slice(*members)), and several fields (download_url, download_url_expires_at, …) are only present when a message is fetched by ID. Struct with keyword_init: true nil-defaults the missing keys for free, whereas Data requires every member and would need a custom initialize defaulting all eight — a bit more boilerplate than the one-line disable. And the rest of the SDK is uniformly Struct, so I lean toward keeping it consistent here. Happy to revisit a repo-wide Struct → Data migration separately if we want it.

mklocek added 2 commits July 24, 2026 16:36
Cassettes recorded against the live API for folders, inboxes, messages and threads, with the spec let IDs pointed at real recorded resources. Response bodies anonymised: the sending domain is replaced with example.com and the live inbox addresses with non-real slugs; the public inbound-mailtrap.io domain and resource IDs are kept, consistent with the existing cassettes.
Per-resource example scripts for inbound folders, inboxes, messages (incl. reply/reply_all/forward) and threads, linked from a new Inbound Email section in the README.
@mklocek
mklocek merged commit b62a308 into main Jul 24, 2026
4 checks passed
@mklocek
mklocek deleted the inbound-v2 branch July 24, 2026 14:47
@github-actions github-actions Bot mentioned this pull request Jul 24, 2026
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.

3 participants