Why Do You Need To Track Email?

After sending an email, there is always a requirement to know whether the recipient opened it and if opened then when. You can ask for email read receipt to the user while sending mail, with many email SMTPs like Gmail, Outlook, Yahoo and many more. But that will only be a request.

If recipient ignores or denies the receipt request then you won’t get any information. It can impart a major impact on your email business.

Smart Meter Analytics  can be a simple & logical way to let you come out from this situation. It is bundled with all kind of smart analytic facilities.

For tracking email open, we send a tracking code using PHPMailer library into the body of the email. Then tracking code itself notify us on the opening of that email.Isn’t it cool?also extremely useful.

Let’s begin learning how to track email opening using PHP.


Watch the live demo or download code from the link given below

track-open-email-in-php


For a quick and complete solution, you can use our email marketing service MailGet.


At first, let me tell you the path we’ll move on.

Step 1. Create a PHP web page with name “index.php”. This will serve as our front-end.We’ll send an email and track it from here only.

Step 2. Create a PHP file with name “tracker.php”. There will be our PHP script for two purpose:
a. Send mail using PHP mailer library.
b. Read the log file(email.txt) to track if the email opened.

Step 3. Create a PHP file with name “trackonline.php”. This will be the PHP script to log an entry in a text file also check for the duplicity.

Step 4. Create a JavaScript file with name “myjs.js”. It will make ajax calls to tracker script and handle the responses.


How Things Work – 

For the ease of understanding, I’ve broken the whole working of our program in three parts.

First one right below, takes user input, sends an email with a unique numerical id attached to it. Then read a log file to find a record with the same id send along with the email. If found then fetch the details and display it on index.php page else the mail is not opened yet. Go through the block diagram to understand what I just told you. block-diagram-of-email-open-trackingSecond is the tracking code and the logic is pretty simple.This is the soul which enable us to know about the mail open.When the email is sent, an HTML <img> tag is inserted in the email body which contains the path to our PHP script trackmailonline.php in “src”.

In the third part, Now when the recipient opens the email, the browser sends an HTTP request to our script asking for image file.There we catch the values arrived within the request and log it into an email.txt file. Also, we shouldn’t fraud with the browser so the request is responded with a transparent image of size 1 pixel.


Tutorial Scripts In Detail –

Below are the details of the code used in this tutorial with proper explanation.

index.php

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Email Open Tracking Using PHP</title>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/myjs.js" type="text/javascript"></script>
<link href="css/style.css" rel="stylesheet" type="text/css"/>

</head>
<body>
<div id="main">
<h1>Email Open Tracking Using PHP</h1>
<div id="login">
<h2>Send Email</h2>
<hr/>
<form id="form1" method="post">
<div id="box">
<input type="email" placeholder="To : Email Id " name="mailto" required/>
<input type="text" placeholder="Subject : " name="subject" required/>
<textarea rows="2" cols="50" placeholder="Meassage : This is the fixed message of test email to get notify when it is read...." name="message" readonly ></textarea>
<input type="submit" value="Send" name="send" />
</div>
</form>

<div id="loading-image"><img src="http://www.arabianbusiness.com/skins/ab.main/gfx/loading_spinner.gif" alt="Sending....."/></div>

<form id="form2" method="post">
<div id="view"></div><br><br>
<div id="readstatus"></div>
<input type="submit" value="Track Status" id="track_mail" name="track"/>
</form>
</div>
</div>
</body>
</html>

tracker.php

<?php

require ('phpmailer/PHPMailerAutoload.php');
$from = "formget.dev@gmail.com"; //sender's username
$pwd = "formgetmb"; //sender's password
//---------------------------SEND eMail------------------------------------------------
if (isset($_POST['mailto'])) {
try {
$mail = new PHPMailer(true); //New instance,exceptions enabled with true
$to = $_POST['mailto'];
$subject = $_POST['subject'];
$id = rand(111, 999);
$id.=rand(111, 999);
$body = "This is the fixed message of test email to get notify when it is read.....";
//Below is the image tag with src to our tracknoline.php script page.........
$body .= "<img border='0' src='https://www.formget.com/tutorial/php-email-tracker/trackonline.php?email=$to&id=$id&subject=$subject' width='1' height='1' alt='image for email' >";
$mail->IsSMTP(); // tell the class to use SMTP
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Port = 25; // set the SMTP server port
$mail->Host = "smtp.gmail.com"; // SMTP server
$mail->Username = $from; // SMTP server username
$mail->Password = $pwd; // SMTP server password
$mail->From = $from;
$mail->FromName = "TESTUSER";
$mail->AddAddress($to);
$mail->Subject = $subject;
$mail->AltBody = "Please return read receipt to me."; // optional, comment out and test
$mail->WordWrap = 80; // set word wrap
$mail->MsgHTML($body);
$mail->IsHTML(true); // send as HTML
$mail->Send();

//return foll
echo '<input id="id1" name="id" type="hidden" value="' . $id . '">'
. '<input id="email1" name="email" type="hidden" value="' . $to . '">'
. '<label id="label1">Mail sent to <b>' . $to . '<b></label>';
} catch (phpmailerException $e) {
echo $e->errorMessage();
}
}
////--------------------------READ email.txt------------------------------------------

if (!empty($_POST['id'])) {

$id = $_POST['id'];
$to = $_POST['email'];
$checkid = "Id:" . $id;
$fh = fopen("//d13dcw7qo4xgly.cloudfront.net/tutorial/php-email-tracker/email.txt", "r");
$read = false; // init as false
while (($buffer = fgets($fh)) !== false) {
if (strpos($buffer, $checkid) !== false) {
$a = explode("%",$buffer);
$read = true;
break; // Once you find the string, you should break out the loop.
}
}
fclose($fh);

if ($read == true) {
//$string = $email . " seen the mail on subject: '" . $sub . "' from ip: " . $ipAddress . " on " . $date . " and Id:" . $id . "\n";
echo "<img id=\"closed-image\" src=\"img/envelope-open.png\" alt=\"email not opened\"/><br><p id=\"closed-para\">"
. "Mail sent from <b>" . $from . "</b><br> To <b>" . $to
. "</b><br>has been<div id=\"color-read\"> opened on <b>".$a[1]."</b></div></p>"
. "<input id=\"id1\" name=\"id\" type=\"hidden\" value=\"" . $id . "\">"; //appended hidden input to keep previous data on the page.

} else {
echo "<img id=\"closed-image\" src=\"img/envelope-closed.png\" alt=\"email not opened\"/><br><p id=\"closed-para\">"
. "Mail sent from <b>" . $from . "</b><br> To <b>" . $to
. "</b><br><div id=\"color-not-read\"> Not yet opened......</div></p>"
. "<input id=\"id1\" name=\"id\" type=\"hidden\" value=\"" . $id . "\">"; //appended hidden input to keep previous data on the page.
}
}

trackonline.php

<?php

if (!empty($_GET['email'])) {
$id = $_GET['id'];
$checkid = "Id:" . $id;
$email = $_GET['email'];
$sub = $_GET['subject'];
date_default_timezone_set('Asia/Kolkata');
$date = date('d/m/Y h:i:s a');
$fh = fopen("email.txt", "a+"); //file handler
$a = fgets($fh);
$found = false; // init as false
while (($buffer = fgets($fh)) !== false) {
if (strpos($buffer, $checkid) !== false) {
$found = true;
break; // Once you find the string, you should break out the loop.
}
}
if ($found == false) {
$string = $email."opened the mail with subject:".$sub."on%".$date."% with mailId:".$id."\n";
fwrite($fh, $string);
}
fclose($fh);

//Get the http URI to the image
$graphic_http = '//d13dcw7qo4xgly.cloudfront.net/tutorial/php-email-tracker/blank.gif';

//Get the filesize of the image for headers
$filesize = filesize('blank.gif');

//Now actually output the image requested, while disregarding if the database was affected
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-Disposition: attachment; filename="blank.gif"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . $filesize);
readfile($graphic_http);

//All done, get out!
exit;
}

myjs.js


$(document).ready(function()
{
$('#loading-image').hide();
//-------------------------------------------first ajax call to submit form1 and send email then receieve response HTML-----//
$("form#form1").submit(function()
{
$('#box').slideUp('fast');
$('#loading-image').show();
var d = $("#form1").serialize();
$.ajax({type: 'POST',
url: "tracker.php",
data: d,
dataType: 'html',
success: function(data)
{ $('form#form2').css("display","block");
$('#view').html(data);
$('#loading-image').hide();
$('#track_mail').css("visibility", "visible");
},
error: function() {
alert("oops! something went wrong....");
}
});
return false;
});
//-------------------------------------------first ajax call to submit form1 and send email then receieve response HTML-----//
$("form#form2").submit(function()
{
var d = $("#form2").serialize();
$.ajax({type: 'POST',
url: "tracker.php",
data: d,
dataType: 'html',
success: function(data)
{
$('#readstatus').html(data);
},
error: function() {
alert("oops");
}
});
return false;
});
});

style.css

Includes basic styling of HTML elements.


@import url(http://fonts.googleapis.com/css?family=Raleway);

h1{
text-align:center;
color: black;
font-size: 2em;
margin-top: 40px;
margin-bottom: 40px;
}

#main{
margin: 25px 100px;
font-family: 'Raleway', sans-serif;
}

h2{
background-color: #FEFFED;
text-align:center;
border-radius: 10px 10px 0 0;
margin: -10px -40px;
padding: 30px 40px;
color: black;
font-weight: bolder;
font-size: 1.5em;
margin-top: -1px !important;
// margin-bottom: -19px !important;
}

hr{
border:0;
border-bottom:1px solid #ccc;
margin: 10px -40px;
margin-bottom: 30px;
}

#login{
width:580px;
float: left;
border-radius: 10px;
font-family:raleway;
border: 2px solid #ccc;
padding: 0px 40px 0px;
margin-top: 70px;
margin: 50px;
margin: 0% 25%;
}

input[type=text],input[type=email],input[type=password]{
width:99.5%;
padding: 10px;
margin-top: 8px;
border: 1px solid #ccc;
padding-left: 5px;
font-size: 16px;
font-family:raleway;
}

textarea{
width:99.5%;
padding: 10px;
margin-top: 8px;
border: 1px solid #ccc;
padding-left: 5px;
margin-bottom: 40px;
font-size: 16px;
font-family:raleway;
}

input[type=submit],input[type=button]{
width: 49%;
background-color:#FFBC00;
color: white;
border: 2px solid #FFCB00;
padding: 10px;
font-size:20px;
cursor:pointer;
border-radius: 5px;
margin-bottom: 40px;
margin-left:25%
}

#track_mail{visibility: hidden;}
#track-div{margin-left:25%;}
#loading-image{margin-left:32%;}
#label{margin:0 20%;}
#para{
clear: both;
margin: 0 35%;
}
#view{padding-left:25%;}

form#form2 {
display: none;
}
img#closed-image, img#open-image {
margin: -6px 40% -40px 38%;
}
p#closed-para,div#color-read,div#color-not-read {
margin: 46px;
text-align: center;
line-height: 1.6em;
}
div#color-read{color:green;}
div#color-not-read{color:red;}

Conclusion

After reading the above post, I am sure you will give a try to the script provided and implement it in your own projects as well. Feel free to visit our website again in the future to get in touch with new coding tricks. You can let us know about your feedback in the space provided below  :)