Installation
composer require welp/mailchimp-bundle
Enable the bundle in config/bundles.php:
Welp\MailchimpBundle\WelpMailchimpBundle::class => ['all' => true],
Configuration Publish the default config:
php bin/console config:dump-reference WelpMailchimpBundle
Update config/packages/welp_mailchimp.yaml with your MailChimp API key and list ID:
welp_mailchimp:
api_key: 'your_api_key-us12' # Format: key-usXX
list_id: 'your_list_id'
merge_fields: ['FNAME', 'LNAME', 'EMAIL'] # Optional
First Use Case: Sync a User
Use the MailchimpSubscriberManager service to sync a user:
use Welp\MailchimpBundle\Manager\MailchimpSubscriberManager;
public function subscribeUser(User $user)
{
$manager = $this->container->get(MailchimpSubscriberManager::class);
$manager->subscribe($user);
}
Subscriber Synchronization
FosSubscriberProvider (if using FOSUserBundle) or implement a custom UserProvider:
class CustomUserProvider implements UserProviderInterface
{
public function getEmail(User $user): string { ... }
public function getMergeFields(User $user): array { ... }
}
config/packages/welp_mailchimp.yaml:
welp_mailchimp:
user_provider: 'App\Service\CustomUserProvider'
List Management
DoctrineListProvider (requires Doctrine):
welp_mailchimp:
list_provider: 'Welp\MailchimpBundle\Provider\DoctrineListProvider'
Lifecycle Events
postPersist, postUpdate):
// In a Doctrine listener
$manager->subscribe($user); // On user creation/update
$manager->unsubscribe($user); // On user deletion
Merge Fields
FNAME, LNAME) from your user model:
welp_mailchimp:
merge_fields:
FNAME: 'first_name' # Maps to user property
LNAME: 'last_name'
Webhooks
config/routes.yaml:
welp_mailchimp_webhook:
path: /mailchimp/webhook
controller: Welp\MailchimpBundle\Controller\WebhookController::handle
WebhookController:
public function handle(Request $request): Response
{
$this->mailchimpWebhook->verify($request);
// Process webhook data...
}
Laravel-Specific Adaptation
Replace Symfony’s UserProvider with Laravel’s User model:
class LaravelUserProvider implements UserProviderInterface
{
public function getEmail(User $user): string
{
return $user->email;
}
public function getMergeFields(User $user): array
{
return [
'FNAME' => $user->first_name,
'LNAME' => $user->last_name,
];
}
}
Service Container Binding
Bind the MailchimpSubscriberManager in Laravel’s AppServiceProvider:
public function register()
{
$this->app->bind(MailchimpSubscriberManager::class, function ($app) {
return new MailchimpSubscriberManager(
$app->make(MailchimpApi::class),
$app->make(UserProviderInterface::class),
$app->make(ListProviderInterface::class)
);
});
}
Batch Processing
Use Laravel’s chunk() for large subscriber lists:
User::chunk(100, function ($users) {
foreach ($users as $user) {
$manager->subscribe($user);
}
});
API Key Format
Invalid API Key or 401 Unauthorized.key-usXX format (e.g., abc123-us12). Check MailChimp’s datacenter.Merge Field Mismatches
400 Bad Request.MailchimpApi service to fetch list fields:
$list = $mailchimpApi->get('lists/' . config('welp_mailchimp.list_id'));
dd($list['merge_fields']); // Debug available fields
Webhook Verification
403 Forbidden.webhook_signature header matches MailChimp’s signature. Use the MailchimpWebhook service:
$this->mailchimpWebhook->verify($request, config('welp_mailchimp.webhook_secret'));
Duplicate Subscribers
Member exists errors during sync.upsert (update if exists, insert if not) via the MailchimpSubscriberManager:
$manager->upsert($user); // Instead of $manager->subscribe()
Rate Limits
429 Too Many Requests.Enable API Debugging
Add this to config/packages/welp_mailchimp.yaml:
welp_mailchimp:
debug: true
Logs will appear in var/log/dev.log (Symfony) or Laravel’s storage/logs.
Test API Connection
Use the MailchimpApi service directly:
$api = $this->container->get(MailchimpApi::class);
dd($api->get('lists')); // Test connection
Symfony vs. Laravel Quirks
app() or resolve() may need adjustments for Symfony services.EventDispatcher with Laravel’s Events facade if using lifecycle hooks.Custom API Requests
Extend the MailchimpApi service to add custom endpoints:
$api->post('lists/' . $listId . '/members', [
'email_address' => $email,
'status' => 'subscribed',
'merge_fields' => $mergeFields,
]);
Custom List Provider
Implement ListProviderInterface for dynamic list selection:
class DynamicListProvider implements ListProviderInterface
{
public function getListId(): string
{
return request()->input('list_id') ?? config('welp_mailchimp.list_id');
}
}
Webhook Handlers
Extend the WebhookController to handle specific events (e.g., subscribe, unsubscribe):
public function handle(Request $request): Response
{
$this->mailchimpWebhook->verify($request);
$event = $request->request->get('type');
if ($event === 'subscribe') {
$this->handleSubscribe($request);
}
return new Response('OK');
}
Async Processing Use Laravel’s queues to offload sync tasks:
dispatch(new SyncMailchimpSubscriber($user));
Implement the job:
class SyncMailchimpSubscriber implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable;
public function handle()
{
$manager->subscribe($this->user);
}
}
How can I help you explore Laravel packages today?