Skip to content

MT-22401: Add Email Campaigns API - #119

Open
Rabsztok wants to merge 2 commits into
mainfrom
MT-22401-ruby-email-campaigns
Open

MT-22401: Add Email Campaigns API#119
Rabsztok wants to merge 2 commits into
mainfrom
MT-22401-ruby-email-campaigns

Conversation

@Rabsztok

@Rabsztok Rabsztok commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Draft until the server-side Email Campaigns API changes are released.

Motivation

MT-22401

Port the Email Campaigns public API (MT-21113) to the Ruby SDK.

Changes

  • Add Mailtrap::EmailCampaignsAPI covering the full contract: list (page-token pagination + name filter), get, create, update, delete, the five lifecycle actions (start, schedule, cancel, terminate, reset), and stats with an optional date range
  • Add Mailtrap::EmailCampaign / EmailCampaignStats / EmailCampaignsListResponse DTOs matching the OpenAPI schema (audience ids, template with body_html/body_text/merge_tags, 10-state lifecycle)
  • Requests send flat JSON bodies and single-object responses unwrap the data envelope, per the published spec; delete returns nil on 204
  • Runnable walkthrough in examples/email_campaigns_api.rb + README "Email marketing" entry

How to test

  • Run examples/email_campaigns_api.rb with a real API token and a verified sending domain — create a draft campaign, update its design, schedule + cancel it, fetch stats, delete it
  • Verify responses deserialize with populated attributes (campaign id, current_state, template fields)

Summary by CodeRabbit

  • New Features

    • Added Email Campaigns API support for creating, listing, filtering, retrieving, updating, and deleting campaigns.
    • Added campaign lifecycle actions, including scheduling, starting, canceling, terminating, and resetting campaigns.
    • Added campaign performance statistics with optional date-range filtering.
    • Added a complete Ruby usage example and documentation entry for Email Campaigns.
  • Tests

    • Added coverage for campaign data handling, API operations, lifecycle transitions, validation, errors, and statistics.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e75b10e2-0ade-4576-a20e-3ac0f5b2a160

📥 Commits

Reviewing files that changed from the base of the PR and between 42ce077 and e17f815.

📒 Files selected for processing (1)
  • examples/email_campaigns_api.rb
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/email_campaigns_api.rb

📝 Walkthrough

Walkthrough

Adds typed email campaign entities and a Mailtrap::EmailCampaignsAPI wrapper. The wrapper supports CRUD, lifecycle actions, pagination, filtering, and statistics retrieval. It also adds request specs, library wiring, and an end-to-end usage example.

Changes

Email Campaigns API

Layer / File(s) Summary
Campaign response contracts
lib/mailtrap/email_campaign.rb, spec/mailtrap/email_campaign_spec.rb
Defines campaign, statistics, and paginated-list DTOs. Tests cover populated and omitted attributes.
Campaign API operations
lib/mailtrap/email_campaigns_api.rb, lib/mailtrap.rb, spec/mailtrap/email_campaigns_api_spec.rb
Implements campaign CRUD, lifecycle actions, date-filtered statistics, response conversion, and API error handling with HTTP request coverage.
Campaign usage example
examples/email_campaigns_api.rb, README.md
Adds an end-to-end campaign API example and links it from the supported functionality section.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant EmailCampaignsAPI
  participant CampaignsEndpoint
  Client->>EmailCampaignsAPI: create, update, or list campaigns
  EmailCampaignsAPI->>CampaignsEndpoint: send campaign request
  CampaignsEndpoint-->>EmailCampaignsAPI: return campaign or list data
  EmailCampaignsAPI-->>Client: return typed response
  Client->>EmailCampaignsAPI: schedule, start, or retrieve stats
  EmailCampaignsAPI->>CampaignsEndpoint: send lifecycle or statistics request
  CampaignsEndpoint-->>EmailCampaignsAPI: return action or statistics data
  EmailCampaignsAPI-->>Client: return typed result
Loading

Possibly related PRs

  • mailtrap/mailtrap-ruby#83: Adds a similar API module with DTOs, examples, README wiring, and tests for another Mailtrap resource.
  • mailtrap/mailtrap-ruby#84: Adds a similar API module with DTOs, client wiring, examples, and tests for another resource.

Suggested reviewers: igordobryn, mklocek

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the addition of the Email Campaigns API.
Description check ✅ Passed The description covers the motivation, changes, and testing steps; the optional Images and GIFs section is omitted.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch MT-22401-ruby-email-campaigns

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.

@Rabsztok
Rabsztok marked this pull request as ready for review July 30, 2026 12:03

@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.

🧹 Nitpick comments (1)
lib/mailtrap/email_campaigns_api.rb (1)

104-110: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fix YARD @return tag format for delete.

# @return nil (Line 106) should be # @return [nil] to match the @return [Type] description convention used by every other method in this file, so YARD parses the return type correctly.

📝 Proposed fix
     # Deletes an email campaign. The campaign must not be in a sending state.
     # `@param` email_campaign_id [Integer] The email campaign ID
-    # `@return` nil
+    # `@return` [nil]
     # @!macro api_errors
     def delete(email_campaign_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 `@lib/mailtrap/email_campaigns_api.rb` around lines 104 - 110, Update the YARD
documentation for the delete method so its `@return` annotation uses the bracketed
type format [nil], matching the convention used throughout the file; leave the
delete implementation unchanged.
🤖 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.

Nitpick comments:
In `@lib/mailtrap/email_campaigns_api.rb`:
- Around line 104-110: Update the YARD documentation for the delete method so
its `@return` annotation uses the bracketed type format [nil], matching the
convention used throughout the file; leave the delete implementation unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 618f5e87-eb29-4288-a78d-8517b08aaaf8

📥 Commits

Reviewing files that changed from the base of the PR and between 484d54c and 82b542c.

📒 Files selected for processing (7)
  • README.md
  • examples/email_campaigns_api.rb
  • lib/mailtrap.rb
  • lib/mailtrap/email_campaign.rb
  • lib/mailtrap/email_campaigns_api.rb
  • spec/mailtrap/email_campaign_spec.rb
  • spec/mailtrap/email_campaigns_api_spec.rb

@Rabsztok

Copy link
Copy Markdown
Contributor Author

Addressed the CodeRabbit nitpick: #delete's YARD tag is now @return [nil] (bracketed type format, matching the rest of the file).

@Rabsztok
Rabsztok marked this pull request as draft July 31, 2026 11:56
Decisions:
- Request bodies are flat (no {email_campaign: ...} wrapper), matching the controller's top-level params; create and update accept the same writable set
- Single-object and stats responses unwrap the {data: ...} envelope (WebhooksAPI pattern); list returns {data, pagination} via EmailCampaignsListResponse
- delete uses base_delete and returns nil (API responds 204 No Content)
- Five lifecycle endpoints (start/schedule/cancel/terminate/reset) share a private perform_action helper; schedule takes an ISO 8601 datetime
- list(name:) maps to the search query param to filter by name; API is token-scoped, so the constructor takes only a client (AccountsAPI precedent)
@Rabsztok
Rabsztok force-pushed the MT-22401-ruby-email-campaigns branch from 4f60fa8 to 42ce077 Compare August 6, 2026 12:01
@Rabsztok
Rabsztok marked this pull request as ready for review August 7, 2026 07:24
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

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

🤖 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/email_campaigns_api.rb`:
- Around line 50-52: Update the example around email_campaigns.schedule and the
delivery-statistics query to use execution-relative future dates and a
statistics window that includes the newly scheduled campaign’s activity;
alternatively, clearly mark the shown outputs as illustrative. Keep the
scheduling and query behavior consistent so the example does not use dates
already in the past or a range that excludes the created campaign.
- Around line 62-68: Update the Email Campaign termination example around
terminate to poll the campaign with get until current_state is no longer
"terminating" or otherwise sending, then call delete only after it reaches a
deletable terminal state; keep the reset example unchanged.
🪄 Autofix

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: 9707087e-01e7-485e-81dc-79be917c869e

📥 Commits

Reviewing files that changed from the base of the PR and between d23a4fe and 42ce077.

📒 Files selected for processing (7)
  • README.md
  • examples/email_campaigns_api.rb
  • lib/mailtrap.rb
  • lib/mailtrap/email_campaign.rb
  • lib/mailtrap/email_campaigns_api.rb
  • spec/mailtrap/email_campaign_spec.rb
  • spec/mailtrap/email_campaigns_api_spec.rb
🚧 Files skipped from review as they are similar to previous changes (5)
  • README.md
  • spec/mailtrap/email_campaign_spec.rb
  • lib/mailtrap.rb
  • spec/mailtrap/email_campaigns_api_spec.rb
  • lib/mailtrap/email_campaigns_api.rb

Comment thread examples/email_campaigns_api.rb
Comment thread examples/email_campaigns_api.rb
@Rabsztok
Rabsztok force-pushed the MT-22401-ruby-email-campaigns branch from 42ce077 to e17f815 Compare August 7, 2026 09:53
# => #<struct Mailtrap::EmailCampaign id=4567, name="Spring Sale", current_state="draft", ...>

# Get all Email Campaigns (paginated, newest first; filter by name)
list = email_campaigns.list(per_page: 50, name: 'Spring')

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.

In other SDK search param name is search. Is there any reason to keep it as name?

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.

2 participants