由于自己最近正在找工作,发求职信和简历时想知道对方是否已经看过自己的求职信。后来找到了www.spypig.com,它可以在收信人每次查看你的邮件时发送Email通知你邮件已经被查看过了,并记录查看的次数。使用过程中发现,它的实现原理还很简单,所以就用PHP照着葫芦画瓢自己写了个。
概述
当你想知道自己发送的邮件是否被收信人查看过时,使用电子邮件追踪系统(Email Tracking System)就可以帮助你。
使用方法
打开链接电子邮件追踪系统,输入Email地址和标题,选择接收通知的次数,然后激活获取Tracking Image,在一分钟内将其复制到你的Email邮件正文中,再正常发送邮件就行了。
实现原理
由于标签的src属性会主动引入外部文件,所以将调用“tracker程序”(此程序会正常输出一张图片)的URL作为src的值,并将此放入邮件正文中与之一起发送出去。这样,每当收信人打开该邮件显示该时,都会调用“tracker程序”,这时“tracker程序”会发送email通知你。而邮件也必须是HTML格式的才行。
程序说明
程序共有四部分:
- index.html -- 创建一个Email Tracker的程序界面,需要传递三个参数 - 邮件地址,标题和接收通知的次数。
- tracker.php -- 接收参数产生一个Email Tracker。
- blank.php -- 发送Email通知用户邮件已阅,并生成一个图片。
- msg_template.html -- 通知正文的模板。
代码
创建表的SQL:
email_tracker SQL
CREATE TABLE `email_tracker` (
`unique_id` varchar(50) NOT NULL,
`email` varchar(100) default NULL,
`title` varchar(100) default NULL,
`number` tinyint(4) default '3',
`times` tinyint(4) default '-1',
`ip` varchar(16) default NULL,
`sent_time` int(11) default '0',
PRIMARY KEY (`unique_id`),
UNIQUE KEY `unique_id` (`unique_id`)
) ENGINE=MyISAM;
tracker.php接收参数产生一个新的Email Tracker:
tracker.php
$db = get_db();
$ip = $_SERVER['REMOTE_ADDR']?$_SERVER['REMOTE_ADDR']:'127.0.0.1'; //获取用户IP
$unique_id = get_unique_id($ip); // 产生一个唯一ID
$number = intval($_POST['number']);
$email = trim($_POST['email']);
$title = trim($_POST['title']);
$sent_time = time(); // 作为发送邮件的时间
$db->query("INSERT INTO `email_tracker` (unique_id, email, title, number, ip, sent_time) VALUES ('$unique_id', '$email', '$title', $number, '$ip', '$sent_time')");
用于产生唯一ID的get_unique_id函数:
get_unique_id
function current_microsecond() {
list($usec, $sec) = explode(" ",microtime());
return $sec.substr($usec, 2);
}
// 获取随机数
function random() {
$tmp = rand(0,1)?'-':'';
return $tmp.rand(1000, 9999).rand(1000, 9999).rand(1000, 9999).rand(100, 999).rand(100, 999);
}
// 产生一个伪GUID
// 三段 : 一段是地址 一段是微秒 一段是随机数
function get_unique_id($ip) {
$raw = strtoupper(md5($ip.'-'.current_microsecond().'-'.random()));
return substr($raw,0,8).'-'.substr($raw,8,4).'-'.substr($raw,12,4).'-'.substr($raw,16,4).'-'.substr($raw,20);
}
blank.php由邮件正文中Tracking Image调用,发送Email通知用户邮件已阅,并生成一个图片。
blank.php
if(!($unique_id = trim($_SERVER['QUERY_STRING']))) exit_with_image_blank();
$db = get_db();
$tracker = $db->fetch_one("SELECT * FROM `email_tracker` WHERE unique_id='$unique_id'");
// 记录不存在,或Tracking已经结束
if(empty($tracker) && $tracker['times'] >= $tracker['number']) {
// 输出一个空白图片并退出
exit_with_image_blank();
}
// 邮件发送时到现在经过的时间
$time_elapsed = time() - $tracker['sent_time'];
// 不到一分钟
if($time_elapsed 60) {
if($tracker['times'] 0) { // 还未激活Email Tracker
$db->query("UPDATE `email_tracker` SET times=0 WHERE unique_id='$unique_id'");
}
exit_with_image_blank();
}
// 一分钟之后,times
if($tracker['times'] 0) {
$one_minute_ago = time() - 60;
// 删除所有经过一分钟还未激活的Email Tracker
$db->query("DELETE FROM `email_tracker` WHERE times $one_minute_ago");//unique_id='$unique_id'
exit_with_image_blank();
}
// 获取收信人IP
$rcpt_ip = $_SERVER['REMOTE_ADDR']?$_SERVER['REMOTE_ADDR']:'127.0.0.1';
if($rcpt_ip == $tracker['ip']) {
//与用户IP相同,也许是用户自己打开了Email
$tracker['times']++;
} else {
// 是收信人打开了Email, 查阅次数增加一次
$tracker['times']++;
}
$db->query("UPDATE `email_tracker` SET times=$tracker[times] WHERE unique_id='$unique_id'");
if($tracker['times'] >= $tracker['number']) {
// Tracking已经结束, 删除记录
$db->query("DELETE FROM `email_tracker` WHERE unique_id='$unique_id'");
}
// 发送Email
send_mail('mailtracker0@gmail.com', $tracker['email'], array(
'subject' =>'Your email "'.$tracker['title'].'" has been read!',
'body' =>notify_content($tracker, $rcpt_ip, $time_elapsed),
'headers' =>"MIME-Version: 1.0;\r\nContent-type:text/html; charset=\"utf-8\";\r\n",
'host' =>'smtp.gmail.com',
'ssl' =>true,
'port' =>465,
'auth' =>true,
'user' =>'mailtracker0',
'pass' =>'**********'
));
// 输出一个空白图片并退出
exit_with_image_blank();
send_mail函数用于发送通知邮件:
send_mail
/*
* 参数:
* from required 发信人email
* recipients required 收信人email地址,如果有多个email则以','分隔或传递数组
* params optional 其它可选参数组成的数组
* ----subject 邮件主题
* ----body 邮件正文
* ----headers
* ----host 用于发邮件的SMTP主机
* ----port 端口
* ----timeout 超时时间
* ----ssl 是SSL加密,默认为false
* ----auth 是否要身份验证,默认为false
* ----user 用于身份验证的用户名
* ----pass 用于身份验证的密码
**/
function send_mail($from, $recipients, $params = array()) {
if(empty($from) || empty($recipients) || !is_array($params)) return 'params error.';
define('CRLF', "\r\n");
$port = 25;
$host = 'localhost';
$timeout = 10;
$auth = false;
$ssl = false;
$subject = 'untitled';
foreach ($params AS $key => $value) {
$$key = $value;
}
if(!is_array($recipients)) $recipients = explode(',', trim($recipients));
if(!is_array($headers)) $headers = explode(CRLF, trim($headers));
if(!is_string($body)) $body = '';
$body = str_replace(CRLF . '.', CRLF . '..', $body{0} == '.' ? '.'.$body : $body);
// 连接SMTP服务器
$connection = fsockopen($ssl?'ssl://'.$host:$host, $port, $errno, $errstr, $timeout);
if(!is_resource($connection)) {
return 'Failed to connect to server: '.$errstr;
}
while($line = @fgets($connection, 1024)) if($line{3} == ' ') break;
// 保存命令
$datas = array();
if($auth === true) { // 需要验证身份
$datas[] = array('EHLO '.$host.CRLF, '250', 'EHLO command failed, output: ');
$datas[] = array('AUTH LOGIN'.CRLF , '334', 'AUTH command failed, output: ');
$datas[] = array(base64_encode($user).CRLF, '334', 'AUTH command failed, output: ');
$datas[] = array(base64_encode($pass).CRLF, '235', 'AUTH command failed, output: ');
} else {
$datas[] = array('HELO '.$host.CRLF, '250', 'HELO command failed, output: ');
}
// 设置发信人
$datas[] = array('MAIL FROM: '.$from.'>'.CRLF, '250', 'MAIL FROM error, output: ');
// 设置收信人
foreach($recipients AS $value) {
$datas[] = array('RCPT TO: '.$value.'>'.CRLF, '250', 'RCPT TO error, output: ');
}
$datas[] = array('DATA'.CRLF, '354', 'DATA command failed, output: ');
// 邮件headers
$datas[] = 'From: '.$from.CRLF;
$datas[] = 'Subject: '.$subject.CRLF;
foreach($headers AS $value) {
$datas[] = $value
Stellungnahme:Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn