Install the Bundle
composer require welp/mailchimp-bundle
Add to config/bundles.php:
return [
// ...
Welp\MailchimpBundle\WelpMailchimpBundle::class => ['all' => true],
];
Configure .env
Add MailChimp API credentials:
MAILCHIMP_API_KEY=your_api_key_here
MAILCHIMP_SERVER=us12 # or your region
MAILCHIMP_LIST_ID=your_list_id
Basic Usage
Inject the MailchimpClient service in a controller or service:
use Welp\MailchimpBundle\Service\MailchimpClient;
public function __construct(private MailchimpClient $mailchimp) {}
public function syncSubscriber(User $user) {
$this->mailchimp->syncSubscriber($user);
}
First Use Case
Sync a user on registration (assuming FosUserBundle):
// src/EventListener/UserRegistrationListener.php
use Welp\MailchimpBundle\EventListener\MailchimpSyncListener;
public function onUserRegistered(UserEvent $event) {
$this->mailchimp->syncSubscriber($event->getUser());
}
FosSubscriberProvider for FosUserBundle:
# config/packages/welp_mailchimp.yaml
welp_mailchimp:
user_provider: welp_mailchimp.user_provider.fos_subscriber
Welp\MailchimpBundle\Provider\UserProviderInterface:
class CustomUserProvider implements UserProviderInterface {
public function getSubscriberData(User $user): array {
return [
'email' => $user->email,
'merge_fields' => [
'FNAME' => $user->firstName,
'LNAME' => $user->lastName,
],
];
}
}
Register in services:
services:
welp_mailchimp.user_provider.custom:
class: App\Service\CustomUserProvider
tags: ['welp_mailchimp.user_provider']
// src/Entity/NewsletterList.php
#[ORM\Entity]
class NewsletterList {
#[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column]
private ?int $id = null;
#[ORM\Column]
private string $mailchimpListId;
}
Configure in welp_mailchimp.yaml:
welp_mailchimp:
list_provider: welp_mailchimp.list_provider.doctrine
// src/EventSubscriber/MailchimpSubscriber.php
use Welp\MailchimpBundle\Event\MailchimpSyncEvent;
public static function getSubscribedEvents(): array {
return [
UserEvents::REGISTERED => 'onUserRegistered',
UserEvents::UPDATED => 'onUserUpdated',
];
}
public function onUserRegistered(UserEvent $event) {
$this->mailchimp->syncSubscriber($event->getUser());
}
welp_mailchimp:
merge_fields:
FNAME: first_name
LNAME: last_name
CUSTOM_FIELD: custom_attribute
getMergeFields() in custom providers.welp_mailchimp:
webhooks:
- url: /mailchimp/webhook
events: ['subscribe', 'unsubscribe', 'cleaned']
public function handleWebhook(Request $request, MailchimpClient $mailchimp) {
$payload = json_decode($request->getContent(), true);
$mailchimp->processWebhook($payload);
}
Mailchimp client for custom requests:
$lists = $this->mailchimp->getClient()->lists->getAllLists();
Service Container
Bind the bundle’s services to Laravel’s container in config/services.php:
'mailchimp' => \Welp\MailchimpBundle\Service\MailchimpClient::class,
Event Dispatcher Use Laravel’s event system alongside Symfony events:
use Illuminate\Support\Facades\Event;
Event::listen(UserRegistered::class, function ($user) {
app('mailchimp')->syncSubscriber($user);
});
Configuration
Merge bundle config with Laravel’s .env:
// config/mailchimp.php
return [
'api_key' => env('MAILCHIMP_API_KEY'),
'server' => env('MAILCHIMP_SERVER'),
'list_id' => env('MAILCHIMP_LIST_ID'),
'merge_fields' => [
'FNAME' => 'first_name',
// ...
],
];
Middleware for Webhooks Protect webhook endpoints with Laravel middleware:
Route::post('/mailchimp/webhook', [MailchimpController::class, 'handleWebhook'])
->middleware('signed'); // Laravel's signed middleware
API Rate Limits
$this->mailchimp->getClient()->setCache(new FilesystemCache('/tmp/mailchimp'));
Merge Field Conflicts
FNAME).Webhook Verification
MailchimpWebhookVerifier service:
if (!$this->mailchimp->verifyWebhook($request)) {
abort(403, 'Invalid webhook signature');
}
User Provider Mismatch
UserProvider, ensure getSubscriberData() returns an array with:
email (required)merge_fields (optional but recommended)status (e.g., 'subscribed', 'unsubscribed').List ID Mismatch
MAILCHIMP_LIST_ID in .env. Syncs will fail silently if the ID is incorrect.Doctrine List Provider Caching
DoctrineListProvider, cache the list ID to avoid repeated DB queries:
$listId = $this->mailchimp->getListProvider()->getListId();
$this->mailchimp->getClient()->lists->getList($listId);
Enable API Logging
Configure the Mailchimp client to log requests:
$client = $this->mailchimp->getClient();
$client->setLogger(new MonologLogger([
new StreamHandler(__DIR__.'/../logs/mailchimp.log', Monolog\Logger::DEBUG),
]));
Test Webhooks Locally Use ngrok to expose a local endpoint for testing webhooks:
ngrok http 8000
Configure the webhook URL in MailChimp to point to your ngrok endpoint.
Validate Subscriber Data
Use the validateSubscriberData() method to check data before syncing:
if (!$this->mailchimp->validateSubscriberData($user)) {
throw new \RuntimeException('Invalid subscriber data');
}
MailchimpClient to add custom sync logic:
class CustomMailchimpClient extends MailchimpClient {
public function syncWithCustomLogic(User $user) {
$data = $this->getUserProvider()->getSubscriberData($user);
// Add custom logic (e.g., tagging)
$data['tags'] = ['vip'];
$this->getClient()->lists->addOrUpdateMember(
$this->getListId(),
$
How can I help you explore Laravel packages today?