fob_ai_mail_auto_reply.php 6.1 KB
<?php


require_once "../vendor/autoload.php";


/**
 * 自动回复
 * @author:dc
 * @time 2025/7/2 9:58
 * Class fob_ai_mail_auto_reply
 */
class fob_ai_mail_auto_reply {


    public $isStop = false;


    /**
     * @var \Lib\Db
     */
    public $fob_db;

    /**
     * @var \Lib\Db
     */
    public $db;


    public $startTime = 0;

    /**
     * SyncToEsCmd constructor.
     */
    public function __construct()
    {
        $this->db = db();
        $this->fob_db = fob_mysql();

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


    public function handler(){


        while (!$this->isStop()){

            $id = redis()->lPop('new_mail_ids');
            if($id){
                // 检查是否到时间了
                list($did,$time)  = explode('.',$id);
                if($time > time()){
                    redis()->rPush('new_mail_ids',$id);
                    usleep(10000);
                    continue;
                }
                // 查询数据
                $data = $this->db->throw()->first(\Model\listsSql::first('`id` = '.$did,'`id`,`folder_id`,`email_id`,`subject`,`is_hots`,`from`,`udate`'));
                if($data && !$data['is_hots']){
                    _echo('处理 '.$data['id']);
                    // 不是屏蔽的
                    $body = getBodyHtml(getMailBody($data['id']));
                    if(isAiAutoMail($data['from'],$data['subject'],$body)===0){
                        // 在检查下是否是 收件箱
                        if($this->db->value(\Model\folderSql::has(['id'=>$data['folder_id'],'origin_folder'=>'INBOX']))){

                            // 检查 是否开启了自动回复
                            list($postid,$source) = $this->getPostid($data['email_id']);
                            if($source == 2){
                                $email = $this->db->throw()->first(\Model\emailSql::first($data['email_id']));
                                // 配置
                                $replySetting = $this->getAutoReplySetting($postid,$email['email']);
                                if($replySetting){
                                    // 有配置才回复
                                    $ret = \Lib\Mail\MailFun::sendEmail([
                                        'subject'   =>  'Re:'.$data['subject'],
                                        'tos'   =>  [['email'=>$data['from'],'name'=>explode('@',$data['from'])[0]]],
                                        'body'  => $this->trimBody($replySetting['content'],$body)
                                    ],$email);
                                    _echo('回复成功'.$data['id'].'==='.$postid);
                                    $this->log([$data,$replySetting,$ret]); // 立即写入日志
                                }else{
                                    _echo('没有找到配置'.$data['id'].'==='.$postid);
                                }

                            }

                        }
                    }
                }

            }else{
                sleep(1);
            }
        }

    }

    public function trimBody($reply,$inbox){
        $reply = explode('</body>',$reply,2);

        return $reply[0]."<pre>{$inbox}</pre>".($reply[1]??'');
    }


    public function log($msg){
        logs($msg,LOG_PATH.'fob_ai_mail_auto_reply.log')->write(); // 立即写入日志
    }

    /**
     * 读取自动回复的配置
     * @param $postid
     * @param $email
     * @return false|mixed
     * @author:dc
     * @time 2025/7/2 11:22
     */
    public function getAutoReplySetting($postid,$email){
        $sets = $this->fob_db->throw()->all("select * from `ai_mail_auto_reply_setting` where ".dbWhere([
                'postid'    =>  $postid
            ]));
        if(!$sets){
            return false;
        }

        foreach ($sets as $set){
            $set['emails'] = @json_decode($set['emails'],true);
            // 是否开启了
            if($set['emails']&&(in_array($email,$set['emails'])||in_array('所有邮箱',$set['emails']))){
                // 必须设置了内容
                if($set['content']){
                    $set['week'] = @json_decode($set['week'],true);
                    // 是否满足周
                    if(!$set['week'] || in_array(date('w'),$set['week'])){
                        $hi = date('H:i');
                        // 是否跨天
                        if ($set['day2day']){
                            // 跨天设置
                            if($hi > $set['s_hour'] || $hi < $set['e_hour']){
                                return $set;
                            }
                        }else{
                            // 非夸天
                            if($hi > $set['s_hour'] && $hi < $set['e_hour']){
                                return $set;
                            }
                        }
                    }
                }
            }
        }

        return false;
    }


    /**
     * 项目id
     * @author:dc
     * @time 2025/5/20 15:44
     */
    public function getPostid($email_id){

        // 没有找到历史,就找绑定表
        $data = redis()->getSet('fob_bind_mail:'.$email_id,300,function ($email_id){
            return $this->fob_db->throw()->first("select `post_id`,`source` from `e_mail_binds` where `email_id` = '{$email_id}' and `deleted_at` is null order by `id` desc limit 1");
        },$email_id);

        return [
            $data['post_id']??0,
            $data['source']??0,
        ];
    }



}

(new fob_ai_mail_auto_reply())->handler();

return 1;