|
|
<?php
|
|
|
|
|
|
|
|
|
use Model\folderSql;
|
|
|
|
|
|
require_once "../vendor/autoload.php";
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 预热自动回复
|
|
|
* @author:dc
|
|
|
* @time 2025/7/2 9:58
|
|
|
* Class fob_ai_mail_auto_reply
|
|
|
*/
|
|
|
class fob_hot_ai_mail_auto_reply {
|
|
|
|
|
|
|
|
|
public $isStop = false;
|
|
|
|
|
|
|
|
|
/**
|
|
|
* @var \Lib\Db
|
|
|
*/
|
|
|
public $db;
|
|
|
|
|
|
|
|
|
public $startTime = 0;
|
|
|
|
|
|
/**
|
|
|
* SyncToEsCmd constructor.
|
|
|
*/
|
|
|
public function __construct()
|
|
|
{
|
|
|
$this->db = db();
|
|
|
|
|
|
$handler = function ($signal){
|
|
|
_echo('收到进程信号 '. $signal);
|
|
|
// 可以处理其他程序
|
|
|
$this->isStop = true;
|
|
|
};
|
|
|
pcntl_signal(SIGTERM, $handler); // 这个是kill
|
|
|
pcntl_signal(SIGINT, $handler); // 这个是 ctrl+c
|
|
|
|
|
|
$this->startTime = time();
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* @return bool
|
|
|
*/
|
|
|
public function isStop(): bool
|
|
|
{
|
|
|
// 检查是否接收到信号
|
|
|
pcntl_signal_dispatch();
|
|
|
|
|
|
// 是否超过来最大执行时间
|
|
|
if(time()-43200 > $this->startTime){
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return $this->isStop;
|
|
|
}
|
|
|
|
|
|
protected $bodys = [];
|
|
|
|
|
|
public function getDelayTime(){
|
|
|
/**
|
|
|
* 随机一个延时时间秒 极小的概率30-60分钟,小概率60-120分钟,中概率120-180分钟 大概率180-240分钟
|
|
|
*/
|
|
|
|
|
|
// 生成一个 0 到 100 之间的随机数
|
|
|
$randomValue = rand(0, 100);
|
|
|
|
|
|
// 根据随机值的范围来决定延迟时间
|
|
|
if ($randomValue < 5) { // 5% 的概率
|
|
|
// 随机 30-60分钟
|
|
|
$rand = rand(45, 60) * 60; // 转换为秒
|
|
|
} elseif ($randomValue < 15) { // 10% 的概率 (5% + 10%)
|
|
|
// 随机 60-120分钟
|
|
|
$rand = rand(65, 120) * 60; // 转换为秒
|
|
|
} elseif ($randomValue < 45) { // 30% 的概率 (15% + 30%)
|
|
|
// 随机 120-180分钟
|
|
|
$rand = rand(125, 180) * 60; // 转换为秒
|
|
|
} else { // 55% 的概率 (45% + 55%)
|
|
|
// 随机 180-240分钟
|
|
|
$rand = rand(180, 240) * 60; // 转换为秒
|
|
|
}
|
|
|
|
|
|
return time()+$rand;
|
|
|
}
|
|
|
|
|
|
public function handler(){
|
|
|
|
|
|
$this->bodys = file_get_contents(__DIR__."/body.reply");
|
|
|
$this->bodys = explode("--------------",$this->bodys);
|
|
|
|
|
|
while (!$this->isStop()){
|
|
|
|
|
|
$id = redis()->lPop('new_hot_mail_auto_reply_ids');
|
|
|
if($id){
|
|
|
// 检查是否到时间了
|
|
|
list($did,$time) = explode('.',((string) $id).'.0');
|
|
|
if($time == '0'){
|
|
|
redis()->rPush('new_hot_mail_auto_reply_ids',$id.'.'.$this->getDelayTime());
|
|
|
continue;
|
|
|
}
|
|
|
if($time > time()){
|
|
|
redis()->rPush('new_hot_mail_auto_reply_ids',$id);
|
|
|
usleep(10000);
|
|
|
continue;
|
|
|
}
|
|
|
// 查询数据
|
|
|
$data = $this->db->first(\Model\listsSql::first('`id` = '.$did,'`id`,`email_id`,`subject`,`is_hots`,`from`,`udate`,`uid`'));
|
|
|
if($data && $data['is_hots']){
|
|
|
// 在检查下是否是 收件箱
|
|
|
if($this->db->cache(3600)->value(\Model\folderSql::has(['id'=>$data['folder_id'],'origin_folder'=>'INBOX']))){
|
|
|
_echo('处理 '.$data['id']);
|
|
|
$email = $this->db->throw()->cache(3600)->first(\Model\emailSql::first($data['email_id']));
|
|
|
// 标记已读
|
|
|
$mailInstance = \Lib\Imap\ImapPool::get((new \Lib\Imap\ImapConfig($email)));
|
|
|
if($mailInstance->login()){
|
|
|
$mailInstance->folder('INBOX')->msg()->uid($data['uid'])->seen();
|
|
|
$mailInstance = null;
|
|
|
}
|
|
|
|
|
|
// 来回超过5次就不回了
|
|
|
if(substr_count($data['subject'],"Re:") < 3){
|
|
|
// 有配置才回复
|
|
|
$ret = \Lib\Mail\MailFun::sendEmail([
|
|
|
'subject' => 'Re:'.$data['subject'],
|
|
|
'tos' => [['email'=>$data['from'],'name'=>explode('@',$data['from'])[0]]],
|
|
|
'body' => $this->trimBody($data,$data['subject']),
|
|
|
'mail-header' => [
|
|
|
'Aicc-Hot-Mail' => 'hot' // 预热邮件
|
|
|
]
|
|
|
],$email);
|
|
|
_echo('回复成功'.$data['id']." ".$email['email'].' to '.$data['from']." ".$ret[1]);
|
|
|
}else{
|
|
|
_echo('来回超过5次就不回了 '.$data['id']);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}else{
|
|
|
sleep(1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public function trimBody($data,$inbox){
|
|
|
// 随机body内容
|
|
|
$reply = $this->bodys[array_rand($this->bodys)];
|
|
|
|
|
|
return "<pre>------------------ 原始邮件 ------------------
|
|
|
发件人: {$data['from']};
|
|
|
发送时间: ".date("Y年m月d日 H:i",$data['udate'])."
|
|
|
收件人: {$data['to']};
|
|
|
主题: {$data['subject']}
|
|
|
|
|
|
{$inbox}</pre>".$reply;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
(new fob_ai_mail_auto_reply())->handler();
|
|
|
|
|
|
return 1; |
|
|
\ No newline at end of file |
...
|
...
|
|