正在显示
3 个修改的文件
包含
209 行增加
和
0 行删除
fobCmd/fob_ai_mail_auto_reply.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | + | ||
4 | +require_once "../vendor/autoload.php"; | ||
5 | + | ||
6 | + | ||
7 | +/** | ||
8 | + * 自动回复 | ||
9 | + * @author:dc | ||
10 | + * @time 2025/7/2 9:58 | ||
11 | + * Class fob_ai_mail_auto_reply | ||
12 | + */ | ||
13 | +class fob_ai_mail_auto_reply { | ||
14 | + | ||
15 | + | ||
16 | + public $isStop = false; | ||
17 | + | ||
18 | + | ||
19 | + /** | ||
20 | + * @var \Lib\Db | ||
21 | + */ | ||
22 | + public $fob_db; | ||
23 | + | ||
24 | + /** | ||
25 | + * @var \Lib\Db | ||
26 | + */ | ||
27 | + public $db; | ||
28 | + | ||
29 | + | ||
30 | + public $startTime = 0; | ||
31 | + | ||
32 | + /** | ||
33 | + * SyncToEsCmd constructor. | ||
34 | + */ | ||
35 | + public function __construct() | ||
36 | + { | ||
37 | + $this->db = db(); | ||
38 | + $this->fob_db = fob_mysql(); | ||
39 | + | ||
40 | + $handler = function ($signal){ | ||
41 | + _echo('收到进程信号 '. $signal); | ||
42 | + // 可以处理其他程序 | ||
43 | + $this->isStop = true; | ||
44 | + }; | ||
45 | + pcntl_signal(SIGTERM, $handler); // 这个是kill | ||
46 | + pcntl_signal(SIGINT, $handler); // 这个是 ctrl+c | ||
47 | + | ||
48 | + $this->startTime = time(); | ||
49 | + } | ||
50 | + | ||
51 | + | ||
52 | + /** | ||
53 | + * @return bool | ||
54 | + */ | ||
55 | + public function isStop(): bool | ||
56 | + { | ||
57 | + // 检查是否接收到信号 | ||
58 | + pcntl_signal_dispatch(); | ||
59 | + | ||
60 | + // 是否超过来最大执行时间 | ||
61 | + if(time()-43200 > $this->startTime){ | ||
62 | + return true; | ||
63 | + } | ||
64 | + | ||
65 | + return $this->isStop; | ||
66 | + } | ||
67 | + | ||
68 | + | ||
69 | + public function handler(){ | ||
70 | + | ||
71 | + | ||
72 | + while (!$this->isStop()){ | ||
73 | + | ||
74 | + $id = redis()->lPop('new_mail_ids'); | ||
75 | + if($id){ | ||
76 | + // 检查是否到时间了 | ||
77 | + list($did,$time) = explode('.',$id); | ||
78 | + if($time > time()){ | ||
79 | + redis()->rPush('new_mail_ids',$id); | ||
80 | + usleep(10000); | ||
81 | + continue; | ||
82 | + } | ||
83 | + // 查询数据 | ||
84 | + $data = $this->db->throw()->first(\Model\listsSql::first('`id` = '.$did,'`id`,`folder_id`,`email_id`,`subject`,`is_hots`,`from`,`udate`')); | ||
85 | + if($data && !$data['is_hots']){ | ||
86 | + // 不是屏蔽的 | ||
87 | + $body = getBodyHtml(getMailBody($data['id'])); | ||
88 | + if(isAiAutoMail($data['from'],$data['subject'],$body)===0){ | ||
89 | + // 在检查下是否是 收件箱 | ||
90 | + if($this->db->value(\Model\folderSql::has(['id'=>$data['folder_id'],'origin_folder'=>'INBOX']))){ | ||
91 | + | ||
92 | + // 检查 是否开启了自动回复 | ||
93 | + list($postid,$source) = $this->getPostid($data['email_id']); | ||
94 | + if($source == 2){ | ||
95 | + $email = $this->db->throw()->first(\Model\emailSql::first($data['email_id'])); | ||
96 | + // 配置 | ||
97 | + $replySetting = $this->getAutoReplySetting($postid,$email['email']); | ||
98 | + if($replySetting){ | ||
99 | + // 有配置才回复 | ||
100 | + $this->log([$data,$replySetting]); // 立即写入日志 | ||
101 | + \Lib\Mail\MailFun::sendEmail([ | ||
102 | + 'subject' => 'Re:'.$data['subject'], | ||
103 | + 'tos' => [['email'=>$data['from'],'name'=>explode('@',$data['from'])[0]]], | ||
104 | + 'body' => $this->trimBody($replySetting['content'],$body) | ||
105 | + ],$email); | ||
106 | + } | ||
107 | + | ||
108 | + } | ||
109 | + | ||
110 | + } | ||
111 | + } | ||
112 | + } | ||
113 | + | ||
114 | + }else{ | ||
115 | + sleep(1); | ||
116 | + } | ||
117 | + } | ||
118 | + | ||
119 | + } | ||
120 | + | ||
121 | + public function trimBody($reply,$inbox){ | ||
122 | + $reply = explode('</body>',$reply,2); | ||
123 | + | ||
124 | + return $reply[0]."<pre>{$inbox}</pre>".($reply[1]??''); | ||
125 | + } | ||
126 | + | ||
127 | + | ||
128 | + public function log($msg){ | ||
129 | + logs($msg,LOG_PATH.'fob_ai_mail_auto_reply.log')->write(); // 立即写入日志 | ||
130 | + } | ||
131 | + | ||
132 | + /** | ||
133 | + * 读取自动回复的配置 | ||
134 | + * @param $postid | ||
135 | + * @param $email | ||
136 | + * @return false|mixed | ||
137 | + * @author:dc | ||
138 | + * @time 2025/7/2 11:22 | ||
139 | + */ | ||
140 | + public function getAutoReplySetting($postid,$email){ | ||
141 | + $sets = $this->fob_db->throw()->all("select * from `ai_mail_auto_reply_setting` where ".dbWhere([ | ||
142 | + 'postid' => $postid | ||
143 | + ])); | ||
144 | + if(!$sets){ | ||
145 | + return false; | ||
146 | + } | ||
147 | + | ||
148 | + foreach ($sets as $set){ | ||
149 | + $set['emails'] = @json_decode($set['emails'],true); | ||
150 | + // 是否开启了 | ||
151 | + if($set['emails']&&(in_array($email,$set['emails'])||in_array('所有邮箱',$set['emails']))){ | ||
152 | + // 必须设置了内容 | ||
153 | + if($set['content']){ | ||
154 | + $set['week'] = @json_decode($set['week'],true); | ||
155 | + // 是否满足周 | ||
156 | + if(!$set['week'] || in_array(date('w'),$set['week'])){ | ||
157 | + $hi = date('H:i'); | ||
158 | + // 是否跨天 | ||
159 | + if ($set['day2day']){ | ||
160 | + // 跨天设置 | ||
161 | + if($hi > $set['s_hour'] || $hi < $set['e_hour']){ | ||
162 | + return $set; | ||
163 | + } | ||
164 | + }else{ | ||
165 | + // 非夸天 | ||
166 | + if($hi > $set['s_hour'] && $hi < $set['e_hour']){ | ||
167 | + return $set; | ||
168 | + } | ||
169 | + } | ||
170 | + } | ||
171 | + } | ||
172 | + } | ||
173 | + } | ||
174 | + | ||
175 | + return false; | ||
176 | + } | ||
177 | + | ||
178 | + | ||
179 | + /** | ||
180 | + * 项目id | ||
181 | + * @author:dc | ||
182 | + * @time 2025/5/20 15:44 | ||
183 | + */ | ||
184 | + public function getPostid($email_id){ | ||
185 | + | ||
186 | + // 没有找到历史,就找绑定表 | ||
187 | + $data = redis()->getSet('fob_bind_mail:'.$email_id,300,function ($email_id){ | ||
188 | + 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"); | ||
189 | + },$email_id); | ||
190 | + | ||
191 | + return [ | ||
192 | + $data['post_id']??0, | ||
193 | + $data['source']??0, | ||
194 | + ]; | ||
195 | + } | ||
196 | + | ||
197 | + | ||
198 | + | ||
199 | +} | ||
200 | + | ||
201 | +(new fob_ai_mail_auto_reply())->handler(); | ||
202 | + | ||
203 | +return 1; |
fobCmd/readme.md
0 → 100644
@@ -532,6 +532,9 @@ class SyncMail { | @@ -532,6 +532,9 @@ class SyncMail { | ||
532 | // 新邮件标记 | 532 | // 新邮件标记 |
533 | if($item->getFolderName() == 'INBOX' && !$data['is_hots']){ | 533 | if($item->getFolderName() == 'INBOX' && !$data['is_hots']){ |
534 | redis()->incr('have_new_mail_'.$this->emailId(),120); | 534 | redis()->incr('have_new_mail_'.$this->emailId(),120); |
535 | + // 新邮件id,丢入redis | ||
536 | + redis()->rPush('new_mail_ids',$id.'.'.(time()+120)); | ||
537 | + | ||
535 | // 通知 | 538 | // 通知 |
536 | if(stripos(trim($data['subject']),'re:')===0){ | 539 | if(stripos(trim($data['subject']),'re:')===0){ |
537 | // 通知黑格 2024-08-22 新上 这个是异步的不会阻塞当前进程 | 540 | // 通知黑格 2024-08-22 新上 这个是异步的不会阻塞当前进程 |
-
请 注册 或 登录 后发表评论