Как узнать, что email письмо прочитали

Рассмотрим простой, но эффективный метод определения - прочитано ли письмо при электронной рассылке писем.
При создании информационной рассылки для своей компании я озаботился о том, прочитали ли мои подписчики письма. На емайл счетчик не поставишь, скрипты никакие не выполнишь, поэтому нужно искать выход. Самый простой способ — попросить пользователя перейти по ссылке — по понятным причинам может на сработать. Ссылка «отписаться» сработает если пользователю это неинтересно, т.е. получим информацию не совсем ту, что нужна. Выход напросился сам собой.

Если в письме используются какие-либо элементы с Вашего сайта, то нужно просто посчитать количество их скачиваний. Почтовые клиенты весьма примитивны и можно рассчитывать лишь на скачивание изображений. Следовательно делаем скрипт, который выдает простую белую картинку:

<?    $image = imagecreatetruecolor(10,10)       or die('Cannot create image');        imagefill($image, 0, 0, 0xFFFFFF);    header('Content-type: image/png');    imagepng($image);    imagedestroy($image);?>


Проверяем — действительно картинка генерируется. Однако теперь нужно определить уникальный ли посетитель. Простой способ, поставив в письме тег таким образом:
<img src="lynks.ru/images/img.php?i=0b96fca79547b435e644a98ffe3e9bda"/>

где 0b96fca79547b435e644a98ffe3e9bda — это уникальный идентификатор подписчика (MD5 хеш от емайла). Внедряем в html страницу, проверяем в браузере — отображается. Теперь запишем статистику в базу данных:

<?    
// Подключаемся к базе данных
$dbh=mysql_connect ("localhost", "site_textpat", "lynksru") or die ('I cannot connect to the database because: ' . mysql_error());
//Выбираем базу
mysql_select_db ("site_textpat");
//Обновляем запись, инкрементируем количество скачиваний
$query="UPDATE `site_textpat`.`bab_pm_subscribers` SET readed=readed+1 WHERE `bab_pm_subscribers`.`unsubscribeID` ='$i' LIMIT 1" ; //Выполняем запрос. $result = mysql_query($query,$dbh) or die("Invalid query: " . mysql_error());?>

Теперь при каждом скачивании картинки в базе данных увеличивается число скачиваний для заданного идентификатора. Формируем письмо, отправляем для проверки. И тут оказывается, что тот же Gmail просто-напросто игнорирует такие изображения. Нужен какой-то способ интерпретировать стандартные ссылки на картинки как обращения к скрипту. Конечно можно наделать кучу скриптов, но это не рационально.

На помощь приходит mod_rewrite для apache. Чтобы распознать ссылку на картинку и подменить ее ссылкой на скрипт нужно в каталоге скрипта создать файл .htaccess такого вида:

<IfModule mod_rewrite.c>    RewriteEngine on    RewriteRule ([[:alnum:]]+).png$ img.php?i=$1 [L]</IfModule>

Первой инструкцией включаем mod_rewrite, второй регулярным выражением вычленяем из ссылки имя png файла, без расширения. Имя может
  • состоять из цифр и букв: [:alnum:]
  • иметь любое их количество: [[:alnum:]]+
  • имя запоминаем: ([[:alnum:]]+)
  • конец расширение будет .png: ([[:alnum:]]+).png

После пробела указываем что должны получить взамен найденного: img.php?i=$1 [L], где $1 это то, что мы до этого запомнили в скобках, а [L] — инструкция предписывающая на этой операции прекратить обработку URL. Объединяем все в один скрипт:
<?    
//Создаем изображение
$image = imagecreatetruecolor(10,10) or die('Cannot create image');
//заливаем белым
imagefill($image, 0, 0, 0xFFFFFF);
//в заголовке указываем что шлем png изображение
header('Content-type: image/png');
//выводим и уничтожаем
imagepng($image); imagedestroy($image); // Подключаемся к базе данных $dbh=mysql_connect ("localhost", "site_textpat", "lynksru") or die ('I cannot connect to the database because: ' . mysql_error());
//Выбираем базу
mysql_select_db ("site_textpat");
//Обновляем запись, инкрементируем количество скачиваний
$query="UPDATE `site_textpat`.`bab_pm_subscribers` SET readed=readed+1 WHERE `bab_pm_subscribers`.`unsubscribeID` ='$i' LIMIT 1" ; //Выполняем запрос. $result = mysql_query($query,$dbh) or die("Invalid query: " . mysql_error());?>

Теперь изображения в письма можно вставлять обычным способом:
<img src="lynks.ru/images/0b96fca79547b435e644a98ffe3e9bda.png"/>

mod_rewrite сам изменит ссылку и передаст управление нашему скрипту. По крайней мере Gmail, Outlook и даже OpenOffice Writer корректно распознали и отобразили изображение, а счетчик прочтений исправно инкрементировался.

Описанный метод можно использовать практически везде, где нужно посчитать количество открытий html структур, ведь изображения поддерживаются почти везде.