Over the past couple years I've run into various frustrations with both open source email list applications and paid cloud-based providers. In this tutorial, I'll guide you through my adoption of Mailgun.com, an economical solution I've been using successfully now for two years.
Open source PHPList was always fairly complex, and I lost interest when they began to overhaul their user interface in directions that seemed more complicated, not less. In the middle of my initiative signature gathering campaign in Seattle, Mailchimp disabled my email list, saying that I didn't properly get permissions from members—even though each had personally given our campaign their email on paper forms. Then I discovered Mailgun and decided to build my own solution, which I've been using every since.
Mailgun is a cloud-based SaaS email cannon, like SendGrid. It's actually free for up to 10,000 emails per month. Mailgun is incredibly powerful and offers a well-documented API in a variety of popular languages. It provides for both send and receive capabilities, the latter of which can be quite difficult to develop from scratch. While Mailgun doesn't provide templates for rich HTML newsletters, it provides a platform upon which you can build anything.
I use Mailgun's list services to communicate with friends and reach out to my social communities, and also for business and marketing outreach. For most of my needs, simple HTML broadcast emails work well.
In this tutorial, I'm going to guide you through ListApp, an applet that builds on the Mailgun List API. In a follow-up tutorial, I'll guide you through building your own email list schema on native PHP and MySQL. Each approach has its own advantages.
If you primarily want to broadcast and want to use Mailgun's own cloud-based web-user interface for managing your list, ListApp may be the best option. Here's an example of Mailgun's web-based user interface for managing lists:
Using ListApp, the master copy of your list is maintained in the cloud at Mailgun and synchronized locally via the API to your installation of ListApp.
If you may want to build group email lists or want more fine-grained control over your email and addressing needs, then you may want to learn how to build list features from scratch. In the next tutorial, we'll still rely on the Mailgun engine and API, but we'll manage lists in the application instead of with Mailgun's List API. This also avoids the complexity of synchronization.
The Open Source ListApp
ListApp provides a simple web-based front end for common scenarios you might use with Mailgun's mailing list features:
- synchronizing your lists and list members from the Mailgun cloud
- creating, updating and deleting lists
- importing members to a list
- sending messages to lists
You can install ListApp on any LAMP-based system. I've posted my generic guide to installing an Ubuntu LAMP server for reference. The app includes instructions for setting up ListApp on an Ubuntu server with 1 GB RAM. It requires PHP 5.x, MySQL 5.x, and the PEAR and cURL libraries.
ListApp is written in the Yii Framework for PHP. You don't need to know anything about the Yii framework to run the application. If you prefer not to use Yii, you can build on the Yiigun component used in ListApp. Yiigun.php is essentially a PHP class file with methods and helpers for leveraging the Mailgun Mailing List SDK.
You'll need to sign up for a free (or higher level) Mailgun account in order to get your API keys for the settings file. If you have a paid account, you'll need to add your domains and create DNS settings for using them. If you use a free account, your domain will be yourchoice.mailgun.org. Therefore, your list addresses can be [email protected]. Your Mailgun API keys will be shown on the control panel home page.
How to Use the Mailgun List API
Using the Mailgun Mailing List API is very straightforward. Mailgun provides its own Mailing List API documentation to assist us. You can review how ListApp uses the Mailgun API in our Yiigun.php component. ListApp uses the Mailgun PHP SDK to interact with Mailgun.
Initializing the Mailgun PHP SDK
Be sure to follow the instructions for configuring your API keys during the installation. Whenever the Yiigun class is used, the constructor is called, creating a secure initialization with Mailgun's API:
function __construct() { // initialize mailgun connection $this->mg = new Mailgun(Yii::app()->params['mailgun']['api_key']); }
Creating a List
You can create new mailing lists by using the menu options on the right of ListApp. Each list requires a name, list email address and description. When you create a new list, ListApp uploads the list and its settings to Mailgun as well. You can also update the properties for any list.
Here's how we create a new list:
public function listCreate($newlist) { $result = $this->mg->post("lists",array('address'=>$newlist->address,'name'=>$newlist->name,'description' => $newlist->description,'access_level' => $newlist->access_level)); return $result->http_response_body; }
Here's how we update mailing list properties:
public function listUpdate($existing_address,$model) { $result = $this->mg->put("lists/".$existing_address,array( 'address'=>$model->address, 'name' => $model->name, 'description' => $model->description, 'access_level' => $model->access_level )); return $result->http_response_body; }
Importing Members to the List
You can import new members to any list from ListApp. We use PEAR's email list parsing libraries for this feature. You can paste in any list of email addresses in the form Personal Name <[email protected]>
, separated by commas or new lines. ListApp will add the members locally and upload them to Mailgun.com.
To add members in bulk, first we create a JSON string of the new members to upload—here's some sample code that you might use.
$json_upload ='[' foreach ($addresses as $i) { $json_upload.='{'; $json_upload.='"name": "'.$i->name.'", '; $json_upload.='"address": "'.$i->address.'"'; $json_upload.='},'; } $json_upload.=']';
Then we call the bulk upload function with this JSON string:
public function memberBulkAdd($list='',$json_str='') { $result = $this->mg->post("lists/".$list.'/members.json',array( 'members' => $json_str, 'subscribed' => true, 'upsert' => 'yes' )); return $result->http_response_body; }
You can add individual members to lists as well, using the Add a Member menu option.
Sending a message
You can send a message to any list using the menu on the right. We deliver the outbound message to Mailgun like any other message. The $to
address is actually the Mailgun mailing list address, such as [email protected]:
public function send_simple_message($to='',$subject='',$body='',$from='') { if ($from == '') $from = Yii::app()->params['supportEmail']; $domain = Yii::app()->params['mail_domain']; $result = $this->mg->sendMessage($domain,array('from' => $from, 'to' => $to, 'subject' => $subject, 'text' => $body, )); return $result->http_response_body; }
Mailgun then manages the delivery of the message to individual recipients.
You can see more examples of the Mailgun List API in action here.
You can also use some of the generic Mailgun recipient variables to include personal salutations, such as Hi %recipient_fname%
(see the Template Variables documentation).
Synchronizing Lists and List Members
You can also manage your lists through the Mailgun web user interface. Then, when you open ListApp, click on the Synchronize option. This will fetch copies of all the existing mailing lists at Mailgun and download all their members into the local database. It essentially synchronizes down your mailing list from the Mailgun.com site. This option does not synchronize up.
Here's the fetchLists
function. Using the Mailgun PHP SDK makes this quite simple:
public function fetchLists() { $result = $this->mg->get("lists"); return $result->http_response_body; }
Here's how we fetch members:
public function fetchListMembers($address) { $result = $this->mg->get("lists/".$address.'/members'); return $result->http_response_body; }
Extending ListApp
The current version of ListApp talks to Mailgun in real time and does not have extensive error handling. Longer term, it would be good to add asynchronous, queued API requests.
In addition to Mailgun's own Mailing List API documentation (which includes examples in cURL, Ruby, PHP, Python, Java and C#), you can review, extract and adapt the Yiigun.php file and its functions for your own PHP application or framework.
If you don't use Yii, you'll need to use composer to install the SDK per Mailgun's installation instructions.
What You've Learned
Now you have an applet that can build and manage cloud-based lists through the Mailgun API and use these to keep your friends, colleagues and clients informed and up to date. In part two, I'll show you how to build email lists natively in PHP and MySQL. We'll still rely on the Mailgun engine and API, but we'll manage lists in the application instead of with Mailgun's List API.
Please feel free to post your questions and comments below. You can also reach me on Twitter @reifman or email me directly. Follow my Tuts+ instructor page to see future articles in this series.
Comments