intracto/campaign-monitor-bundle
Symfony bundle that integrates the Campaign Monitor email marketing API into your application, providing configured services for managing subscriber lists, adding and updating subscribers, and working with campaigns. Credentials and API clients are wired through bundle configuration, keeping them ou...
What you are actually buying. intracto/campaign-monitor-bundle is a Symfony bundle that (a) holds Campaign Monitor credentials in Symfony's config tree and (b) registers service definitions for campaignmonitor/createsend-php. It is a few hundred lines of glue. The product it "delivers" is saved wiring time, not capability. Frame the decision to stakeholders as "adopt community glue vs. write our own thin wiring," never as a platform or vendor commitment.
Architecture fit. Poor for a Laravel codebase. Laravel has no Symfony bundle kernel, no bundles.php, and no bundle extension lifecycle; the package's only Laravel-usable assets are the config keys and constructor arguments in its Configuration and services files. Everything it provides is reproducible in a single Laravel ServiceProvider in well under a day. The architectural fit question for the TPM is therefore not "how do we integrate this?" but "why would we take a dependency that provides nothing we can natively consume?"
Integration feasibility. Low-to-moderate, and the bundle is not the enabler. The underlying SDK and Campaign Monitor's REST API are straightforward (API key / OAuth, list, subscriber, campaign operations). The friction is entirely on the bundle side: stale Symfony/PHP Composer constraints that will likely conflict with modern Laravel and PHP 8.x, Symfony DI conventions with no Laravel equivalent, and transitive dependencies (older Guzzle) that may collide with Laravel's HTTP client stack. If you consume the SDK directly, feasibility rises to high.
Technical risk. High, and it is concentrated in dependency and ownership risk rather than functional risk.
Key questions to put to engineering before any decision.
createsend-php version does it pin, and is that SDK still maintained and aligned to Campaign Monitor's current API?Recommended stack decision: do not adopt the bundle; adopt the SDK it wraps. Add campaignmonitor/createsend-php directly and treat the bundle as a reference implementation to read once. This keeps the dependency surface smaller, eliminates the Symfony/Laravel mismatch, and moves maintenance onto a dependency that at least has a vendor behind it.
Migration path.
composer.json, DependencyInjection/Configuration.php, and Resources/config/services.* to capture the canonical config keys and wiring — this is the entire reusable content of the package.campaignmonitor/createsend-php directly.CampaignMonitorServiceProvider binding a configured client singleton; move credentials to config/services.php and .env with secret-manager backed rotation.CampaignMonitorGateway) so the vendor is swappable and mockable in tests.Compatibility notes. Expect Composer resolution failures if you attempt to install the bundle against Laravel 10/11 and PHP 8.x; treat that as the expected outcome, not a surprise. If the bundle is used only as a reference, compatibility risk collapses to the SDK's own constraints, which are manageable. Pin the SDK version and record the pin in the dependency register.
Sequencing and decision gates.
Scope framing for stakeholders. The bundle saves roughly a day of wiring. The integration it implies costs roughly five engineer-weeks once queueing, webhooks, error handling, and PII controls are included. Present the estimate against the latter number; the package is a rounding error in both cost and risk.
Maintenance and ownership. The realistic posture is "we own this code," whether or not we fork it. With 0 dependents and no visible maintainership, there is no upstream to lean on. Assign a named owner for the Campaign Monitor integration — credential rotation, SDK upgrades, webhook health, list-state reconciliation — and put it on the team's standing roadmap rather than treating it as a one-time build. Budget a recurring maintenance line (order of a few days per quarter) for dependency and API-drift work.
Support. Effectively none from the package. No issue triage, no security response channel, no community to search. Commercial support for Campaign Monitor itself (now under Marigold/CM Group) is a separate paid relationship and should not be assumed in the plan. If the business depends on deliverability, that commercial relationship is the actual support contract — the package is not.
Scaling. Scaling is bounded by Campaign Monitor's API and account quotas, not by the package, which contributes no caching, connection pooling, or async capability. Two operational constants to plan around: (1) all writes must be queued, because synchronous API calls in request handlers will degrade user-facing latency under load; (2) bulk imports must be batched, chunked, and idempotent, or a single 429 mid-run produces duplicate or missing subscribers that require manual reconciliation.
Failure modes and their business impact.
Ramp-up. For a Laravel team, ramp-up on the bundle is largely wasted — its Symfony idioms do not transfer. Ramp-up on the direct SDK is hours-to-days: the API surface is small and the service-provider pattern is familiar. The genuine ramp-up cost is operational — queue design, retry semantics, webhook verification, idempotency, and PII handling — and that cost exists regardless of which package we choose. Plan and staff accordingly.
TPM recommendation. Treat intracto/campaign-monitor-bundle as a reference document, not a dependency. Commit to a thin, internally owned Laravel integration over campaignmonitor/createsend-php, with explicit ownership, secret management, queueing, webhook handling, and a documented upgrade path. The adoption metrics, the Symfony-versus-Laravel mismatch, and the absence of any capability beyond container wiring make direct adoption a poor risk-adjusted decision — and the decision to avoid it costs us roughly one day of engineering.
How can I help you explore Laravel packages today?