Skip to content

MT-22401: Add Email Campaigns API - #72

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

MT-22401: Add Email Campaigns API#72
Rabsztok wants to merge 2 commits into
mainfrom
MT-22401-php-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 PHP SDK.

Changes

  • Add emailCampaigns() to the General client with the full contract: list (per_page/search/token), get, create, update, delete (204), the five lifecycle actions (start, schedule, cancel, terminate, reset), and stats with an optional date range
  • Typed request DTOs per the published OpenAPI schema: flat request bodies, integer domainId (a Sending Domains endpoint id), new TemplateAttributes (subject/bodyHtml/bodyText/mergeTags) and ReplyTo DTOs, audience id arrays (empty array clears the audience), rapid/gradual delivery modes, 10-value state constants
  • Full-lifecycle example in examples/email-campaigns/all.php + README/CHANGELOG entries

How to test

  • Run examples/email-campaigns/all.php with a real API token and a verified sending domain — create a draft, update design/audience, schedule + cancel, fetch stats, delete
  • Verify single-campaign responses expose the data payload and a lifecycle 422 surfaces the API error message

Summary by CodeRabbit

  • New Features

    • Added Email Campaigns API support.
    • List, view, create, update, and delete campaigns.
    • Manage campaign lifecycles with start, schedule, cancel, terminate, and reset actions.
    • Retrieve campaign performance statistics with optional date ranges.
    • Added support for campaign delivery settings, templates, reply-to details, contact lists, and segments.
    • Added runnable examples and usage documentation.
  • Tests

    • Added comprehensive coverage for campaign management, lifecycle actions, validation, serialization, 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 59947756-702f-468f-b8ed-98527d891b4a

📥 Commits

Reviewing files that changed from the base of the PR and between 85e7d2a and 2c88691.

📒 Files selected for processing (13)
  • CHANGELOG.md
  • README.md
  • examples/README.md
  • examples/email-campaigns/all.php
  • src/Api/General/EmailCampaign.php
  • src/DTO/Request/EmailCampaign/CreateEmailCampaign.php
  • src/DTO/Request/EmailCampaign/EmailCampaignInterface.php
  • src/DTO/Request/EmailCampaign/ReplyTo.php
  • src/DTO/Request/EmailCampaign/TemplateAttributes.php
  • src/DTO/Request/EmailCampaign/UpdateEmailCampaign.php
  • src/MailtrapGeneralClient.php
  • tests/Api/General/EmailCampaignTest.php
  • tests/MailtrapGeneralClientTest.php
🚧 Files skipped from review as they are similar to previous changes (10)
  • tests/MailtrapGeneralClientTest.php
  • README.md
  • src/DTO/Request/EmailCampaign/TemplateAttributes.php
  • src/MailtrapGeneralClient.php
  • examples/README.md
  • src/DTO/Request/EmailCampaign/EmailCampaignInterface.php
  • src/DTO/Request/EmailCampaign/ReplyTo.php
  • CHANGELOG.md
  • tests/Api/General/EmailCampaignTest.php
  • src/Api/General/EmailCampaign.php

📝 Walkthrough

Walkthrough

This PR adds an account-scoped Email Campaigns API to the Mailtrap SDK. It includes request DTOs, CRUD and lifecycle operations, scheduling, statistics, tests, a usage example, and documentation updates.

Changes

Email Campaigns

Layer / File(s) Summary
Campaign request contracts
src/DTO/Request/EmailCampaign/*
Adds campaign states, delivery modes, nested DTOs, flat request serialization, and empty-update validation.
Campaign API and client wiring
src/Api/General/EmailCampaign.php, src/MailtrapGeneralClient.php, tests/MailtrapGeneralClientTest.php
Adds listing, CRUD, lifecycle, scheduling, statistics, account ID access, and client registration.
Campaign operation coverage
tests/Api/General/EmailCampaignTest.php
Tests request serialization, API operations, validation, lifecycle transitions, date conversion, and statistics filters.
Usage examples and documentation
examples/email-campaigns/all.php, examples/README.md, README.md, CHANGELOG.md
Adds a complete campaign workflow example and documents the new API.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Application
  participant MailtrapGeneralClient
  participant EmailCampaign
  participant MailtrapAPI
  Application->>MailtrapGeneralClient: emailCampaigns(accountId)
  MailtrapGeneralClient-->>Application: EmailCampaign client
  Application->>EmailCampaign: createEmailCampaign(CreateEmailCampaign)
  EmailCampaign->>MailtrapAPI: POST /api/email_campaigns
  MailtrapAPI-->>EmailCampaign: campaign response
  EmailCampaign-->>Application: handled response
  Application->>EmailCampaign: scheduleEmailCampaign(id, datetime)
  EmailCampaign->>MailtrapAPI: POST /api/email_campaigns/{id}/schedule
  MailtrapAPI-->>EmailCampaign: scheduled campaign response
  EmailCampaign-->>Application: handled response
Loading

Suggested reviewers: igordobryn, vladimirtaytor

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.53% 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
Title check ✅ Passed The title clearly and concisely identifies the main change: adding the Email Campaigns API.
Description check ✅ Passed The description includes the required Motivation, Changes, and How to test sections with specific implementation and testing details.
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 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

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.

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/email-campaigns/all.php`:
- Around line 58-71: Update the example flow around createEmailCampaign and all
dependent operations to extract and reuse the created campaign ID from response
data instead of hard-coded 4567. Check the create response for failure and stop
before update, lifecycle, stats, or delete actions when creation does not
succeed; preserve the existing operation order and output behavior for
successful creation.
- Around line 173-181: Update the campaign lifecycle sequence around
resetEmailCampaign so resetEmailCampaign is called while the campaign remains
scheduled. Move the reset demonstration immediately after scheduling, then
schedule the campaign again before the cancellation, start, and termination
steps, or use a separate campaign identifier for the later sequence.
- Line 60: Update the email campaign configuration around mailsendDomainId and
the related contact list/segment IDs to remove account-scoped hardcoded
fallbacks. Require the corresponding environment or configuration values, or
mark each fallback explicitly as a placeholder that must be replaced before use.
- Around line 16-18: Cast the $_ENV['MAILTRAP_ACCOUNT_ID'] value to an integer
when assigning $accountId, then pass that integer unchanged to
MailtrapGeneralClient::emailCampaigns().
🪄 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: b23572ec-0178-4077-92d2-77e45f57fc88

📥 Commits

Reviewing files that changed from the base of the PR and between aa1e5fc and 5a51fc4.

📒 Files selected for processing (13)
  • CHANGELOG.md
  • README.md
  • examples/README.md
  • examples/email-campaigns/all.php
  • src/Api/General/EmailCampaign.php
  • src/DTO/Request/EmailCampaign/CreateEmailCampaign.php
  • src/DTO/Request/EmailCampaign/EmailCampaignInterface.php
  • src/DTO/Request/EmailCampaign/ReplyTo.php
  • src/DTO/Request/EmailCampaign/TemplateAttributes.php
  • src/DTO/Request/EmailCampaign/UpdateEmailCampaign.php
  • src/MailtrapGeneralClient.php
  • tests/Api/General/EmailCampaignTest.php
  • tests/MailtrapGeneralClientTest.php

Comment thread examples/email-campaigns/all.php Outdated
Comment thread examples/email-campaigns/all.php
Comment thread examples/email-campaigns/all.php Outdated
Comment thread examples/email-campaigns/all.php Outdated
@Rabsztok

Copy link
Copy Markdown
Contributor Author

Addressed all 4 CodeRabbit findings in d7105c4:

  • Reuse the campaign created by the example (Major) — the create step now extracts data.id and every dependent step (get/update/lifecycle/stats/delete) reuses it; the script exits early if creation fails.
  • Move reset while the campaign is still scheduled (Major) — lifecycle reordered to schedule → reset → schedule again → cancel → start → terminate, so each action runs from a valid state.
  • Do not use arbitrary account-scoped identifier fallbacks (Minor) — dropped the hardcoded domain UUID fallback (MAILTRAP_DOMAIN_ID env var is now required and documented inline); contact list/segment IDs are marked as placeholders to replace.
  • Cast MAILTRAP_ACCOUNT_ID to int (Minor) — now (int) $_ENV['MAILTRAP_ACCOUNT_ID'], matching other examples.

Also derived the stats date window at runtime (-30 daystoday) so it covers the just-created campaign instead of a fixed past month.

Verified: full phpunit suite (418 tests) green, psalm clean.

@Rabsztok
Rabsztok marked this pull request as draft July 31, 2026 11:56
@Rabsztok
Rabsztok force-pushed the MT-22401-php-email-campaigns branch from d7105c4 to 9dd3c92 Compare August 6, 2026 12:06
Decisions:
- Request bodies are flat JSON — no ['email_campaign' => ...] wrapper; domain_id is an integer sending domain ID
- Single-campaign and stats responses documented/tested as {data: ...} envelopes; delete returns 204 with no body
- Typed TemplateAttributes (subject/body_html/body_text/merge_tags, no template id) and ReplyTo DTOs replace raw arrays
- contact_list_ids/contact_segment_ids kept behind the !== null filter so [] still clears the audience
- Five lifecycle endpoints (start/schedule/cancel/terminate/reset); schedule accepts string or DateTimeInterface; stats gains optional start_date/end_date
Decisions:
- Reuse the created campaign ID across all dependent example steps; exit early when creation fails
- Reorder lifecycle to schedule -> reset -> schedule again -> cancel -> start -> terminate so every action runs from a valid state
- Require MAILTRAP_DOMAIN_ID (no arbitrary fallback) and mark contact list/segment IDs as placeholders
- Cast MAILTRAP_ACCOUNT_ID to int (strict_types + int param)
- Derive stats date window at runtime instead of fixed dates
@Rabsztok
Rabsztok force-pushed the MT-22401-php-email-campaigns branch from 9dd3c92 to 2c88691 Compare August 7, 2026 06:23
@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.

Comment thread CHANGELOG.md
@@ -1,3 +1,6 @@
## [Unreleased]

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.

This is not necessary and should be auto-generated on release

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