You Know How I Know You Read My Email?

By  on  

I've probably mentioned this before, but I've designed and coded numerous HTML email templates for my customers. Though I currently use an email service that tracks click-throughs, bounces, and opens, it wasn't always that way. I had to rely on my own methods of tracking click-throughs and opens. Here's how you do it.

Tracking Click-Throughs: The Email HTML

<a href="http://mydomain.com/landing.php?e=email@address.com">Click here</a> for more information!

Tracking Click-Throughs: The PHP

// (inside "landing.php")

if(isset($_GET['e']))
{
	//validate and record click-through here
}

Tracking click-throughs was the easy part. All you do is attach a $_GET variable to the link and listen for that variable on the website. Simple!

Tracking Opens: The HTML

<img src="http://mydomain.com/emails/record.php?e=email@address.com" alt="Tracker" />

Tracking Opens: The PHP

// (inside "record.php")
header('Content-Type: image/gif');

if(isset($_GET['e']))
{
	//validate and record click-through here
}
	
//push out image
if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off');	}
header('Pragma: public'); 	// required
header('Expires: 0');		// no cache
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('blank.gif'));	// provide file size
readfile('blank.gif');		// push it out
exit();

This involves a bit more. You need to first tell the PHP file that it should be served as an image. Then, you read the $_GET variable value and record that the user had requested the file. Lastly, you push out the actual image.

Of course, this isn't the best method of email tracking. You miss bounce reports, forwards, and a host of other important stats. You do, however, get the most important information: who viewed your email?

Recent Features

  • By
    7 Essential JavaScript Functions

    I remember the early days of JavaScript where you needed a simple function for just about everything because the browser vendors implemented features differently, and not just edge features, basic features, like addEventListener and attachEvent.  Times have changed but there are still a few functions each developer should...

  • By
    Conquering Impostor Syndrome

    Two years ago I documented my struggles with Imposter Syndrome and the response was immense.  I received messages of support and commiseration from new web developers, veteran engineers, and even persons of all experience levels in other professions.  I've even caught myself reading the post...

Incredible Demos

  • By
    Control Element Outline Position with outline-offset

    I was recently working on a project which featured tables that were keyboard navigable so obviously using cell outlining via traditional tabIndex=0 and element outlines was a big part of allowing the user navigate quickly and intelligently. Unfortunately I ran into a Firefox 3.6 bug...

  • By
    Implement jQuery&#8217;s hover() Method in MooTools

    jQuery offers a quick event shortcut method called hover that accepts two functions that represent mouseover and mouseout actions. Here's how to implement that for MooTools Elements. The MooTools JavaScript We implement hover() which accepts to functions; one will be called on mouseenter and the other...

Discussion

  1. Jon

    Doesn’t this only work if I allow HTML content in my email program?

  2. @Jon: Correct. Text-only email doesn’t allow for this. Most clients are set up to allow HTML by default.

  3. Gmail also blocks all images by default.

  4. You set the Content-Type header twice, once for jpeg at the top and then again for gif.

  5. @Dan: Thank you for pointing that out. Fixed!

  6. Sebastian Otaegui

    So that is why you need to disable html in your email reader. To avoid email harvesting.

    ’nuff said.

  7. dan

    I am having problems with this script. Instead of blank image, the browser will display the broken image icon. When I look at the source I can see that IMG SRC still shows link to php tracker file.

    What am I missing? Thanks for yor help

  8. @Dan: You do have a “blank.gif” file, correct?

  9. Einer Iriarte

    Greetings and as is the “record.php” not much php, but if I want I could explain how it is please?

  10. antonio

    Hello,

    I´ve included the html code in my newsletter, and create the record.php. I can see the blank.gif but i dont know where the emails are stored and how should i do to get them.

    Regards,
    Antonio.

  11. Nice trick !
    I think on line 2 image type should be image/gif if the image is blank.gif (instead of image/jpeg) ?

    Thanks
    Sylvin

  12. Good catch Sylvin — updated.

  13. have tried eveyrthing but cannot get my to work–use a cable provide– with my old computor worked just fine–new comp s dell

  14. isa

    how comes it can be that you cant view your images on ypur email addres after more than 3 mopnths let me say that its becauyse of the HTML .So how should I go aboutthis let me call it aproblem?

  15. Didier

    Hi, the script is ok and works fine indead, but only if the client doesn’t block is images in his mail program.
    Is this correct??

  16. nabil

    hi, this post is just awesome. a Big thank you David.
    any idea about how to detect forwarded emails ? :p

  17. Raham

    Hi David Walsh!
    First of all if the user does not click on the link then…???
    Now secondly,what if the user has already disable the images in his/her mail then…???

    • Anh Huynh

      …Then nothing happens

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!