Skip to content

MT-22401: Add Email Campaigns API - #250

Merged
Rabsztok merged 7 commits into
mainfrom
MT-22401-dotnet-email-campaigns
Aug 14, 2026
Merged

MT-22401: Add Email Campaigns API#250
Rabsztok merged 7 commits into
mainfrom
MT-22401-dotnet-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 .NET SDK.

Changes

  • Add client.Account(id).EmailCampaigns() / .EmailCampaign(id) covering the full contract: list (token/per_page/search filter), get, create, update, delete (204 → Task), the five lifecycle actions (Start, Schedule, Cancel, Terminate, Reset), and GetStats with an optional date window
  • Models follow the published OpenAPI schema: flat request bodies (request DTO envelopes removed), data-envelope response DTOs (Webhooks precedent), int64 DomainId/DomainName matching the Sending Domains endpoints, Rapid/Gradual delivery modes, 10-value CampaignState, audience id lists, template attributes with BodyHtml/BodyText/MergeTags, per-recipient state-metadata errors
  • FluentValidation: TemplateAttributes.Subject and FromLocalPart required on create; Schedule datetime must be in the future and ≤1 month ahead
  • Example project rewritten for the full lifecycle + README bullet

How to test

  • Run Mailtrap.Example.EmailCampaigns with a real API token and a verified sending domain — create a draft, update design/audience, schedule + cancel, fetch stats, delete
  • Verify a lifecycle 422 (e.g. Cancel on a draft) surfaces the API error message

Note: the endpoint is token-scoped; the resource hangs off Account(...) for API-shape consistency but the URI is /api/email_campaigns (asserted by tests).

Summary by CodeRabbit

  • New Features
    • Added email campaign management to the SDK.
    • Create, list, view, update, and delete campaigns.
    • Start, schedule, cancel, terminate, and reset campaign sending.
    • Retrieve campaign performance statistics with date filters.
    • Added support for campaign templates, delivery modes, recipient targeting, pagination, and validation.
    • Added a complete .NET email campaigns example and README guidance.
  • Tests
    • Added comprehensive unit and integration coverage for campaign workflows, validation, serialization, errors, and statistics.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: d140866e-05c1-4658-8909-d175059a22b5

📥 Commits

Reviewing files that changed from the base of the PR and between a7dd4c8 and 3643f0e.

📒 Files selected for processing (6)
  • examples/Mailtrap.Example.EmailCampaigns/EmailCampaigns.cs
  • src/Mailtrap.Abstractions/IMailtrapClient.cs
  • src/Mailtrap/MailtrapClient.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/EmailCampaignIntegrationTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignResourceTests.cs
💤 Files with no reviewable changes (3)
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignResourceTests.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/EmailCampaignIntegrationTests.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/Mailtrap.Example.EmailCampaigns/EmailCampaigns.cs

📝 Walkthrough

Walkthrough

The PR adds email campaign contracts, models, validation, REST resources, lifecycle operations, statistics retrieval, integration and unit tests, and a runnable console example.

Changes

Email campaigns API

Layer / File(s) Summary
Campaign contracts and validation
src/Mailtrap.Abstractions/EmailCampaigns/*, src/Mailtrap.Abstractions/Core/Models/Pagination.cs
Adds campaign interfaces, lifecycle states, delivery modes, campaign models, request models, pagination, JSON metadata, and validators.
REST resource integration
src/Mailtrap/EmailCampaigns/*, src/Mailtrap/MailtrapClient.cs, src/Mailtrap.Abstractions/IMailtrapClient.cs, src/Mailtrap/Core/Constants/UrlSegments.cs
Adds collection and campaign resources for listing, creation, retrieval, updates, deletion, lifecycle actions, and statistics.
Campaign behavior verification
tests/Mailtrap.UnitTests/EmailCampaigns/*, tests/Mailtrap.IntegrationTests/EmailCampaigns/*
Adds validation, serialization, route, response mapping, CRUD, lifecycle, statistics, error, and JSON fixture coverage.
Example and project discovery
examples/Mailtrap.Example.EmailCampaigns/*, Mailtrap.sln, README.md
Adds a console workflow, runtime settings, solution registration, and a README link for email campaign management.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Application
  participant MailtrapClient
  participant EmailCampaignResource
  participant MailtrapAPI
  Application->>MailtrapClient: resolve email campaign resource
  MailtrapClient-->>Application: return resource
  Application->>EmailCampaignResource: execute campaign operation
  EmailCampaignResource->>MailtrapAPI: send REST request
  MailtrapAPI-->>EmailCampaignResource: return campaign or statistics data
  EmailCampaignResource-->>Application: return mapped result
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.51% 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 covers motivation, changes, testing steps, endpoint scope, and implementation details; the omitted image table is not relevant.
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
@Rabsztok
Rabsztok requested a review from mklocek as a code owner 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: 2

🧹 Nitpick comments (1)
tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignCollectionResourceTests.cs (1)

19-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover collection operations, not only construction.

Add tests for GetAll with token, per_page, and search, plus Create request/response mapping. These are the main behaviors introduced by EmailCampaignCollectionResource and are currently untested.

🤖 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
`@tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignCollectionResourceTests.cs`
around lines 19 - 58, The EmailCampaignCollectionResource tests currently cover
only construction and URI behavior; add coverage for its collection operations.
Extend the test fixture around CreateResource to verify GetAll passes token,
per_page, and search parameters correctly, and verify Create maps the request to
the command and maps the response back to the expected resource model.
🤖 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.EmailCampaigns/EmailCampaigns.cs`:
- Around line 100-115: Change the EmailCampaigns example so
campaignResource.Start is not executed by default; place it behind an explicit
opt-in snippet or command. When opted in and a campaign is started, call
campaignResource.Terminate before cleanup, while preserving stats behavior as
appropriate. Verify the equivalent Mailtrap app example still accurately
reflects this public lifecycle and update it if needed.
- Around line 107-111: Update the GetStats call in the campaign example to use a
statistics window derived from the current execution time, covering the campaign
actions created during that run, instead of fixed May 2026 dates. Keep the
existing stats logging unchanged.

---

Nitpick comments:
In
`@tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignCollectionResourceTests.cs`:
- Around line 19-58: The EmailCampaignCollectionResource tests currently cover
only construction and URI behavior; add coverage for its collection operations.
Extend the test fixture around CreateResource to verify GetAll passes token,
per_page, and search parameters correctly, and verify Create maps the request to
the command and maps the response back to the expected resource model.
🪄 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: e005b093-9047-44b0-9f09-14a1c4114666

📥 Commits

Reviewing files that changed from the base of the PR and between e9a931e and cbeb1ed.

📒 Files selected for processing (61)
  • Mailtrap.sln
  • README.md
  • examples/Mailtrap.Example.EmailCampaigns/EmailCampaigns.cs
  • examples/Mailtrap.Example.EmailCampaigns/Mailtrap.Example.EmailCampaigns.csproj
  • examples/Mailtrap.Example.EmailCampaigns/Properties/launchSettings.json
  • examples/Mailtrap.Example.EmailCampaigns/appsettings.json
  • src/Mailtrap.Abstractions/Accounts/IAccountResource.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/IEmailCampaignCollectionResource.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/IEmailCampaignResource.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/CampaignState.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/DeliveryMode.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaign.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignDeliveryOptions.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignList.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignListFilter.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStateError.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStateMetadata.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStats.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStatsFilter.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignTemplate.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignType.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignsPagination.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/ReplyTo.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/CreateEmailCampaignRequest.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/EmailCampaignTemplateAttributes.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/ScheduleEmailCampaignRequest.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/UpdateEmailCampaignRequest.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Validators/CreateEmailCampaignRequestValidator.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Validators/ScheduleEmailCampaignRequestValidator.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Validators/UpdateEmailCampaignRequestValidator.cs
  • src/Mailtrap.Abstractions/GlobalSuppressions.cs
  • src/Mailtrap.Abstractions/GlobalUsings.cs
  • src/Mailtrap/Accounts/AccountResource.cs
  • src/Mailtrap/Core/Constants/UrlSegments.cs
  • src/Mailtrap/EmailCampaigns/EmailCampaignCollectionResource.cs
  • src/Mailtrap/EmailCampaigns/EmailCampaignResource.cs
  • src/Mailtrap/EmailCampaigns/Responses/EmailCampaignListResponseDto.cs
  • src/Mailtrap/EmailCampaigns/Responses/EmailCampaignResponseDto.cs
  • src/Mailtrap/EmailCampaigns/Responses/EmailCampaignStatsResponseDto.cs
  • src/Mailtrap/GlobalUsings.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Create_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Create_Unprocessable.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/EmailCampaignIntegrationTests.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/GetAll_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/GetDetails_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/GetStats_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Schedule_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Start_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Start_Unprocessable.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Terminate_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Update_Success.json
  • tests/Mailtrap.IntegrationTests/GlobalUsings.cs
  • tests/Mailtrap.IntegrationTests/TestConstants/UrlSegmentsTestConstants.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignRequestValidatorTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignResourceTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/Requests/CreateEmailCampaignRequestTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/Requests/ScheduleEmailCampaignRequestTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/Requests/UpdateEmailCampaignRequestTests.cs
  • tests/Mailtrap.UnitTests/GlobalUsings.cs
  • tests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cs

Comment thread examples/Mailtrap.Example.EmailCampaigns/EmailCampaigns.cs Outdated
Comment thread examples/Mailtrap.Example.EmailCampaigns/EmailCampaigns.cs Outdated
@Rabsztok
Rabsztok requested a review from piobeny July 30, 2026 12:12
@Rabsztok

Copy link
Copy Markdown
Contributor Author

Addressed CodeRabbit review feedback in 8fc13fc:

  • Do not start a real campaign by default (Major): Start() is now gated behind an explicit MAILTRAP_START_CAMPAIGN=true env var opt-in, and when opted in the campaign is Terminate()d before cleanup. The default demo path remains schedule + cancel.
  • Use a runtime-relative statistics window (Minor): GetStats now uses a window derived from the current run time (last 7 days) instead of hardcoded May 2026 dates. Formatting uses CultureInfo.InvariantCulture via a small Program partial member to stay under the CA1506 coupling limit.

Verified: dotnet build examples/Mailtrap.Example.EmailCampaigns clean (0 warnings/errors), dotnet test --filter EmailCampaign — 48/48 passing.

@Rabsztok
Rabsztok marked this pull request as draft July 31, 2026 11:56
@Rabsztok
Rabsztok force-pushed the MT-22401-dotnet-email-campaigns branch from 8fc13fc to 711af62 Compare August 6, 2026 12:13
Decisions:
- Request bodies are flat per the current OpenAPI contract: the Create/Update
  request DTO envelopes and their ToDto() extensions are deleted; the public
  requests are posted directly.
- Single-object and stats responses unwrap the data envelope via internal
  EmailCampaignResponseDto/EmailCampaignStatsResponseDto (Webhooks precedent).
- Delete returns Task via RestResource.DeleteWithStatusCodeResult() to match
  the API's 204 No Content.
- Five lifecycle endpoints (start/schedule/cancel/terminate/reset) POST to
  sub-segments via RestResourceCommandFactory.CreatePost;
  ScheduleEmailCampaignRequest carries a DateTimeOffset validated as future
  and at most 1 month ahead.
- DomainId is a positive int64 sending domain ID (as returned by the Sending
  Domains endpoints) validated with NotNull + GreaterThan(0);
  a TemplateAttributes.Subject required-on-create rule replaces the dropped
  Scheduled/ScheduledFor rules.
Decisions:
- Gate Start() behind MAILTRAP_START_CAMPAIGN=true so the example does not send real emails by default; Terminate() the campaign before cleanup when opted in
- Derive the GetStats window from the current run time (last 7 days) instead of hardcoded May 2026 dates
- Keep the date formatter in a partial Program member to stay under the CA1506 coupling limit for the top-level statements
@Rabsztok
Rabsztok force-pushed the MT-22401-dotnet-email-campaigns branch from 711af62 to 027e001 Compare August 7, 2026 06:26
@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.

🧹 Nitpick comments (1)
tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignRequestValidatorTests.cs (1)

158-164: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test the one-month boundary.

This test only rejects a date two months ahead. A validator that accepts dates more than one month ahead, but less than two months ahead, will still pass.

Add a case such as DateTimeOffset.UtcNow.AddMonths(1).AddDays(1). Assert that it fails validation.

🤖 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
`@tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignRequestValidatorTests.cs`
around lines 158 - 164, Update
Schedule_WithDatetimeMoreThanOneMonthAhead_ShouldFail to use a date just beyond
the one-month limit, such as DateTimeOffset.UtcNow.AddMonths(1).AddDays(1), and
retain the assertion that the Datetime field has a validation error. This must
verify the one-month boundary rather than only rejecting dates two months ahead.
🤖 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
`@tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignRequestValidatorTests.cs`:
- Around line 158-164: Update
Schedule_WithDatetimeMoreThanOneMonthAhead_ShouldFail to use a date just beyond
the one-month limit, such as DateTimeOffset.UtcNow.AddMonths(1).AddDays(1), and
retain the assertion that the Datetime field has a validation error. This must
verify the one-month boundary rather than only rejecting dates two months ahead.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f175993c-5cca-4fc9-8a56-ef627601e810

📥 Commits

Reviewing files that changed from the base of the PR and between c195b56 and 027e001.

📒 Files selected for processing (60)
  • Mailtrap.sln
  • README.md
  • examples/Mailtrap.Example.EmailCampaigns/EmailCampaigns.cs
  • examples/Mailtrap.Example.EmailCampaigns/Mailtrap.Example.EmailCampaigns.csproj
  • examples/Mailtrap.Example.EmailCampaigns/Properties/launchSettings.json
  • examples/Mailtrap.Example.EmailCampaigns/appsettings.json
  • src/Mailtrap.Abstractions/Accounts/IAccountResource.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/IEmailCampaignCollectionResource.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/IEmailCampaignResource.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/CampaignState.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/DeliveryMode.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaign.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignDeliveryOptions.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignList.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignListFilter.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStateError.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStateMetadata.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStats.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStatsFilter.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignTemplate.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignsPagination.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/ReplyTo.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/CreateEmailCampaignRequest.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/EmailCampaignTemplateAttributes.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/ScheduleEmailCampaignRequest.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/UpdateEmailCampaignRequest.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Validators/CreateEmailCampaignRequestValidator.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Validators/ScheduleEmailCampaignRequestValidator.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Validators/UpdateEmailCampaignRequestValidator.cs
  • src/Mailtrap.Abstractions/GlobalSuppressions.cs
  • src/Mailtrap.Abstractions/GlobalUsings.cs
  • src/Mailtrap/Accounts/AccountResource.cs
  • src/Mailtrap/Core/Constants/UrlSegments.cs
  • src/Mailtrap/EmailCampaigns/EmailCampaignCollectionResource.cs
  • src/Mailtrap/EmailCampaigns/EmailCampaignResource.cs
  • src/Mailtrap/EmailCampaigns/Responses/EmailCampaignListResponseDto.cs
  • src/Mailtrap/EmailCampaigns/Responses/EmailCampaignResponseDto.cs
  • src/Mailtrap/EmailCampaigns/Responses/EmailCampaignStatsResponseDto.cs
  • src/Mailtrap/GlobalUsings.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Create_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Create_Unprocessable.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/EmailCampaignIntegrationTests.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/GetAll_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/GetDetails_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/GetStats_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Schedule_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Start_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Start_Unprocessable.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Terminate_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Update_Success.json
  • tests/Mailtrap.IntegrationTests/GlobalUsings.cs
  • tests/Mailtrap.IntegrationTests/TestConstants/UrlSegmentsTestConstants.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignRequestValidatorTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignResourceTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/Requests/CreateEmailCampaignRequestTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/Requests/ScheduleEmailCampaignRequestTests.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/Requests/UpdateEmailCampaignRequestTests.cs
  • tests/Mailtrap.UnitTests/GlobalUsings.cs
  • tests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cs
🚧 Files skipped from review as they are similar to previous changes (53)
  • examples/Mailtrap.Example.EmailCampaigns/Mailtrap.Example.EmailCampaigns.csproj
  • src/Mailtrap/GlobalUsings.cs
  • README.md
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Terminate_Success.json
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/DeliveryMode.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStatsFilter.cs
  • tests/Mailtrap.UnitTests/GlobalUsings.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignDeliveryOptions.cs
  • src/Mailtrap/EmailCampaigns/Responses/EmailCampaignListResponseDto.cs
  • src/Mailtrap/EmailCampaigns/Responses/EmailCampaignStatsResponseDto.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Schedule_Success.json
  • src/Mailtrap.Abstractions/EmailCampaigns/Validators/ScheduleEmailCampaignRequestValidator.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Create_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/GetStats_Success.json
  • tests/Mailtrap.IntegrationTests/GlobalUsings.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Start_Unprocessable.json
  • examples/Mailtrap.Example.EmailCampaigns/appsettings.json
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStateError.cs
  • src/Mailtrap.Abstractions/Accounts/IAccountResource.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/IEmailCampaignCollectionResource.cs
  • examples/Mailtrap.Example.EmailCampaigns/Properties/launchSettings.json
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignList.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Start_Success.json
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignsPagination.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/IEmailCampaignResource.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/GetAll_Success.json
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/UpdateEmailCampaignRequest.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/GetDetails_Success.json
  • tests/Mailtrap.UnitTests/EmailCampaigns/Requests/CreateEmailCampaignRequestTests.cs
  • src/Mailtrap/EmailCampaigns/Responses/EmailCampaignResponseDto.cs
  • tests/Mailtrap.IntegrationTests/TestConstants/UrlSegmentsTestConstants.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Create_Unprocessable.json
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignTemplate.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignCollectionResourceTests.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/ReplyTo.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/EmailCampaignResourceTests.cs
  • tests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cs
  • examples/Mailtrap.Example.EmailCampaigns/EmailCampaigns.cs
  • src/Mailtrap/Core/Constants/UrlSegments.cs
  • tests/Mailtrap.UnitTests/EmailCampaigns/Requests/ScheduleEmailCampaignRequestTests.cs
  • Mailtrap.sln
  • src/Mailtrap.Abstractions/EmailCampaigns/Requests/EmailCampaignTemplateAttributes.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/CampaignState.cs
  • src/Mailtrap.Abstractions/GlobalUsings.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStats.cs
  • src/Mailtrap/Accounts/AccountResource.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignListFilter.cs
  • src/Mailtrap/EmailCampaigns/EmailCampaignCollectionResource.cs
  • src/Mailtrap.Abstractions/GlobalSuppressions.cs
  • src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStateMetadata.cs
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/Update_Success.json
  • tests/Mailtrap.IntegrationTests/EmailCampaigns/EmailCampaignIntegrationTests.cs
  • src/Mailtrap/EmailCampaigns/EmailCampaignResource.cs

Comment thread src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignsPagination.cs Outdated
Decisions:
- Nothing in the payload is campaign-specific, so move it to Core/Models as
  Pagination for the next paginated resource to reuse
- Core.Models is already a global using, so no call site needs a new import

@piobeny piobeny left a comment

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.

We should make decision on the scoping, other then that LGTM

Comment thread src/Mailtrap/Accounts/AccountResource.cs Outdated
Decisions:
- Account(1).EmailCampaigns() and Account(2).EmailCampaigns() hit the same
  token-scoped path and returned identical results, which is misleading
- Follow the Inbound precedent: token-scoped resources hang off IMailtrapClient
- Drop assertions and comments about the account-scoped campaigns path; it does
  not exist, so there is nothing to guard against
Decisions:
- The backend allows deleting only a campaign in the draft state
  (EmailCampaign#validate_soft_delete), not merely a non-sending one
- Examples deleted a campaign after start/terminate, which would 422; a started
  campaign can never return to draft, so they now delete a fresh draft
Decisions:
- Campaigns are an Email Marketing feature, not contact management or Email
  API/SMTP, so they were filed under the wrong heading
@Rabsztok
Rabsztok requested a review from piobeny August 13, 2026 09:45
Comment thread src/Mailtrap.Abstractions/EmailCampaigns/Models/EmailCampaignStats.cs Outdated
…-shaped errors

Decisions:
- Campaign rates were float while the existing SendingStats uses double; one
  numeric type per concept avoids surprising precision differences
- The lifecycle 422 body is oneOf string or array of strings per the spec, but
  only the string branch was covered
@Rabsztok
Rabsztok merged commit b036f92 into main Aug 14, 2026
3 checks passed
@Rabsztok
Rabsztok deleted the MT-22401-dotnet-email-campaigns branch August 14, 2026 07:07
@github-actions github-actions Bot mentioned this pull request Aug 14, 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.

4 participants