Creating a custom signup form 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 using our table of contents below.
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!
<form action="contact.php" method="POST" onsubmit="return check_the_box()">
<input name="email" type="text" required placeholder="Your Email">
<input name="firstName" type="text" required placeholder="Your Name">
<p>
<a href="#">I've read and agree to the Terms of Service </a>
<input id="chx" type="checkbox">
</p>
<button type="submit" >Newsletter Signup</button>
<p>
<span style="display: none" id="pls"> Please review and tick the Terms of Service box</span>
</p>
</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!
<script type="text/javascript">
var box = document.getElementById("chx");
var alrt = document.getElementById("pls");
function check_the_box(){
if(!box.checked) {
alrt.setAttribute("style","display: inline");
return false
}
else {
return true
}
}
</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:
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
<?php
require 'vendor/autoload.php';
use MailgunMailgun;
$mgClient = new Mailgun('key-UseYourOwnAPIKeyHere');
$domain = 'mydomain.com'; // Use your domain
$uniqueKey = 'thisisalongstringnooneknowsabout'; //Any string will work
$mailingList = 'me@mydomain.com'; // Create a MailingList in the control Panel first
$siteURL = 'http://mysite.com/mailgun';
function SanitizeInputs($var) {
$sane = htmlspecialchars($var, ENT_QUOTES);
return $sane;
}
function SanitizeEmail ($var) {
$sane = htmlspecialchars($var, ENT_QUOTES);
$pattern = "/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$/";
preg_match($pattern, $sane, $res);
$r = $res[0] ? $res[0] : false;
return $r;
}
function SendConfirmationEmail($recipientAddress, $subjectText, $recipientName) {
global $mgClient, $domain, $uniqueKey;
$hashedUnique = MakeConfirmationHash($recipientAddress, $uniqueKey);
$result = $mgClient->sendMessage($domain, array(
'from' => 'confirmation@'.$domain,
'to' => $recipientAddress,
'subject' => $subjectText,
'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>'
));
}
function MakeConfirmationHash($confEmail, $confCode) {
return md5($confEmail.$confCode);
}
function CheckConfirmationHash($confEmail, $confCode) {
global $uniqueKey;
if (md5($confEmail.$uniqueKey) === $confCode) { return TRUE; }
else { return FALSE; }
}
function AddMemberToList($recipientAddress,$recipientName) {
global $mailingList,$mgClient;
$result = $mgClient->post("lists/$mailingList/members", array(
'address' => $recipientAddress,
'name' => $recipientName,
'description' => 'Form Opt In',
'subscribed' => true
));
}
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:
And that’s it, double-opt in respected, a well job done!
<?php
require("functions.php");
if (isset($_POST['email']) && isset($_POST['firstName'])) {
$email = SanitizeEmail($_POST['email']);
$name = SanitizeInputs($_POST['firstName']);
SendConfirmationEmail($email,"Email Subscription Confirmation",$name);
echo "Email Sent to your email! Check your inbox and confirm it! Thank you";
}
$c = isset($_GET['c']) ? SanitizeInputs($_GET['c']) : NULL;
$e = isset($_GET['e']) ? SanitizeInputs($_GET['e']) : NULL;
$n = isset($_GET['n']) ? SanitizeInputs($_GET['n']) : NULL;
if (isset($c) && isset($e)&& isset($n) ) {
$a = CheckConfirmationHash($e, $c);
if ($a) {
echo "Success! Thanks for signing up ";
AddMemberToList($e,$n);
}
else {
echo "Oh Noes! Confirmation went wrong! Did you click on the right link?";
}
}
?>
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!