You can download my code for this article here.
Some time ago I had great aspirations of launching a web company that does email tracking and analytics. One of the things that I really wanted to figure out but wasn’t well documented on the web was how to track how long a user had a particular email open. When a company like MailChimp wants to track emails that they are sending out, they put a small image in the email called a “beacon”. When the user opens the email, the beacon image is requested from the server. The server sends the image, but not before it gathers information about the computer requesting it. The works great for checking if an email was opened, or what platform the person is on, but it doesn’t work at all for determining how long the email was open for.
One option that came to mind for checking the open time of an email was long polling. Long polling (in this case) would use Javascript to contact the server every X seconds after the email was loaded. Using those requests, it’d be trivial to find out how long it was open for. Unfortunately, most (if not all) email clients don’t allow the execution of Javascript within emails, so that idea was completely sank. The only option I had left was to use the beacon image to somehow determine open time.
The only option I could think of for using the image beacon without any Javascript was to redirect the image back to itself. After much trial and error, I came up with the following.
//Open the file, and send to user. $fileName = "../img/beacon.gif"; $fp = fopen($fileName, "r"); header("Content-type: image/gif"); while(!feof($fp)) { //Do a redirect for the timing.? sleep(2); if(isset($_GET['clientID'])) { $redirect = $_SERVER['REQUEST_URI']; } else { $redirect = $_SERVER['REQUEST_URI'] . "?clientID=" . $clientID; } header("Location: $redirect"); } |
So what’s happening in this code? First of all, we’re opening a small GIF file that we’re going to pretend to send to the user. The second step is to send a header for an image file to the user so that their mail client expects one to be delivered. This step is important because if the header isn’t sent, the browser/mail client will close the connection. After that, you make the request sleep for a few seconds (as few or as many as you want depending on how granular you want your timing data to be) and then redirect back to the same page. The “if” statement within the while loop is there so you can identify incoming requests and log the data accordingly.
So there you have it. If you’ve ever wondered how people track the open time of an email, it’s probably a method very similar to this. The only caveat to this method is that it relies on the user loading images in an email. However, if you have a large enough sample you can just take the average open time from the users that did open it and be fairly confident with that.
Note: There has been some discussion over on Stack Overflow about this article. You may find it helpful.
7 replies on “Tracking Email Open Time with PHP”
Probably smarter to keep the request open and send a byte every second (or half a second just in case the connection isn’t closed properly and want a bit more accurate time) and see how long the request is open until it’s closed by the client, with a max of a couple of minutes.
Would be very trivial to implement in node.js
To work around the disabled images problem… what about using an iframe or even a css link instead of an image?
BTW Your blog is awesome, nice job!
I hadn’t thought about using an iframe or a css link. Good idea!
How did the css thing turn out ?
I chose not to implement the css link because client support for css varies widely.
its not working with php and mysql
Hi Jack-
I know its been a while.. But I am looking for some code that will track the length of time a recipient is viewing an Email, then fire a pixel after x seconds or minutes. Can you help with this?
Also- Can you clarify if html iFrame works to track opens when image blocking is enabled? Does that technique harm deliverability or have compatibility issues with various email clients?