Track Email Duration Using PHP

I tracked emails for many years using the lighthouse image, and for those clients that let you upload images, it worked just fine to keep track of how many people have opened emails.

I came across the service "DidTheyReadIt", which shows how long the client really reads the letter, I tested it with my free service, and in fact it is pretty close to the time when I opened the letter.

I’m very curious how they achieve the ability to track this, I’m sure that regardless of the solution chosen, it will put a lot of load on the server / database and that many of the community will answer “Stop, No and Dont”, but I want to explore this and try, even if it’s enough to run a test on the server and say "no hell."

I did some search queries and found this article, which has a basic solution http://www.re-cycledair.com/tracking-email-open-time-with-php

I did a test using sleep () on the beacon image page:

<?php set_time_limit(300); //1000 seconds ignore_user_abort(false); $hostname_api = "*"; $database_api = "*"; $username_api = "*"; $password_api = "*"; $api = mysql_pconnect($hostname_api, $username_api, $password_api) or trigger_error(mysql_error(),E_USER_ERROR); mysql_select_db($database_api, $api); $fileName = "logo.png"; $InsertSQL = "INSERT INTO tracker (FileName,Time_Start,Time_End) VALUES ('$fileName',Now(),Now()+1)"; mysql_select_db($database_api, $api); $Result1 = mysql_query($InsertSQL, $api) or die(mysql_error()); $TRID = mysql_insert_id(); //Open the file, and send to user. $fp = fopen($fileName, "r"); header("Content-type: image/png"); header('Content-Length: ' . filesize($fileName)); readfile($fileName); set_time_limit(60); $start = time(); for ($i = 0; $i < 59; ++$i) { // Update Read Time $UpdateSQL = "UPDATE tracker SET Time_End = Now() WHERE TRID = '$TRID'"; mysql_select_db($database_api, $api); $Result1 = mysql_query($UpdateSQL, $api) or die(mysql_error()); time_sleep_until($start + $i + 1); } ?> 

The problem with the above code (except for updating the database every second) is that after running the script, it continues to work, even if the user disconnects (or goes to another message in this case).

I added "ignore_user_abort (false);" however, since there is no connection to the mail client and the headers are already written, I do not think that "ignore_user_abort (false)"; can shoot.

I looked at the message to track massive email campaigns , and one from below "Haragashi" says:

"You can simply create a tracking handler that returns image tracking bytes by byte. After each byte, start the response and sleep for a certain period of time.

If you encounter a closed stream, the client closed the email (deleted or changed to another email that he knows).

During the exception, you know how long the client has been “reading” the email.

Does anyone know how I can “just build a tracking handler” like this, or learn about a solution that I can implement in my code that will cause the code to stop working when the user disconnects?

+6
source share
2 answers

I think the problem is that you do not redirect the header so often. The reason this is necessary is because after running the script in PHP + Apache it basically ignores the client until it is complete. If you force redirects every X seconds, this forces the server to re-evaluate if the client is still connected. If the client is not connected, it cannot force redirection and, therefore, stops time tracking.

When I played with this material, my code looked like this:

 header("Content-type: image/gif"); while(!feof($fp)) { sleep(2); if(isset($_GET['clientID'])) { $redirect = $_SERVER['REQUEST_URI']; } else { $redirect = $_SERVER['REQUEST_URI'] . "&clientID=" . $clientID; } header("Location: $redirect"); exit; } 

If the client ID was set, then above this block of code I would register this attempt to read the beacon in the database. It was easy to simply increase the time on the email column by 2 seconds each time the server forcibly redirected.

+1
source

Could you do something more:

 <?php // Time the request $time = time(); // Ignore user aborts and allow the script // to run forever ignore_user_abort(true); set_time_limit(0); // Run a pointless loop that sometime // hopefully will make us click away from // page or click the "Stop" button. while(1) { // Did the connection fail? if(connection_status() != CONNECTION_NORMAL) { break; } // Sleep for 1 seconds sleep(1); } // Connention is now terminated, so insert the amount of seconds since start $duration = time() - $time; 
0
source

Source: https://habr.com/ru/post/919334/


All Articles