Skip to content

MT-22401: Add Email Campaigns API - #72

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

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, UUID mailsendDomainId, 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.
    • Manage campaigns by listing, viewing, creating, updating, and deleting.
    • Control campaign lifecycles with start, schedule, cancel, terminate, and reset actions.
    • Retrieve campaign performance statistics with optional date ranges.
    • Added runnable examples and usage documentation.
  • Tests

    • Added comprehensive coverage for campaign management, lifecycle actions, validation, serialization, and statistics.

Decisions:
- Request bodies are flat JSON — no ['email_campaign' => ...] wrapper; mailsend_domain_id is a string UUID
- 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
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds an account-scoped Email Campaigns API to the Mailtrap SDK. The implementation includes request DTOs with flat serialization, an API client with list, CRUD, lifecycle, scheduling, and statistics operations, comprehensive unit tests, a complete usage example, and documentation updates.

Changes

Email Campaigns

Layer / File(s) Summary
Campaign request contracts
src/DTO/Request/EmailCampaign/*
Adds EmailCampaignInterface with delivery modes and lifecycle states. Creates CreateEmailCampaign, UpdateEmailCampaign, ReplyTo, and TemplateAttributes DTOs. All DTOs serialize to flat request arrays with only non-null fields. UpdateEmailCampaign rejects empty payloads.
Campaign API and client wiring
src/Api/General/EmailCampaign.php, src/MailtrapGeneralClient.php, tests/MailtrapGeneralClientTest.php
Implements token-scoped EmailCampaign client with methods for listing (with filters), fetching, creating, updating, and deleting campaigns. Adds lifecycle actions: start, schedule (accepts string or DateTimeInterface), cancel, terminate, and reset. Includes stats retrieval with optional date range. Registers the client in MailtrapGeneralClient via API_MAPPING and updates test wiring.
Campaign operation coverage
tests/Api/General/EmailCampaignTest.php
Tests all API operations including request wiring, flat payload serialization, validation error messages, empty update rejection, lifecycle state transitions, datetime conversion, and statistics queries with optional date parameters.
Usage examples and documentation
examples/email-campaigns/all.php, examples/README.md, README.md, CHANGELOG.md
Provides a complete PHP example demonstrating campaign creation, retrieval, update, scheduling, reset, cancellation, start, termination, stats, and deletion with exception handling. Updates documentation to announce the API and link to examples.

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

Possibly related PRs

  • mailtrap/mailtrap-php#39: Adds another account-scoped email-management API with analogous client classes, DTOs, mappings, examples, and tests.

Suggested reviewers: vladimirtaytor, igordobryn, mklocek

🚥 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
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 clearly and concisely describes the primary change: adding the Email Campaigns API.
Description check ✅ Passed The description includes motivation, detailed changes, and testing steps; the optional images section is not relevant to this API change.
✨ 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
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 UUID 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

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