Installation
composer require welp/mailchimp-bundle
Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):
Welp\MailchimpBundle\WelpMailchimpBundle::class => ['all' => true],
Configure
Add MailChimp API credentials to config/packages/welp_mailchimp.yaml:
welp_mailchimp:
api_key: '%env(MAILCHIMP_API_KEY)%'
server: us12 # or your MailChimp server prefix (e.g., eu1)
list_id: 'YOUR_LIST_ID'
merge_fields: # Optional: Map Symfony user fields to MailChimp merge fields
FNAME: first_name
LNAME: last_name
First Use Case: Sync a User
Use the SubscriberManager service to sync a user:
use Welp\MailchimpBundle\Manager\SubscriberManager;
class UserController extends AbstractController
{
public function subscribe(User $user, SubscriberManager $subscriberManager)
{
$subscriberManager->subscribe($user);
// Returns MailChimp subscriber object or throws exception
}
}
Lifecycle Events Hook into Symfony events to auto-sync users:
# config/services.yaml
services:
App\EventListener\MailchimpSyncListener:
tags:
- { name: kernel.event_listener, event: user.registered, method: onUserRegistered }
class MailchimpSyncListener
{
public function onUserRegistered(UserEvent $event, SubscriberManager $subscriberManager)
{
$subscriberManager->subscribe($event->getUser());
}
}
Custom User Provider
Extend FosSubscriberProvider or implement Welp\MailchimpBundle\Provider\UserProviderInterface:
class CustomUserProvider implements UserProviderInterface
{
public function getEmail(UserInterface $user): string
{
return $user->getEmail();
}
public function getMergeFields(UserInterface $user): array
{
return [
'FNAME' => $user->getFirstName(),
'LNAME' => $user->getLastName(),
];
}
}
Register in config:
welp_mailchimp:
user_provider: App\Provider\CustomUserProvider
Webhooks
Register a webhook endpoint in config/routes.yaml:
welp_mailchimp_webhook:
path: /mailchimp/webhook
controller: Welp\MailchimpBundle\Controller\WebhookController::handle
Handle events (e.g., unsubscribes) in a custom listener:
class MailchimpWebhookListener
{
public function onWebhook(MailchimpWebhookEvent $event)
{
if ($event->getType() === 'unsubscribe') {
$this->userManager->softDelete($event->getUser());
}
}
}
Direct API Access
Use the MailchimpClient service for custom API calls:
public function getCampaigns(MailchimpClient $client)
{
$campaigns = $client->get('campaigns');
// Process campaigns...
}
API Rate Limits
$cache = $this->container->get('cache.app');
$cachedLists = $cache->get('mailchimp_lists', function () use ($client) {
return $client->get('lists');
});
Merge Field Mismatches
config match MailChimp’s merge field tags. Use MC_ prefix if needed:
merge_fields:
MC_FNAME: first_name # MailChimp expects MC_ prefix
Webhook Verification
WebhookController, but validate the X-Mailchimp-Signature header:
$signature = $_SERVER['HTTP_X_MAILCHIMP_SIGNATURE'];
$isValid = $client->verifyWebhook($payload, $signature);
Duplicate Subscribers
upsert() instead of subscribe() to avoid duplicates:
$subscriberManager->upsert($user); // Updates if exists, creates if not
Enable API Logging
Add to config/packages/welp_mailchimp.yaml:
welp_mailchimp:
debug: true # Logs API requests/responses to `var/log/mailchimp.log`
Common Errors
400 Bad Request: Validate list_id and merge fields.403 Forbidden: Check api_key and server prefix (e.g., us12).404 Not Found: Ensure the MailChimp list exists in your account.Custom Sync Logic
Override SubscriberManager to add pre/post-sync logic:
class CustomSubscriberManager extends SubscriberManager
{
protected function beforeSubscribe(UserInterface $user)
{
// Add custom logic (e.g., validate email)
}
}
Register as a service:
services:
Welp\MailchimpBundle\Manager\SubscriberManager: '@App\Manager\CustomSubscriberManager'
Async Processing Use Symfony Messenger to offload syncs to a queue (e.g., RabbitMQ):
$message = new SyncMailchimpSubscriber($user);
$this->messageBus->dispatch($message);
Create a handler:
class SyncMailchimpSubscriberHandler
{
public function __invoke(SyncMailchimpSubscriber $message, SubscriberManager $subscriberManager)
{
$subscriberManager->subscribe($message->getUser());
}
}
Batch Sync Sync multiple users efficiently:
$users = $userRepository->findBy(['isNewsletterSubscribed' => true]);
foreach ($users as $user) {
$subscriberManager->upsert($user, false); // Disable auto-commit
}
$subscriberManager->flush(); // Commit all changes at once
How can I help you explore Laravel packages today?