Back to blog

Manage Mailchimp subscribers in a Laravel website

Posted

I've been managing my websites subscribers myself but sending my newsletters manually was not ideal so I decided to start using Mailchimp. The free tier is pretty good (up to 2000 contacts and 10.000 emails per month) so that's more than enough for me (at least for now).

In this article I'm going to explain all the necessary steps to integrate the Mailchimp API in a Laravel website.

Get a Mailchimp account

The first think you need to do is to create a Mailchimp account. Once you have completed the initial setup you'd need to create an API key, which we'll use to send our subscriber's details to Mailchimp's API, and find your audience ID.

To generate a new API key, go to Profile > Extras > API Keys and create a new one.

To find your audience ID, go to the Audience page > Settings > Audience Name and campaign defaults. You'll see a section with your audience ID:

Some plugins and integrations may request your Audience ID. Typically, this is what they want: xxxXXXxxxXXXXxxxx

These are the two IDs we need to send the information of our subscribers to Mailchimp.

Integrate with a Laravel website

In order to store our subscribers details in Mailchimp we need to create two components in our Laravel website:

  1. The form the users will use to submit their details
  2. The controller that will handle the form request and send the information to Mailchimp

Create the form

The following form is super basic and has no styling so you can customize it as you want:

<div id="subscribe">
  <!-- Error messages -->
  @if($errors->subscribe->any())
  <div role="alert">
    <ul>
    @foreach ($errors->subscribe->all() as $error)
    <li><strong>{{ $error }}</strong></li>
    @endforeach
    </ul>
  </div>
  @endif

  <!-- Success message -->
  @if (session()->has('message-for') && session()->get('message-for') == 'subscribe')
  <div role="alert">
    <strong>{{session('message-content')}}</strong>
  </div>
  {{session()->forget('flash')}}
  @endif

  <form id="contact-form" action="{{Route('subscriber.store')}}" method="POST">
    @csrf
    <div>
        <input aria-label="Name" name="sub_name" type="sub_name" required  placeholder="Johnny Mnemonic" />
        <input aria-label="Email address" name="sub_email" type="sub_email" required  placeholder="[email protected]" />
    </div>
    <div>
      <button type="submit">Subscribe</button>
    </div>
  </form>

</div>

As you can see, there are main three sections:

  1. Error message container, in case something fails
  2. Success message container, to display a message after user subscribes
  3. The form with two inputs and a submit button

The action of the form points to a route that we haven't created yet. That's our next step.

Create the controller

We're going to create a new controller to handle the subscription request. Run php artisan generate:controller SubscriptionController. Once created go to your routes/web.php file and create a new route to handle POST requests:

Route::post('/subscribe', '[email protected]')->name('subscribe');

This route will point to the store function inside the SubscriptionController that we just created.

There is composer package that is going to simplify a lot the next steps for us. It's named laravel-newsletter and it will help us send the user details to the Mailchimp API. To install it, we just need to run require spatie/laravel-newsletter. Once installed we'll have to run php artisan vendor:publish --provider="Spatie\Newsletter\NewsletterServiceProvider" to generate the config file in /config/newsletter.php . This file has references to the environment variables MAILCHIMP_APIKEY and MAILCHIMP_LIST_ID which we're going to initialise using the values we got from the Mailchimp dashboard.

Open your .env file and create the variables like this:

MAILCHIMP_APIKEY=YourApiKey
MAILCHIMP_LIST_ID=YourAudienceId

Now in our SubscriptionController.php file let's create a store function with the following code:

// For spatie/laravel-newsletter package 
use Newsletter;

class SubscriptionController extends Controller
{
  public function store(Request $request)
  {
    // validator to redirect to an anchor with error named bag
    $validator = Validator::make($request->all(), [
        'sub_email' => 'required|email',
        'sub_name'=> 'required'  
    ]);
    if($validator->fails()){
      // if request does not contain valid email and name
      return Redirect::to(URL::previous() . "#subscribe")->withErrors($validator, 'subscribe');
    }

    if (Newsletter::isSubscribed($request->email) ) {
      //send error, already sub
      $request->session()->flash('message-for', 'subscribe');                
      $request->session()->flash('message-content', 'You were already subscribed!');
      return redirect(url()->previous() . '#subscribe');
      
    }

    // Store name and email in Mailchimp
    Newsletter::subscribe($request->sub_email,['FNAME'=>$request->sub_name]);
    // Add tags to subscriber
    Newsletter::addTags(['website'], $request->sub_email);
    //include success message
    $request->session()->flash('message-for', 'subscribe');                
    $request->session()->flash('message-content', 'Thanks for subscribing ' . $request->name);
    
    return redirect(url()->previous() . '#subscribe');

  }
}

In the code above we're doing the following:

  1. Validate that the request contains a valid email and name
  2. Check if user's email is already subscribed using the isSubscribed() method provided by the Newsletter package (imported on top of the file)
  3. If not subscribed already, subscribe and, optionally, add a tag to our subscriber. Tags can be useful is you have multiple forms in your site and you want to identify from which form it's been submitted.

And that's pretty much it. Give it a try and if the form is submitted with correct details, you'll see the subscriber appears in your Audience within Mailchimp.

Note: You might want to include recaptcha in your form to make sure you don't receive spam in your subscriber list.

Hope you find this article useful.

Happy coding!

Included in categories

coding laravel

Did you enjoy this article? Consider sharing it on social media and following me on Twitter 🤙