作者 邓超

自动回复

<?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']){
// 不是屏蔽的
$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){
// 有配置才回复
$this->log([$data,$replySetting]); // 立即写入日志
\Lib\Mail\MailFun::sendEmail([
'subject' => 'Re:'.$data['subject'],
'tos' => [['email'=>$data['from'],'name'=>explode('@',$data['from'])[0]]],
'body' => $this->trimBody($replySetting['content'],$body)
],$email);
}
}
}
}
}
}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;
\ No newline at end of file
... ...
这个目录是存放fob那边的脚本
* fob_ai_mail_auto_reply.php 文件是ai邮件自动回复脚本
... ...
... ... @@ -532,6 +532,9 @@ class SyncMail {
// 新邮件标记
if($item->getFolderName() == 'INBOX' && !$data['is_hots']){
redis()->incr('have_new_mail_'.$this->emailId(),120);
// 新邮件id,丢入redis
redis()->rPush('new_mail_ids',$id.'.'.(time()+120));
// 通知
if(stripos(trim($data['subject']),'re:')===0){
// 通知黑格 2024-08-22 新上 这个是异步的不会阻塞当前进程
... ...