strings.no_script

How to Set Up Batch Emails (With Sample Code) - MailerSend

Introducing MailerSend’s batch email feature

Transactional emails are sent immediately when they’re triggered by recipients, but sometimes a scheduled email delivery is preferred to synchronize it with an event. Learn how to set up the batch email feature and download sample code to get started.

Transactional emails, like password resets and order confirmations, are typically sent as soon as they are triggered by recipients. This is great for time-sensitive situations where speedy email delivery gives peace of mind and reassurance.

At other times, a delayed delivery is preferred when recipients share the same transaction. For example, if people have signed up to receive product updates and you wish to notify all of them at once whenever a new app version is released.

You can now set up batch email sending using MailerSend’s new send bulk emails endpoint. Read on to learn how to delay sending email by working with an example using the MailerSend PHP library, then download the sample code to help you get started!

What is bulk email?

In transactional sending, bulk emails are emails sent to recipients who share a common transaction. They are also known as batch emails because they are sent in batches for optimal email deliverability and to avoid overloading email servers.

Note: Bulk emails are also used in email marketing where promotional email campaigns are sent in very large volumes. Subscribers to these emails have opted-in to receive marketing emails and their contents usually contain a call to action.

Bulk email sending in MailerSend

The new bulk email functionality in MailerSend enables you to send a single email to many recipients. You can use the endpoint by including it in a POST request like this:

POST https://api.mailersend.com/v1/bulk-email

If you’re on a Free or Premium plan, you can include 500 individual email objects in a single request, each containing up to 50 TO recipients, 10 CC, and 10 BCC, for a total of 35,000 emails. Otherwise, you are limited to 5 individual email objects.

For speedy sendings and to save you time, bulk emails are sent asynchronously without waiting for an API response. Email validation is also done after the request. You can check for failed emails and validation errors using the bulk_email_id in a GET request:

GET https://api.mailersend.com/v1/bulk-email/{bulk_email_id}

How to schedule batch emails

Here’s an example to help you get started sending batch emails in MailerSend. Let’s say that you’re organizing an event and you want to follow up with everyone who signed up for it. An email reminder will be sent, along with the event schedule as a PDF file, to everyone a few days before the event.

The general workflow to send the email notifications goes like this:

1. Identify the event and guests that you need to send a reminder to

2. Prepare an email message for each guest

3. Schedule emails to send later using a bulk request

The email reminders are sent using the MailerSend PHP SDK, where a cron job will call the PHP routine every minute. Let’s see how you can set up all this in 5 steps!

Note: PHP is used for the example here as it’s one of the easiest scripting languages. If you prefer using another programming language, here’s how you can send emails using other MailerSend SDKs.

1. Set up the database structure

Start by organizing your event data into tables using the following database schema:

  • The events table stores the event name, event date, and the date and time we want to send the email reminders to our guests

  • The guests table contains the guest’s name, email address, the ID of the event that the guest belongs to, and a flag indicating whether a reminder was sent

database schema example
Note: The events table has a one-to-many relationship with guests as one event can have many guests attending it.

2. Create an email template

Compose the email reminder template in MailerSend using the drag & drop template builder. You can also use the rich-text email editor or create a custom design with the HTML editor.

create an email template in mailersend

Each email template will contain the following variables for simple personalization:

  • {$guest_name}, the name of the guest

  • {$event_name}, the name of our event

  • {$date}, the date of the event in the format Month Xth (e.g. October 1st)

  • {$time}, the time of the event in 12-hour format (e.g. 1:00pm)

The email subject line is also customized with the following variables:

  • {$event_name}, the name of the event

  • {$days_left}, how many days are left for the event

  • {$days_label}, which is “days” if the event is more than 1 day away or “day” if the event is tomorrow

Now that you have everything in place to start sending email reminders, let’s get coding!

3. Collect all the relevant information

Use the following PHP code to make an SQL-like query to your database. This will select the guests to the event to whom you haven’t sent a reminder.

/**
* Collect the guest and event information to send the reminder to
* We access the database using Illuminate but you can use whatever you want.
* The following is equivalent to this SQL query:
*
* SELECT guests.*, events.event_name, events.data FROM guests JOIN events ON events.id = guests.event_id
* WHERE guests.reminded = 0 AND events.remind_date <= NOW();
*/
$guestReminders = DB::table('guests')->select(['guests.*', 'events.event_name', 'events.date'])
   ->join('events', 'events.id', '=', 'guests.event_id')
   ->where('guests.reminded', '=', '0')
   ->where('events.remind_date', '<=', 'NOW()')
   ->get();

4. Prepare the email for each guest

To prepare the emails for sending, store each one in an array that you’ll use to make a bulk email request. Guest IDs are stored so you can keep track of which guests you have sent a reminder to. Also, the code is smart enough to know how many day(s) are left until the event, producing a grammatically correct subject line!

// we'll store the emails we want to send in an array that we'll use in the bulk email request
$emails = [];

// we'll store the guest ids so that we can update the ones we sent the reminder to
$sentToGuestIds = [];

// we loop through the collected database records to set up the recipients and variables
foreach ($guestReminders as $guestReminder) {

   $eventDate = DateTime::createFromFormat('Y-m-d H:i:s', $guestReminder->date);
   $currentDate = new DateTime();

   // we want to use a subject like "X days left for our event",
   // so we calculate the number of days between the event data and now
   $daysLeft = $currentDate->diff($eventDate);
   $daysLeft = (int)($daysLeft->days + ceil($daysLeft->h / 24));

   $recipients = [
       new Recipient($guestReminder->email, $guestReminder->name)
   ];

   // if the event is 1 day away, we don't want the subject to be '1 days left for the our event'
   // so we use a label for the word "days" which we change to "day" if the event is 1 day away
   $daysLabel = 'days';
   if ($daysLeft == 1) {

       $daysLabel = 'day';
   }

   // we set up the variables for our email
   $variables = [
       new Variable($guestReminder->email, [
           'guest_name' => $guestReminder->name,
           'event_name' => $guestReminder->event_name,
           'date' => $eventDate->format('F jS'),
           'time' => $eventDate->format('g:ia'),
           'days_left' => (string)$daysLeft,
           'days_label' => $daysLabel
       ])
   ];

   // set up the email
   $email = (new EmailParams())
       ->setFrom('your from email address')
       ->setFromName('your from name')
       ->setRecipients($recipients)
       ->setSubject('Only {$days_left} {$days_label} left for {$event_name}!')
       ->setTemplateId('your template id')
       ->setVariables($variables);

   // if we want to also include the event schedule, we can do the following:
   /*
       $attachments = [
           new Attachment(file_get_contents('schedule.pdf'), 'schedule.pdf')
       ];

       $email->setAttachments($attachments);
   */

   $emails[] = $email;

   // we store the id of each guest we sent the reminder to so that we can update its "reminded" field.
   // that way we prevent sending duplicate reminders to the guests
   $sentToGuestIds[] = $guestReminder->id;

   // there is a limit of 500 emails per bulk request, so if we reach 500 emails,
   // we need to break to send the emails we prepared and continue in the next run
   if (count($emails) == 500) {

       break;
   }
}
Note: As seen in the code comments above, the event schedule can be attached as a PDF file named schedule.pdf. Simply uncomment the code to enable file attachments.

5. Send using the bulk email endpoint

Before sending, check if there are any emails left to send using the following PHP routine. If so, the bulk-email endpoint will be called using your MailerSend API token. Once sent, the reminder flag will be updated to show that an email has been sent.

// we check that we have emails to send and then do a request to the bulk email MailerSend endpoint
if (count($emails) > 0) {

   // init the MailerSend SDK
   $mailersend = new MailerSend(['api_key' => 'your MailerSend token']);

   // send the email
   $mailersend->bulkEmail->send($emails);

   // update the guests that have been reminded
   DB::table('guests')
       ->whereIn('id', $sentToGuestIds)
       ->update(['reminded' => 1]);
}

Since bulk emails are delivered in batches to avoid overloading mailbox providers, you need to check and send reminders every minute. To do this, create a method called checkReminders on a class called EventReminder, calling it from an index file or another entry point. Then start this automation using a cron job:

* * * * * php /home/user/check_reminders/reminders.php

To help you get started with scheduled email delivery, you can download all the sample code and files here.

Schedule your email sendings now

MailerSend’s new bulk email endpoint enables you to delay delivery of batch emails. With more sending options to choose from, you can use triggered emails and scheduled email delivery to match your use case!

Triggered or scheduled emails. Which ones do you use most often and why? Share in the comments below.

Agathe
I'm Agathe, Project Manager at MailerSend. When I'm not busy rolling out new product features, I'm planning my future mud-brick farmhouse complete with farm animals and a vineyard!