- For devs
How to Improve the Way WordPress Websites Send Email
Creating a signup with Mailgun can be trivial. I receive tons of messages from people asking me to write a tutorial on how to do this in PHP so here it is. Before talking code, let’s briefly discuss best practices. If you know everything about double opt-in, skip the next paragraph and move on to the engineering part.
A double opt-in process is a way of verifying that when a person leaves their details in your newsletter sign-up form on your website, that they actually did sign for it. It achieves this by asking you to acknowledge and confirm that your email address has been added to a certain mailing list. How does it do that? Simply by sending you an email and asking you to confirm you really want to receive emails from that sender. If you don’t confirm your subscription (mostly by clicking on a confirmation link within a confirmation email) you should never receive a marketing (or similar) email from that sender.
Marketing people have learned to dislike this practice as it adds one extra step from reaching their audience, but it is important to understand that without this process anyone could be a target of unsolicited email spam
Without double opt-in, anyone that knows your email address could sign you up to thousands of newsletters and marketing lists on your behalf without your consent.
In most countries, this is required by law but either way, I believe it is a best practice and protects your business from stumbling upon deliverability issues and email abuse complaints.
The first thing you will want to do is create a form that you will have somewhere on your website. This form will ask people for their details that you can save in a database or if supported, within the email platform itself. Mailgun supports the latter (and even more when using custom variable parameters), so you don’t have to worry about having to set up a database to hold this data.
The form will post to a file called contact.php
and will have two fields that are mandatory. You can obviously make the name field non-mandatory or add more, but for the purpose of this article, we will keep it simple!
1<form action="contact.php" method="POST" onsubmit="return check_the_box()">2 <input name="email" type="text" required placeholder="Your Email">3 <input name="firstName" type="text" required placeholder="Your Name">4 <p>5 <a href="#">I've read and agree to the Terms of Service </a>6 <input id="chx" type="checkbox">7 </p>8 <button type="submit" >Newsletter Signup</button>9 <p>10 <span style="display: none" id="pls"> Please review and tick the Terms of Service box</span>11 </p>12</form>
Using the below Javascript code will ensure the tickbox has been checked before validation (on submit), otherwise we will not pass the email onwards!
1<script type="text/javascript"> 2 var box = document.getElementById("chx");3 var alrt = document.getElementById("pls");45function check_the_box(){ 6 if(!box.checked) {7 alrt.setAttribute("style","display: inline");8 return false9}10else { 11 return true12}13}14</script>
Feel free to add some style to the form. Right now it’s very basic, but functional.
The interesting part begins here – a file containing all the functions needed to make the form work.
Here is a brief listing of all function created and an explanation of what they do:
SanitizeInputs(): This function is used to clean the userinput from any “damaging” characters
SanitizeEmail(): Same as above but instead, performs a regex check on the email address, we don’t want to send emails to mispelled addresses now do we?
SendConfirmationEmail(): Sends an email to a specified email address, in our case it is the email address specified by the user
MakeConfirmationHash(): Creates a unique hash based on a string concatenation of the user email’s address and a secret string. This string will be sent as part of the URL the user needs to click to verify it wants to receive emails from our site. Secure double opt-in awesomeness.
CheckConfirmationHash(): A function checking that when the user clicks on the confirmation link, the hash contained in the URL is valid. This is very important for the double opt-in procedure, otherwise, anyone could verify each other’s email address.
You can change the text of the email as you wish. Keep in mind that you will be passing the secret hash, the email address and the name of the user back to the script as GET parameters!
Dependency Alert: I’ve used the official mailgun php library available on GitHub
1<?php2require 'vendor/autoload.php';3use MailgunMailgun;45$mgClient = new Mailgun('key-UseYourOwnAPIKeyHere');6$domain = 'mydomain.com'; // Use your domain7$uniqueKey = 'thisisalongstringnooneknowsabout'; //Any string will work 8$mailingList = 'me@mydomain.com'; // Create a MailingList in the control Panel first9$siteURL = 'http://mysite.com/mailgun';1011function SanitizeInputs($var) {12 $sane = htmlspecialchars($var, ENT_QUOTES);13 return $sane;1415}1617function SanitizeEmail ($var) {18 $sane = htmlspecialchars($var, ENT_QUOTES);19 $pattern = "/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$/";20 preg_match($pattern, $sane, $res);21 $r = $res[0] ? $res[0] : false;22 return $r;23}2425function SendConfirmationEmail($recipientAddress, $subjectText, $recipientName) {2627 global $mgClient, $domain, $uniqueKey;2829 $hashedUnique = MakeConfirmationHash($recipientAddress, $uniqueKey);3031 $result = $mgClient->sendMessage($domain, array(32 'from' => 'confirmation@'.$domain,33 'to' => $recipientAddress,34 'subject' => $subjectText,35 'html' => '<p>Hello, please confirm you want to receive marketing emails from '.$domain.' by clicking on the below link <p><a href="$siteURL/contact.php?c='.$hashedUnique.'&e='.$recipientAddress.'&n='.$recipientName.'">CONFIRMATION</a></p></p><p> This email was sent to'.$recipientName.', at the speed of a bullet, by Mailgun!</a>'36 ));37}3839 function MakeConfirmationHash($confEmail, $confCode) {40 return md5($confEmail.$confCode);41 }4243 function CheckConfirmationHash($confEmail, $confCode) {44 global $uniqueKey;45 if (md5($confEmail.$uniqueKey) === $confCode) { return TRUE; }46 else { return FALSE; }47 }4849function AddMemberToList($recipientAddress,$recipientName) {50 global $mailingList,$mgClient;51 $result = $mgClient->post("lists/$mailingList/members", array(52 'address' => $recipientAddress,53 'name' => $recipientName,54 'description' => 'Form Opt In',55 'subscribed' => true 56));57}
For the logic section, I’ll explain the reasoning behind the code.
When the user enters his email address and name inside the box and submits the form, the following happens:
The script generates a unique code and emails it to the user
The user receives an email with a confirmation link, containing information about him and unique code: Clicking on the email will confirm he is okay with his address being part of our mailing list.
Clicking the URL sends back details of the user who are checked against the unique code and triggers his addition to the mailing list on Mailgun.
And that’s it, double-opt in respected, a well job done!
1<?php23require("functions.php");45if (isset($_POST['email']) && isset($_POST['firstName'])) { 6 $email = SanitizeEmail($_POST['email']);7 $name = SanitizeInputs($_POST['firstName']);89 SendConfirmationEmail($email,"Email Subscription Confirmation",$name);1011 echo "Email Sent to your email! Check your inbox and confirm it! Thank you";12}1314$c = isset($_GET['c']) ? SanitizeInputs($_GET['c']) : NULL;15$e = isset($_GET['e']) ? SanitizeInputs($_GET['e']) : NULL;16$n = isset($_GET['n']) ? SanitizeInputs($_GET['n']) : NULL;1718if (isset($c) && isset($e)&& isset($n) ) {19 $a = CheckConfirmationHash($e, $c);20 if ($a) {21 echo "Success! Thanks for signing up ";22 AddMemberToList($e,$n);23 }24 else {25 echo "Oh Noes! Confirmation went wrong! Did you click on the right link?";26 }2728}2930?>
Let me know if you’ve enjoyed this article by sharing your thoughts in the comment box below or on Twitter; and if you’d love to see this tutorial in a different programming language, please let me know.
Happy Sending!
Learn about our Deliverability Services
Looking to send a high volume of emails? Our email experts can supercharge your email performance. See how we've helped companies like Lyft, Shopify, Github increase their email delivery rates to an average of 97%.
Last updated on November 05, 2020
How to Improve the Way WordPress Websites Send Email
What’s Cool About COIL
How To Use Parallel Programming
Sending to the Wrong Segment - Misfit Email Series
How we built a Lucene-inspired parser in Go
Gubernator: Cloud-native distributed rate limiting for microservices
What Toasters And Distributed Systems Might Have In Common
Pseudonymization And You – Optimizing Data Protection
Same API, New Tricks: Get Event Notifications Just In Time With Webhooks
Sending Email Using The Mailgun PHP API
InboxReady x Salesforce: The Key to a Stronger Email Deliverability
Become an Email Pro With Our Templates API
Google Postmaster Tools: Understanding Sender Reputation
Navigating Your Career as a Woman in Tech
Implementing Dmarc – A Step-by-Step Guide
Email Bounces: What To Do About Them
Announcing InboxReady: The deliverability suite you need to hit the inbox
Black History Month in Tech: 7 Visionaries Who Shaped The Future
How To Create a Successful Triggered Email Program
Designing HTML Email Templates For Transactional Emails
InboxReady x Salesforce: The Key to a Stronger Email Deliverability
Implementing Dmarc – A Step-by-Step Guide
Announcing InboxReady: The deliverability suite you need to hit the inbox
Designing HTML Email Templates For Transactional Emails
Email Security Best Practices: How To Keep Your Email Program Safe
Mailgun’s Active Defense Against Log4j
Email Blasts: The Dos And Many Don’ts Of Mass Email Sending
Email's Best of 2021
5 Ideas For Better Developer-Designer Collaboration
Mailgun Joins Sinch: The Future of Customer Communications Is Here
Always be in the know and grab free email resources!
By sending this form, I agree that Mailgun may contact me and process my data in accordance with its Privacy Policy.