作者 邓超

预热自动回复

此 diff 太大无法显示。
  1 +<?php
  2 +
  3 +
  4 +use Model\folderSql;
  5 +
  6 +require_once "../vendor/autoload.php";
  7 +
  8 +
  9 +/**
  10 + * 预热自动回复
  11 + * @author:dc
  12 + * @time 2025/7/2 9:58
  13 + * Class fob_ai_mail_auto_reply
  14 + */
  15 +class fob_hot_ai_mail_auto_reply {
  16 +
  17 +
  18 + public $isStop = false;
  19 +
  20 +
  21 + /**
  22 + * @var \Lib\Db
  23 + */
  24 + public $db;
  25 +
  26 +
  27 + public $startTime = 0;
  28 +
  29 + /**
  30 + * SyncToEsCmd constructor.
  31 + */
  32 + public function __construct()
  33 + {
  34 + $this->db = db();
  35 +
  36 + $handler = function ($signal){
  37 + _echo('收到进程信号 '. $signal);
  38 + // 可以处理其他程序
  39 + $this->isStop = true;
  40 + };
  41 + pcntl_signal(SIGTERM, $handler); // 这个是kill
  42 + pcntl_signal(SIGINT, $handler); // 这个是 ctrl+c
  43 +
  44 + $this->startTime = time();
  45 + }
  46 +
  47 +
  48 + /**
  49 + * @return bool
  50 + */
  51 + public function isStop(): bool
  52 + {
  53 + // 检查是否接收到信号
  54 + pcntl_signal_dispatch();
  55 +
  56 + // 是否超过来最大执行时间
  57 + if(time()-43200 > $this->startTime){
  58 + return true;
  59 + }
  60 +
  61 + return $this->isStop;
  62 + }
  63 +
  64 + protected $bodys = [];
  65 +
  66 + public function getDelayTime(){
  67 + /**
  68 + * 随机一个延时时间秒 极小的概率30-60分钟,小概率60-120分钟,中概率120-180分钟 大概率180-240分钟
  69 + */
  70 +
  71 +// 生成一个 0 到 100 之间的随机数
  72 + $randomValue = rand(0, 100);
  73 +
  74 + // 根据随机值的范围来决定延迟时间
  75 + if ($randomValue < 5) { // 5% 的概率
  76 + // 随机 30-60分钟
  77 + $rand = rand(45, 60) * 60; // 转换为秒
  78 + } elseif ($randomValue < 15) { // 10% 的概率 (5% + 10%)
  79 + // 随机 60-120分钟
  80 + $rand = rand(65, 120) * 60; // 转换为秒
  81 + } elseif ($randomValue < 45) { // 30% 的概率 (15% + 30%)
  82 + // 随机 120-180分钟
  83 + $rand = rand(125, 180) * 60; // 转换为秒
  84 + } else { // 55% 的概率 (45% + 55%)
  85 + // 随机 180-240分钟
  86 + $rand = rand(180, 240) * 60; // 转换为秒
  87 + }
  88 +
  89 + return time()+$rand;
  90 + }
  91 +
  92 + public function handler(){
  93 +
  94 + $this->bodys = file_get_contents(__DIR__."/body.reply");
  95 + $this->bodys = explode("--------------",$this->bodys);
  96 +
  97 + while (!$this->isStop()){
  98 +
  99 + $id = redis()->lPop('new_hot_mail_auto_reply_ids');
  100 + if($id){
  101 + // 检查是否到时间了
  102 + list($did,$time) = explode('.',((string) $id).'.0');
  103 + if($time == '0'){
  104 + redis()->rPush('new_hot_mail_auto_reply_ids',$id.'.'.$this->getDelayTime());
  105 + continue;
  106 + }
  107 + if($time > time()){
  108 + redis()->rPush('new_hot_mail_auto_reply_ids',$id);
  109 + usleep(10000);
  110 + continue;
  111 + }
  112 + // 查询数据
  113 + $data = $this->db->first(\Model\listsSql::first('`id` = '.$did,'`id`,`email_id`,`subject`,`is_hots`,`from`,`udate`,`uid`'));
  114 + if($data && $data['is_hots']){
  115 + // 在检查下是否是 收件箱
  116 + if($this->db->cache(3600)->value(\Model\folderSql::has(['id'=>$data['folder_id'],'origin_folder'=>'INBOX']))){
  117 + _echo('处理 '.$data['id']);
  118 + $email = $this->db->throw()->cache(3600)->first(\Model\emailSql::first($data['email_id']));
  119 + // 标记已读
  120 + $mailInstance = \Lib\Imap\ImapPool::get((new \Lib\Imap\ImapConfig($email)));
  121 + if($mailInstance->login()){
  122 + $mailInstance->folder('INBOX')->msg()->uid($data['uid'])->seen();
  123 + $mailInstance = null;
  124 + }
  125 +
  126 + // 来回超过5次就不回了
  127 + if(substr_count($data['subject'],"Re:") < 3){
  128 +// 有配置才回复
  129 + $ret = \Lib\Mail\MailFun::sendEmail([
  130 + 'subject' => 'Re:'.$data['subject'],
  131 + 'tos' => [['email'=>$data['from'],'name'=>explode('@',$data['from'])[0]]],
  132 + 'body' => $this->trimBody($data,$data['subject']),
  133 + 'mail-header' => [
  134 + 'Aicc-Hot-Mail' => 'hot' // 预热邮件
  135 + ]
  136 + ],$email);
  137 + _echo('回复成功'.$data['id']." ".$email['email'].' to '.$data['from']." ".$ret[1]);
  138 + }else{
  139 + _echo('来回超过5次就不回了 '.$data['id']);
  140 + }
  141 +
  142 + }
  143 +
  144 + }
  145 +
  146 + }else{
  147 + sleep(1);
  148 + }
  149 + }
  150 +
  151 + }
  152 +
  153 + public function trimBody($data,$inbox){
  154 + // 随机body内容
  155 + $reply = $this->bodys[array_rand($this->bodys)];
  156 +
  157 + return "<pre>------------------ 原始邮件 ------------------
  158 +发件人: {$data['from']};
  159 +发送时间: ".date("Ymd H:i",$data['udate'])."
  160 +收件人: {$data['to']};
  161 +主题: {$data['subject']}
  162 +
  163 +{$inbox}</pre>".$reply;
  164 + }
  165 +
  166 +
  167 +
  168 +
  169 +}
  170 +
  171 +(new fob_ai_mail_auto_reply())->handler();
  172 +
  173 +return 1;