|
- <?php
- namespace App\Jobs;
- use App\Models\AiMailTask;
- use App\Models\AiMailTaskDetail;
- use App\Models\Email\EMailBind;
- use App\Models\Email\EMailSubscribe;
- use App\Repositories\AiMailTaskDetailRepository;
- use App\Repositories\AiPotentialCustomerAcquisitionTaskDetailRepository;
- use Carbon\Carbon;
- use Exception;
- use Illuminate\Bus\Queueable;
- use Illuminate\Contracts\Queue\ShouldQueue;
- use Illuminate\Foundation\Bus\Dispatchable;
- use Illuminate\Queue\InteractsWithQueue;
- use Illuminate\Queue\SerializesModels;
- use Cache;
- use Log;
- /**
- * 创建AI邮件群发任务
- */
- class AiEmailWillTaskJob implements ShouldQueue
- {
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- protected $param;
- /**
- * Create a new job instance.
- *
- * @return void
- */
- public function __construct($params)
- {
- $this->connection = 'ai_mail_sub_task_create';
- $this->param = $params;
- }
- /**
- * Execute the job.
- *
- * @return true|void
- */
- public function handle()
- {
- $param = $this->param;
- try {
- $post_id = $param['post_id'];
- $user_id = $param['user_id'];
- $task_id = $param['task_id'];
- $bind_name = $param['bind_name'];
- $bind_email = $param['bind_email'];
- $email_type = $param['email_type'];
- $custom_list = $param['custom_list'];
- $removal_day = $param['removal_day'];
- if (!$post_id || !$user_id || !$task_id || (!$email_type && !$custom_list)) {
- Log::error("邮件群发参数不完整");
- return 0;
- }
- // 加个创建子任务标志
- $cache_key = 'ai_mail_send_create_subtask_' . $task_id;
- Cache::put($cache_key, '1');
- if (!is_array($email_type) && $email_type) {
- $email_type = [$email_type];
- }
- if ($email_type) { // AI潜客采集列表
- $customers = app(AiPotentialCustomerAcquisitionTaskDetailRepository::class)->getMultiTaskValidEmails($email_type);
- $all_mailboxes = $customers->pluck('mailbox')->toArray(); //待发送的所有目标邮箱
- $history_send_mailboxes = [];
- // 过滤多少天内发送过的邮箱
- if ($removal_day) {
- $history_send_mailboxes = $this->filterSentMailboxes($all_mailboxes, $removal_day, $user_id);
- }
- foreach ($customers as $customer) {
- $email = $customer->mailbox;
- if (empty($email)) continue;
- // 在$removal_day天发过,不发送该邮箱
- if (in_array($email, $history_send_mailboxes)) {
- continue;
- }
- $name = $customer->name;
- if (empty($name)) {
- $temp = explode("@", $email);
- $name = $temp[0];
- }
- $this->createSubTask($task_id, $post_id, $user_id, $bind_name, $bind_email, $email, $name, $customer->id);
- }
- }
- if ($custom_list) { // 添加自定义邮箱(自定义列表)
- $custom_list = str_replace(array("\r\n", "\r", "\n"), '加入异步队列
- [code] //加入计划任务队列
- if ($data['email_type'] || $data['custom_list'] || $data['subscribe']) {
- $param = ['email_type' => $data['email_type'], 'custom_list' => $data['custom_list'], 'task_id' => $aiMailTask->id, 'post_id' => $postId, 'user_id' => $userId, 'bind_name' => ($bindMailbox->name ?? null), 'bind_email' => ($bindMailbox->email ?? null), 'removal_day' => $aiMailTask->removal_day,'subscribe'=>$data['subscribe'],'filter_subscribe'=>$attributes['filter_subscribe']];
- AiEmailWillTaskJob::dispatch($param);
- }
复制代码
, trim($custom_list));
$customList = explode('加入异步队列
- //加入计划任务队列
- if ($data['email_type'] || $data['custom_list'] || $data['subscribe']) {
- $param = ['email_type' => $data['email_type'], 'custom_list' => $data['custom_list'], 'task_id' => $aiMailTask->id, 'post_id' => $postId, 'user_id' => $userId, 'bind_name' => ($bindMailbox->name ?? null), 'bind_email' => ($bindMailbox->email ?? null), 'removal_day' => $aiMailTask->removal_day,'subscribe'=>$data['subscribe'],'filter_subscribe'=>$attributes['filter_subscribe']];
- AiEmailWillTaskJob::dispatch($param);
- }
复制代码
, $custom_list);
$name_and_mailboxes = [];
foreach ($customList as $customerId) {
$customerId = preg_replace('/^[\s ]+|[\s ]+$/u', '', $customerId);// 去掉全角空格
$customerId = str_replace(['<','>'], '', $customerId);// 去掉全角空格
$customerId = trim($customerId); // 去掉两边的空格
$temp = explode('|', $customerId);
$temp = array_map('trim', $temp);// 去掉两边的空格
$name = '';
$to = '';
if (count($temp) == 1 && filter_var($customerId, FILTER_VALIDATE_EMAIL)) {
$to = $customerId;
$arr = explode("@", $to);
$name = $arr[0];
} else if (count($temp) == 2 && filter_var($temp[1], FILTER_VALIDATE_EMAIL)) {
$to = $temp[1];
$name = $temp[0];
}
if (!$to) continue;
if (empty($name)) {
$name = explode("@", $to)[0];
}
$name_and_mailboxes[$to] = $name;
}
if ($name_and_mailboxes) {
$history_send_mailboxes = [];
if ($removal_day) {
$history_send_mailboxes = $this->filterSentMailboxes(array_keys($name_and_mailboxes), $removal_day, $user_id);
}
foreach ($name_and_mailboxes as $mailbox => $name) {
// 过滤多少天内发送过的邮箱
if (in_array($mailbox, $history_send_mailboxes)) {
continue;
}
$this->createSubTask($task_id, $post_id, $user_id, $bind_name, $bind_email, $mailbox, $name);
}
}
}
if (!empty($param['subscribe'])) {// 订阅邮箱
$bindEmails = $this->getBindEmail();
$p = 1;
while ($p) {
$subModel = EMailSubscribe::query()->whereIn('c_email', $bindEmails);//->get(['u_email']);
// 过滤已取消订阅的
if (!empty($param['filter_subscribe'])) {
$subModel->where('status', 's');
}
$subModel = $subModel->forPage($p, 1000)->get(['u_email'])->pluck('u_email')->toArray();
foreach ($subModel as $item) {
// 邮箱存在,如果收件人姓名(name)不存在,name就取@前面的值,不可能为空
$this->createSubTask($task_id, $post_id, $user_id, $bind_name, $bind_email, $item, explode('@', $item)[0]);
}
// 没有了,跳出
if (count($subModel) < 1000) {
break;
}
}
}
// 创建完成更新主任务的发送总数
$task = AiMailTask::find($task_id);
$count = $task->taskDetails->count();
$updateParams = ['send_total_num' => $count];
if ($count == 0) {
$updateParams['status'] = AiMailTask::FAILED_STATUS;
$updateParams['remark'] = '过滤后未获取到收件邮箱';
}
$task->update($updateParams);
Cache::forget($cache_key);
return true;
} catch (Exception $e) {
Log::error("AI发邮件-写入邮件队列失败:" . $e, ['params' => $param]);
}
}
/**
* 获取发送邮箱
* @return array
* @author:dc
* @time 2024/8/13 16:21
*/
public function getBindEmail(){
if($this->param['bind_email']){
return [$this->param['bind_email']];
}else{
if(empty($this->bindEmail)){
$this->bindEmail = EMailBind::query()->where('post_id',$this->param['post_id'])->get(['email'])->pluck('email')->toArray();
}
return $this->bindEmail;
}
}
/**
* @param $task_id
* @param $post_id
* @param $user_id
* @param $bind_name
* @param $bind_email
* @param $mailbox
* @param $name
* @param int $recipient_id
* @return void
*/
public function createSubTask($task_id, $post_id, $user_id, $bind_name, $bind_email, $mailbox, $name, $recipient_id = 0): void
{
// 是否要过滤掉退订的邮箱
if(empty($this->param['subscribe']) && !empty($this->param['filter_subscribe'])){
$unsubscribe = EMailSubscribe::query()
->whereIn('c_email',$this->getBindEmail())
->where('status','d')->count();
if($unsubscribe){
return ;
}
}
// 项目包含指定的域名的邮箱则不创建发件任务
if ($post_id == 544429) { // 浙江大铭汽车零部件有限公司
$filterDomains = ['Bilsteingroup.com', 'bilsteingroup.com', 'driv.com', 'autozone.com', 'motorcarparts.com',
'atp-autoteile.de', 'valeryd.se', 'smartparts.eu', 'nexusautomotive.eu', 'sapco.com', 'ntn-snr.fr',
'mgadistribution.fr', 'optimal-germany.com'];
if (in_array(explode('@', $mailbox)[1], $filterDomains)) {
return;
}
}
$insert['task_id'] = $task_id;
$insert['post_id'] = $post_id;
$insert['user_id'] = $user_id;
$insert['send_nickname'] = $bind_name;
$insert['send_mailbox'] = $bind_email;
$insert['to'] = $mailbox;
$insert['name'] = $name;
$insert['recipient_id'] = $recipient_id;
$insert['status'] = AiMailTaskDetail::CREATED_STATUS;
app(AiMailTaskDetailRepository::class)->createDetailTask($insert);
}
/**
* 过滤$removal_day天内已发送过的邮箱
* @param array $object_mailboxes 待发送的所有目标邮箱
* @param $removal_day
* @param $user_id
* @return array
*/
public function filterSentMailboxes(array $object_mailboxes, $removal_day, $user_id)
{
$history_send_mailboxes = [];
// 查询多少天内发送过的邮箱
if ($removal_day) {
$history_send_mailboxes = AiMailTaskDetail::where(['user_id' => $user_id])
->where('created_at', '>', Carbon::now()->subDays($removal_day))
->where('status', AiMailTaskDetail::SUCCESS_STATUS)
->whereIn('to', $object_mailboxes)
->pluck('to')
->toArray();
$history_send_mailboxes = array_unique($history_send_mailboxes);
}
return $history_send_mailboxes;
}
}
[/code]加入异步队列
[ DISCUZ_CODE_9 ]
|
|