2012-06-29 7 views
6

He estado rastreando correos electrónicos durante años usando una imagen "beacon" y para aquellos clientes que permiten que las imágenes se descarguen, ha funcionado muy bien para rastrear cuántas personas han abierto el correo electrónico.Email Open Length Tracking con PHP

Me encontré con el servicio "DidTheyReadIt" que muestra cuánto tiempo el cliente realmente leyó el correo electrónico, lo probé con su servicio gratuito y en realidad está muy cerca de las veces que abrí el correo electrónico.

Tengo mucha curiosidad en cómo logran la capacidad de rastrear esto, estoy seguro de que cualquiera que sea la solución elegida cargará mucho en el servidor/base de datos y que la comunidad responderá con "Detener, No y No ", pero quiero investigar esto y probarlo, incluso si es suficiente para hacer una prueba en el servidor y decir" no, no ".

he hecho un poco buscando en Google y encontré este artículo que tiene una solución básica http://www.re-cycledair.com/tracking-email-open-time-with-php

Hice una prueba con el sueño() dentro de la página imagen Faro:

<?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); 
} 

?> 

El problema con el código anterior (aparte de actualizar la base de datos cada segundo) es que una vez que se ejecuta el script, continúa ejecutándose incluso si el usuario se desconecta (o se mueve a otro correo electrónico en este caso).

Agregué "ignore_user_abort (false);", sin embargo, como no hay conexión con el cliente de correo y los encabezados ya están escritos, no creo que el "ignore_user_abort (false);" puede disparar

miré en el puesto Track mass email campaigns y uno desde el fondo "Haragashi" dice:

"Usted puede simplemente construir un manejador de rastreo que devuelve el byte de imagen de seguimiento a byte Después de cada byte a eliminar la respuesta. y dormir durante un período de tiempo.

Si se encuentra con una corriente excepción que el cliente ha cerrado la dirección de correo (eliminado o cambiado a otra dirección de correo que sabe) cerrado.

en el momento de la excepción usted sabe cuánto tiempo el cliente 'leyó' el correo electrónico ".

¿Alguien sabe cómo podría "simplemente crear un controlador de seguimiento" como este o conocer una solución que pueda implementar en mi código que forzará al código a dejar de funcionar cuando el usuario se desconecte?

Respuesta

1

Creo que el problema es que no se está haciendo una cabecera de redirección de vez en cuando. La razón por la que es necesario es porque una vez que una secuencia de comandos comienza a ejecutarse en PHP + Apache, básicamente ignora el cliente hasta que termina. Si fuerza una redirección cada X segundos, hace que el servidor vuelva a evaluar si el cliente todavía está conectado. Si el cliente no está conectado, no puede forzar la redirección y, por lo tanto, detiene el seguimiento de la hora.

Cuando jugaba un poco con esto, mi código parecía:

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; 
} 

Si se ha programado el ID de cliente, a continuación, por encima de este bloque de código que podría registrar este intento de leer el faro en la base de datos.Fue fácil simplemente incrementar el tiempo en la columna de correo electrónico en 2 segundos cada vez que el servidor forzó una redirección.

+0

Los clientes no siguen tanto los redireccionamientos, por lo que esta es más una respuesta teórica que algo que tiene sentido prácticamente. Además, esto no es lo que citó el OP. – hakre

0

¿no es hacer algo de la misma familia:

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

Gracias por publicar el código de arriba. Lo intenté y cuando hago clic en detener en el navegador, la inserción no se lleva a cabo cuando lo pongo después de $ duration = $ time() - $ time; Intenté poner el inserto db después de la suspensión (1); y se actualizará cada segundo pero si detengo la página el script continúa. – jdublu

+0

Ignorar el aborto del usuario se establece en falso, lo que tiene sentido, no se detiene hasta el tiempo de espera que tampoco está configurado. –

+1

también envía un byte cada vez, de lo contrario PHP no notará si la conexión se cerró. Crea algo de tráfico. – hakre