Question

I am working on an email system (PHP based) where hundreds of emails will be sent by the users and i want to track those emails so i will be able to know that email is opened or not ?

Can any one guide me how to do this ?

Thanks

Was it helpful?

Solution

The only way I know of - and it's not very reliable - is to send an HTML mail in which you include something like:

PHP Code:

<img src='http://www.domain.com/mailcheck.php?user=123'>

image but in the process, you can track the GET user. You can also find a way to modifier the mail header so as to request a receipt - but I don't know how to do that - and it's also not reliable because of the voluntary nature of the request.

OTHER TIPS

Simple, you set up a PHP script that returns a 1x1 image. Have that script log the User-Agent and the IP (You can even log the referrer).

Now embed that in the email.

Since gmail has started showing the image always, but will host them from its own servers, you can although get to know if the mail is opened, but you might not be able to track the correct IP. Check some reference here: Effect of gmail caching and showing images by default

You can get to know how mailchimp does it: MailChimp Working

EDIT: Code reference:

<img src="http://www.example.com/checkopen.php?user_id=20" />

Inside the checkopen.php script, get the user_id field, now corresponding to this field, store it that this user has opened the mail.

While sending the mail, make sure you increment the user_id field everytime you send the mail.

So whenever this image is rendered, it will call the corresponding url and thus you can log into your system about the status of mail being opened.

Email has a disposition notification field which you can use to achieve this. It, of course, depends on the MUA at the remote end. They're free to ignore the MDN (which is a polite request rather than something subversive which the other 2 answers suggest). The MUA of your final recipient will send an email back to you saying that your message has been read. Your SMTP server can filter these and you can run some kind of program that maps sent emails to responses.

While I didn't discover exactly why the simple PHP file wasn't generating the included image, here is another very complicated way of generating an image file that wasn't rejected by my own PHP 5.4.30 web server.

Here is the code that I put into an index.php file within an /email_image/ subdirectory:

<?php
$message_id = $_REQUEST['message_id'];

$graphic_http = 'http://mywebsite.com/email_image/message_open_tracking.gif';

$filesize = filesize( 'message_open_tracking.gif' );

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="a_unique_image_name_' . $message_id  . '.gif"' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Content-Length: '.$filesize );
readfile( $graphic_http );
exit;
?>

For the image filename, I used the following:

http://mywebsite.com/email_image/?message_id=12345

Within the email_image folder is also a blank 1x1 gif image named "message_open_tracking.gif".

The index.php file can also be revised to make use of the message_id in order to mark that message as having been read. If other variables are included within the querystring, such as the recipient's email address, those values can also be used within that index.php file.

Many thanks to Bennett Stone for the following article: http://www.phpdevtips.com/2013/06/email-open-tracking-with-php-and-mysql/

There are many possibilities, which is unfortunate from a client's point of view, because many of them are abused by spammers who want to know whether their mail addresses are "alive".

The most exhaustive list of techniques is listed (and tested) by https://www.emailprivacytester.com

I think from your point of view, the most "kind" solution are the disposition notification headers. Asking for a "reliable" solution, however, opposes the general interest of the recipients that there should not be a way to reliably observe their behavior against their will.

Here is link to complete guide

[ [ Prerequisite: ] ] 1. You need download PHPMailerAutoload.php. 2. Please check your php version. 3. Please check your shared hosting allows phpmailer.

[ [ Privacy Policy ] ] 1. A recipient mail service provider obviously pops up a privacy alert when the recipient opens your email. So if he or she rejects your email, the desirable information could not be gained.

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.

<!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>

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.

<?php

require ('phpmailer/PHPMailerAutoload.php');
$from = "test@gmail.com";    //sender's username
$pwd = "test@1234";         //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.....";
        $body .= "<img border='0' src='https://yourwebsite.com/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("https://yourwebsite.com/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.
    }
}

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.

<?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 = 'https://yourwebsite.com/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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top