Search by

silvershop-suite / newsletter-campaignmonitor

RVXD

Campaign Monitor ESP adapter for silvershop-suite/newsletter: syncs subscribers to a Campaign Monitor list via a thin Guzzle client, with a webhook back to the local list.

Package info

github.com/silvershop-suite/silvershop-newsletter-campaignmonitor

Type:silverstripe-vendormodule

pkg:composer/silvershop-suite/newsletter-campaignmonitor

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.1 2026-10-19 18:05 UTC

This package is auto-updated.

Last update: 2026-10-19 19:54:39 UTC


README

Campaign Monitor ESP adapter for silvershop-suite/newsletter. It implements the core's NewsletterProvider contract with a thin Guzzle client (no heavy official SDK) and maps subscriber changes to the Campaign Monitor API v3.3, plus a webhook back to the local list.

The core owns capture, consent and double opt-in; this adapter just syncs confirmed subscribers to a Campaign Monitor list and keeps the local status in step via webhooks.

Requirements

  • silvershop-suite/newsletter dev-main (the core — not on Packagist, see Installation)
  • guzzlehttp/guzzle ^7
  • silverstripe/framework ^6, silverstripe/cms ^6, PHP 8.3 / 8.4

silvershop-suite/newsletter hard-requires symbiote/silverstripe-queuedjobs, so the queued sync runner comes in transitively.

Installation

silvershop-suite/newsletter is an RVXD module (not published to Packagist), so it is resolved from a composer repositories entry. The shipped composer.json uses the VCS form:

"repositories": [
    { "type": "vcs", "url": "https://github.com/RVXD/silvershop-newsletter.git" }
]

Then:

composer require silvershop-suite/newsletter-campaignmonitor:dev-main

(A private newsletter repo needs a GitHub token with repo scope, e.g. composer config -g github-oauth.github.com <token>.)

Local development (core not yet pushed)

When you are developing both modules side by side and silvershop-suite/newsletter isn't published yet, point the adapter at your local checkout with a path repository instead of (or in addition to) the VCS entry — this is how the dev site and the standalone clean-room resolve it:

"repositories": [
    { "type": "path", "url": "../silvershop-newsletter" }
]

Configuration

Credentials come from the environment (.env):

SS_CAMPAIGNMONITOR_API_KEY="your-api-key"
SS_CAMPAIGNMONITOR_LIST_ID="your-list-id"
SS_CAMPAIGNMONITOR_WEBHOOK_SECRET="optional-shared-secret"

Then make Campaign Monitor the active provider:

SilverShop\Newsletter\Provider\NewsletterProviderRegistry:
  active: campaignmonitor

Optionally map subscription merge fields to Campaign Monitor custom fields (which must already exist on the list — Name/first+surname is sent natively):

SilverShop\Newsletter\CampaignMonitor\CampaignMonitorProvider:
  custom_field_map:
    Locale: '[locale]'

Configure the Campaign Monitor list as SINGLE opt-in. The core already performs double opt-in (it emails the subscriber a confirm link and only syncs them once confirmed). If the Campaign Monitor list is also set to confirmed opt-in, subscribers would receive a second confirmation email. Single opt-in avoids the double-confirm.

How it maps

Operation Campaign Monitor API v3.3
subscribe / update POST subscribers/{listid}.json (add-or-update; Resubscribe: true)
unsubscribe POST subscribers/{listid}/unsubscribe.json
full resync (sake tasks:NewsletterResync --run) add-or-update for every locally-subscribed record

Authentication is HTTP Basic with the API key as the username.

Webhook (Campaign Monitor → local)

Point a Campaign Monitor webhook at:

https://your-shop.example/newsletter/webhook/campaignmonitor

(append ?secret=<SS_CAMPAIGNMONITOR_WEBHOOK_SECRET> if you set a secret). The core's webhook controller calls this adapter's verifyWebhook() + parseWebhook(), which map Campaign Monitor events to the local status:

Campaign Monitor event Local status
Subscribe Subscribed
Update Subscribed
Deactivate / Unsubscribe Unsubscribed
Bounce Bounced

Development

composer install
composer run lint    # phpcs (PSR-12)
composer run stan    # phpstan (cambis/silverstan, level 5)
composer run test    # phpunit — uses a FakeCampaignMonitorClient, no live HTTP

License

BSD-3-Clause.

Credits

Built and maintained by Remy Vaartjes (remy@xd.nl) — part of the SilverShop-Suite.