Audience
On this page:
- Creating a list
- Subscribing to a list
- Specifying first name and last name
- Adding regular attributes
- Adding extra attributes
- Checking if someone is subscribed
- Getting the status of a subscriber
- Getting all list subscribers
- Skipping opt in when subscribing
- Using subscription forms
- Validating subscribers
- Unsubscribing from a list
- Using double opt-in
- Working with tags
- Working with extra attributes
In this section you’ll learn how to programmatically work with email lists & subscribers.
Creating a list
An email list is used to group a collection of subscribers.
You can create a new email list by newing up an EmailList
. The only required field is name
.
$emailList = EmailList::create(['name' => 'my email list name']);
Setting a default sender and reply to
You can set a default email address and from name.
$emailList->update([ 'default_from_email' => 'john@example.com', 'default_from_name' => 'John Doe', ]);
$emailList->update([ 'default_reply_to_email' => 'jane@example.com', 'default_reply_to_name' => 'Jane Doe', ]);
When sending a campaign to this email list these defaults will be used if you send a campaign that doesn’t have a from or reply to of its own.
Specifying the mailers to be used
By default, Mailcoach sends all mails using the default mailer of your Laravel app. In the mailcoach.php
config file, you can override this.
At the time of creating your EmailList, the transactional_mailer
, automation_mailer
, and campaign_mailer
attributes will be set based on your configuration settings. Any future change in your configuration settings will not automatically apply to the EmailList.
You can also override the mailer to be used on the list level by updating the campaign_mailer
attribute with the mailer to be used. Confirmation and welcome mails will be sent using the mailer specified in transactional_mailer
.
$emailList->update([ 'campaign_mailer' => $nameOfMailer, 'automation_mailer' => $nameOfMailer, 'transactional_mailer' => $nameOfAnotherMailer, ]);
Subscribing to a list
This is the easiest way to subscribe to a list:
$emailList->subscribe('john@example.com');
Alternatively you can create a subscriber via the Subscriber
model.
Subscriber::createWithEmail('john@example.com')->subscribeTo($emailList);
Specifying first name and last name
There are attributes named first_name
and last_name
on the Subscriber
model itself. When subscribing you can fill them by passing a second argument to subscribe
.
$subscriber = $emailList->subscribe('john@example.com', [ 'first_name' => 'John', 'last_name' => 'Doe' ]);
Alternatively you can create a subscriber with attributes via the Subscriber
model.
Subscriber::createWithEmail('john@example.com') ->withAttributes([ 'first_name' => 'John', 'last_name' => 'Doe' ]) ->subscribeTo($emailList);
Adding regular attributes
If you need more attributes on a subscriber you can create a migration that adds a field.
Schema::table('mailcoach_subscribers', function (Blueprint $table) { $table->string('job_title')->nullable(); });
To fill the field just add a key to the second array passed to subscribe
.
$subscriber = $emailList->subscribe('john@example.com', ['job_title' => 'Developer']); $subscriber->job_title; // returns 'Developer'
Adding extra attributes
The email_list_subscribers
table has an json field called extra_attributes
. You can use this field to add unstructured data to a subscriber.
When subscribing pass unstructured data as the value of the extra_attributes
key . This data will be saved in extra_attributes
.
$subscriber = $emailList->subscribe('john@example.com', [ 'extra_attributes' => [ 'key 1' => 'value 1', 'key 2' => 'value 2', ], ]); $subscriber->extra_attributes->get('key 1'); // returns 'value 1'; $subscriber->extra_attributes->get('key 2'); // returns 'value 2';
You can read more on extra attributes in this section of the docs.
Checking if someone is subscribed
You can check if a given email is subscribed to an email list.
$emailList->isSubscribed('john@example.com'); // returns a boolean
You can use a subscriber to check to if it is subscribed.
$subscriber->isSubscribed() // returns a boolean;
Getting the status of a subscriber
To get the status of a subscriber
$subscriber->status;
This property can contain three possible values:
-
unconfirmed
: when the list uses double opt-in and the confirmation link wasn’t clicked yet -
subscribed
: when the subscriber is subscribed. -
unsubscribed
: when the subscriber was unsubscribed.
Getting all list subscribers
To get all subscribers of an email list you can use the emailList
you can call subscribers
on an email list.
$subscribers = $emailList->subscribers; // returns all subscribers
To get the email address of a subscriber call email
on a subscriber.
$email = $subscribers->first()->email;
Calling subscribers
on an email list will only return subscribers that have a subscription with a subscribed
status. Subscribers that have unsubscribed or are still unconfirmed (when using double opt-in) will not be returned.
To return all subscribers, including all unconfirmed and unsubscribed ones, use allSubscribers
.
$allSubscribers = $emailList->allSubscribers;
Skipping opt in when subscribing
If double opt-in is enabled on a list, then subscribeTo
won’t result in an immediate subscription. Instead, the user must first confirm, by clicking a link in a mail, before their subscription to the new list is completed.
To immediately confirm someone, and skipping sending the confirmation mail, use subscribeSkippingConfirmation
:
$emailList->subscribeskippingConfirmation('john@example.com');
Alternatively you can use this syntax:
Subscriber::createWithEmail('john@example.com') ->skipConfirmation() ->subscribeTo($emailList);
Using subscription forms
You can accept email list subscriptions coming from external sites by adding a subscription form to that site.
In order to accept incoming form subscriptions you must set allow_form_subscriptions
to true.
$emailList->update(['allow_form_subscriptions' => true]);
Here’s an example form you can embed on an external site to accept subscriptions.
<form method="POST" action="https://domain-where-mailcoach-runs/mailcoach/subscribe/<uuid-of-emaillist>"> <div> <label for="email">Email</label> <input name="email"> </div> <!-- optionally you can include the first_name and last_name field <div> <label for="first_name">First name</label> <input name="first_name"> </div> <div> <label for="last_name">Last name</label> <input name="last_name"> </div> --> <input type="hidden" name="redirect_after_subscribed" value="https://your-site/subscribed" /> <input type="hidden" name="redirect_after_already_subscribed" value="https://your-site/already-subscribed" /> <!-- only required if your list has double opt-in enabled <input type="hidden" name="redirect_after_subscription_pending" value="https://your-site/redirect-after-pending" /> --> <div> <button type="submit">Subscribe</button> </div> </form>
Attaching tags
You can specify one or more tags in an input field named tags
that should be attached to the subscriber when it gets created.
<!-- somewhere in your form --> <input type="hidden" name="tags" value="tagA;tagB">
Only tags that were added on the allowedFormSubscriptionTags
relation of the email list you’re subscribing someone to will be attached. Here’s you can attach tags to that relation.
$tagA = $emailList->tags()->where('name', 'tagA')->first(); $tagB = $emailList->tags()->where('name', 'tagB')->first(); $emailList->allowedFormSubscriptionTags([$tagA->id, $tagB->id]);
A word to the wise
We highly recommend that you turn on confirmation for email lists that allow form subscriptions. This will keep your list healthy. Also consider adding a honeypot to the form to avoid bots from trying to subscribe. When using Laravel, you could opt to use the spatie/laravel-honeypot package.
Validating subscribers
When integrating this package into your app you will likely build a UI where people can subscribe to your list. This package provides a validation rule that verifies that given email address isn’t already on the given email list. You can use it like this:
// in a form request public function rules() { $emailList = EmailList::first(); return [ 'email' => ['email', new Spatie\Mailcoach\Rules\EmailListSubscriptionRule($emailList)] ]; }
You can customize the validation error message publishing the lang files.
php artisan vendor:publish --provider="Spatie\Mailcoach\MailcoachServiceProvider" --tag="mailcoach-translations"
You’ll find the translation files in lang/vendor/mailcoach
. If you need to change the English messages, you can copy the keys from one of the other translation files.
Unsubscribing from a list
You can add an unsubscribe link by adding an {{ unsubscribeUrl }}
placeholder to the HTML of your campaign.
When a subscriber visits the actual unsubscribe URL, a simple message will be displayed to confirming that they have successfully unsubscribed.
To customize this confirmation message, publish the views.
php artisan vendor:publish --provider="Spatie\Mailcoach\MailcoachServiceProvider" --tag="mailcoach-views"
Now we modify the following views in the /resources/views/vendor/mailcoach/landingPages/
directory:
-
unsubscribed.blade.php
-
couldNotFindSubscription.blade.php
Unsubscribing manually
You can also unsubscribe someone manually like this.
$emailList->unsubscribe('john@example.com');
Alternatively, you can call unsubscribe on a subscriber
Subscriber::findForEmail('john@example.com', $emailList)->unsubscribe();
Unsubscribing using an email client
Emails sent have the List-Unsubscribe
header included. This allows for users to unsubscribe from their email client as per RFC2369.
Permanently deleting a subscriber
Behind the scenes, the subscriber won’t be deleted. Instead, the status of the subscription will be updated to unsubscribed
.
If you want to delete the subscription/subscriber entirely, you can call delete
on it.
Subscriber::findForEmail('john@example.com', $emailList)->delete();
The code above will also delete all related subscriptions.
Using double opt-in
To ensure that all subscribers of your email list really wanted to subscribe, you can enable the double opt-in requirement.
EmailList::create([ 'name' => 'My list' 'requires_confirmation' => true, ]);
When calling subscribe
on a list where requires_confirmation
is enabled, a subscription will be created with a status
set to unconfirmed
. An email will be sent to the email address you’re subscribing. The email contains a link that, when clicked, will confirm the subscription. When a subscription is confirmed, its status will be set to subscribed
.
When sending a campaign to an email list, only subscribers that have a subscription with status subscribed
will receive the campaign.
To immediately subscribe someone, and skip sending a confirmation email, you can call subscribeNow
on a list.
Customizing the subscription confirmation response
When a person clicks the email confirmation link, a simple message explaining the result of confirmation is displayed. You can customize that response by publishing the views.
php artisan vendor:publish --provider="Spatie\Mailcoach\MailcoachServiceProvider" --tag="mailcoach-views"
The responses of a confirmation can now be modified in the view inside the /resources/views/vendor/mailcoach/landingPages/
directory. It will contain these blade files:
-
subscribed.blade.php
-
couldNotFindSubscription.blade.php
-
alreadySubscribed.blade.php
Customizing the double opt in mail
You can customize the content of the double opt-in mail.
First, you must publish the views.
php artisan vendor:publish --provider="Spatie\Mailcoach\MailcoachServiceProvider" --tag="mailcoach-views"
After that, the content of the double opt-in mail can be modified in the /resources/views/vendor/mailcoach/mails/confirmSubscription.blade.php
view.
Working with tags
A mailinglist can have one or more tags. These tags can be applied onto the subscribers of that list.
Creating and attaching tags
Here’s how you can create a tag.
$subscriber->addTag('tagA');
The tag named tagA
will be created an associated with the email list of the subscriber and with the subscriber itself.
Tags can be created and associated in one go:
$subscriber->addTags(['tagB', 'tagC']);
Detaching tags
Tags can be detached.
$subscriber->removeTag('tagA'); $subscriber->removeTags(['tagA', 'tagB']);
Detaching a tags will only remove it from a subscriber. It will not be removed from the email list.
Deleting tags
To delete a certain tag from an email list, just call delete
on it.
$emailList->tags()->where('name', 'tagA')->first()->delete();
Syncing tags
You can pass multiple tags names to syncTags
. Tags that do not exist yet will be created. Tags that are already attached but not present in the array passed to syncTags
will be detached from the subscriber.
$subscriber->syncTags(['tagA', 'tagC']);
Working with extra attributes
When subscribing you can add extra attributes. Here’s an example where first_name
and last_name
are added.
$subscription = $emailList->subscribe('john@example.com', [ 'first_name' => 'John', 'last_name' => 'Doe' ]);
When you are adding subscribers from an external form, you can also add extra attributes by using a specific input name pattern attributes['name-of-your-new-attribute']
. This is what that looks like for storing a user’s job.
<input type="text" name="attributes[job]" value="developer">
To make this work, you also have to make sure job
is defined as an allowed extra field on your email list’s field allowed_form_extra_attributes
.
Here are examples of methods to work with those extra attributes.
$subscriber = $subscription->subscriber; // get all extra attributes $subscriber->extra_attributes->all(); // return an array with all extra attributes; // updating an extra attibute $subscriber->extra_attributes->first_name = 'Other name'; $subscriber->save(); // replacing all extra attributes in one go $subscriber->extra_attributes = ['first_name' => 'Jane', 'last_name' => 'Dane']; $subscriber->save(); // returns all models with a first_name set to John $subscriber->withExtraAttributes(['first_name' => 'John'])->get();