作者 邓超

自动回复调优

<?php
include_once "../vendor/autoload.php";
// 查询不是预热邮箱
$eids = db()->throw()->all('SELECT `emails`.`id` FROM `emails` LEFT JOIN `hot_mail` ON `emails`.`email` = `hot_mail`.`email` WHERE `hot_mail`.`email` is NULL AND `pwd_error` = 0');
$eids = array_column($eids,'id');
foreach ($eids as $eid){
// 查询文件夹
$fids = db()->all(\Model\folderSql::all($eid,'`id`'));
array_map(function ($fid){
// 总数
$folder['exsts'] = db()->count(\Model\listsSql::listCount(
dbWhere(['folder_id'=> $fid, 'deleted' => 0])
));
// 未读
$folder['unseen'] = db()->count(\Model\listsSql::listCount(
dbWhere(['folder_id'=> $fid, 'seen' => 0, 'deleted' => 0])
));
_echo('fid: '.$fid.' data: '.json_encode($folder));
db()->update(\Model\folderSql::$table,$folder,'`id` = '.$fid,false);
},array_column($fids,'id'));
}
_echo('完成');
<?php
use Model\listsSql;
/**
* 处理预热邮箱
* @author:dc
* @time 2024/9/4 11:02
* Class HotMail
*/
class HotMail {
public function __construct(){
$this->db = db();
$this->start();
}
/**
* shopk那边的预热邮箱
* @var array
*/
private $hotEmail = [];
/**
* @var \Lib\Db|\Lib\DbPool
*/
private $db;
/**
* @author:dc
* @time 2024/7/18 14:04
*/
private function start(){
_echo('启动预热邮件处理 ');
if(redis()->add('hot_mail_sync2',1,60)){
_echo( '正在计算数据');
$maxId = $this->db->value("select `id` from `lists` order by `id` desc limit 1");
foreach (minMaxToArray($maxId-50000,$maxId) as $ids){
redis()->rPush('hot_check_ids',implode(',',$ids));
}
_echo( '计算完成');
redis()->delete('hot_mail_sync2');
}
while (1){
$ids = redis()->lPop('hot_check_ids');
if($ids){
$ids = explode(',',$ids);
$this->run($ids);
}else{
break;
}
}
}
private $folder = [];
private function run($id){
$list = $this->db->all(\Model\listsSql::all(dbWhere(['id'=>$id,'is_hots'=>0]),'`id`,`from`,`to`,`folder_id`,`is_hots`'));
foreach ($list as $item){
if(empty($this->folder[$item['folder_id']])){
$this->folder[$item['folder_id']] = folderAlias($this->db->value(\Model\folderSql::first($item['folder_id'],'folder')));
}
if(!in_array($this->folder[$item['folder_id']],['收件箱','发件箱'])){
continue;
}
// 是否是发件箱
if($this->folder[$item['folder_id']] == '发件箱'){
$w = ['email' => array_map('strtolower',explode(',',$item['to']))];
}else{
$w = ['email' =>strtolower($item['from'])];
}
// 是否在 预热邮箱中
$mkey = md5(dbWhere($w));
if(!isset($this->hotEmail[$mkey])){
$this->hotEmail[$mkey] = $this->db->count('select count(*) from `hot_mail` where '.dbWhere($w));
}
if($this->hotEmail[$mkey]){
if(!$item['is_hots']){
$ret = $this->db->update(listsSql::$table,['is_hots'=>1],dbWhere(['id'=>$item['id']]));
echo date('d H:i:s').' +==》 '.$item['id'].':'.$ret."\n";
}
}else{
// if($item['is_hots']){
// $ret = $this->db->update(listsSql::$table,['is_hots'=>0],dbWhere(['id'=>$item['id']]));
// echo date('d H:i:s').' -==》 '.$item['id'].':'.$ret."\n";
// }
}
}
// $list = $this->db->all(\Model\listsSql::all(dbWhere(['id'=>$id,'is_hots'=>1]),'`id`'));
// foreach ($list as $item){
// redis()->rPush('sync_to_es',$item['id']);
// }
}
}
\Co\run(function () {
include_once "../vendor/autoload.php";
new HotMail();
});
//
//swoole_set_process_name('hot-email-run-man');
//
//$pm = new Swoole\Process\Manager();
//
//$pm->addBatch(3,function (){
//
// swoole_set_process_name('hot-email-run');
//
// include_once "../vendor/autoload.php";
//
// new HotMail();
//
// exit();
//},true);
//
//$pm->start();
<?php
use Model\listsSql;
/**
* 自动回复的邮件
* @author:dc
* @time 2024/9/6 17:09
* Class HotMail
*/
class AutoMail {
public function __construct(){
$this->db = db();
$this->start();
}
/**
* shopk那边的预热邮箱
* @var array
*/
private $black_emails = [];
/**
* @var \Lib\Db|\Lib\DbPool
*/
private $db;
private $fids = [];
/**
* @author:dc
* @time 2024/7/18 14:04
*/
private function start(){
$this->fids = $this->db->all("select `id` from `folders` where `folder` = '收件箱'");
$this->fids = array_column($this->fids,'id');
$this->black_emails = $this->db->all("select * from `ai_black_email`");
$this->black_emails = array_column($this->black_emails,'email');
$this->black_emails = array_map("strtolower",$this->black_emails);
if(redis()->add('black_mail_sync2',1,60)){
echo '正在计算数据';
$maxId = $this->db->value("select `id` from `lists` order by `id` desc limit 1");
$id = 0;
while (1){
$ids = [];
for ($i=0;$i<1000;$i++){
$ids[] = $i+$id;
}
$id = end($ids);
redis()->rPush('black_check_ids',implode(',',$ids));
if($id>$maxId){
break;
}
}
echo '计算完成';
}
while (1){
$ids = redis()->lPop('black_check_ids');
if($ids){
$ids = explode(',',$ids);
$this->run($ids);
}else{
echo '等待'.PHP_EOL;
co::sleep(2);
}
}
}
private $filter = [];
private function run($id){
$list = $this->db->all(\Model\listsSql::all(dbWhere(['id'=>$id,'deleted'=>0]),'`id`,`from`,`folder_id`,`email_id`'));
foreach ($list as $item){
// 必须是收件箱
if(in_array($item['folder_id'],$this->fids)){
// 是否在黑名单中
if(in_array(strtolower($item['from']),$this->black_emails)){
if (!isset($this->filter[$item['email_id']])){
// 找到邮箱
$e = $this->db->value(\Model\emailSql::first($item['email_id'],'`email`'));
// 是否是ai邮件
$this->filter[$item['email_id']] =
$this->db->count("select count(*) from `hot_mail` where ".dbWhere(['email'=> $e]));
}
// 是否是ai邮件
if($this->filter[$item['email_id']]){
echo '删除 '.$item['id'].'===>'.$this->db->update(listsSql::$table,['deleted'=>1],dbWhere(['id'=>$item['id']]))."\n";
}
}
}
}
}
}
$pm = new Swoole\Process\Manager();
$pm->addBatch(3,function (){
include_once "../vendor/autoload.php";
// while(1){
new AutoMail();
// 执行完了暂停5分钟在执行
sleep(40);
// }
},true);
$pm->start();
... ... @@ -63,7 +63,7 @@ class SyncToEsCmd {
if($is_auto) return 1;
return isAiAutoMail($data['from'],$data['subject']) === 1 ? 1 : 0;
return isAiAutoMail($data['from'],$data['subject'],$data['body']??'') === 1 ? 1 : 0;
}
... ... @@ -94,11 +94,18 @@ class SyncToEsCmd {
$id = redis()->lPop('sync_to_es');
$code = 500;
if($id){
redis()->rPush('sync_to_es2',$id);
$is_check_body = false;
if(str_contains($id, '.')){
$id = explode('.',$id)[0];
$is_check_body = true;
}
$doc_id = '';
try {
$data = $this->db->throw()->first(\Model\listsSql::first('`id` = '.$id));
if(!$data){
$data = $this->db->throw()->first(\Model\listsSql::firstHot('`id` = '.$id));
}
}catch (Throwable $e){
redis()->rPush('sync_to_es',$id);
_echo('sync to es '.$e->getMessage());
... ... @@ -117,6 +124,14 @@ class SyncToEsCmd {
// 是否是自动回复
if($data['folder_as_int'] === 1){
// 是否检查body
if($is_check_body){
$body = getMailBody($data['id'],$this->db);
if($body){
$data['body'] = getBodyHtml($body);
}
}
$data['is_auto'] = $this->isAuto($data);
}
... ...
... ... @@ -995,19 +995,7 @@ class Home extends Base {
// 是否再次 重新获取
$data['allowreply'] = db()->value(folderSql::first(['id'=>$data['folder_id']],'folder'))!='发件箱'?1:0;
$body = db()->first(bodySql::first($id));
if(empty($body['text_html'])){
$body = db()->first("select * from `bodies_back` where `lists_id` = ".$id." limit 1");
if(empty($body['text_html'])){
$body = @file_get_contents('http://172.19.0.5:9527?id='.$id);
if($body){
$body = ['lists_id'=>$id,'text_html'=>$body];
}
}
}
if(empty($body['text_html'])){
$body = [];
}
$body = getMailBody($id);
if($body && !$reload){
$data['body'] = json_decode($body['text_html'],true);
$htmlbody = '';
... ...
... ... @@ -292,8 +292,6 @@ class MailListV2Es extends Base {
$v['deleted'] = $info['deleted'];
}
// 手动触发同步es
// if(empty($v['is_auto']) && $v['folder_name']=='收件箱') redis()->rPush('sync_to_es',$v['id']);
return $v;
},$lists?:[]);
... ...
... ... @@ -230,7 +230,7 @@ class MailListV2Es2 extends Base {
// 手动触发同步es
// 手动触发同步es
if(empty($v['is_auto']) && $v['folder_name']=='收件箱' && isAiAutoMail($v['from'],$v['subject'])) redis()->rPush('sync_to_es',$v['id']);
// redis()->rPush('sync_to_es',$v['id']);
return $v;
},$lists?:[]);
... ...
<?php
use Model\bodySql;
use Model\emailSql;
... ... @@ -503,6 +504,8 @@ function isAiAutoMail($from,$subject,$body=''){
$haystack = $subject;
}elseif ($t==1){
$haystack = $from;
}elseif ($t==3&&$body){
$haystack = $body;
}
if($haystack && $str && stripos($haystack,$str)!==false){
return 1;
... ... @@ -769,4 +772,58 @@ function minMaxToArray($min, $max,$len=1000) {
*/
function es(string $index='email_lists_copy'){
return (new Lib\Es\Es($index,['https://ai-email:3mLbEKwDX9YjUDFm@172.19.0.56:9200']));
}
/**
* 读取邮件详情内容
* @param $id
* @param null $db
* @return array|false|mixed|string|null
* @author:dc
* @time 2025/6/23 11:24
*/
function getMailBody($id,$db=null){
$db = $db ? $db : db();
$body = $db->first(bodySql::first($id));
if(empty($body['text_html'])){
$body = $db->first("select * from `bodies_back` where `lists_id` = ".$id." limit 1");
if(empty($body['text_html'])){
$body = @file_get_contents('http://172.19.0.5:9527?id='.$id);
if($body){
$body = ['lists_id'=>$id,'text_html'=>$body];
}
}
}
if(empty($body['text_html'])){
$body = [];
}
return $body;
}
/**
* 获取邮件内容body体
* @param $body 邮件数据 表里面的
* @return false|string
* @author:dc
* @time 2025/6/23 11:33
*/
function getBodyHtml($body){
if(!empty($body['text_html'])){
$body = $body['text_html'];
}
$body = is_array($body) ? $body : json_decode($body,true);
$html = '';
$text = '';
foreach ($body as $bd){
if(($bd['type']??'') == 'text/html'){
$html = base64_decode($bd['body']??'');
}
if(($bd['type']??'') == 'text/plain'){
$text = base64_decode($bd['body']??'');
}
}
return $html ? $html : $text;
}
\ No newline at end of file
... ...