由于本人项目发邮件次数比较多,而每个邮箱地址最大上限每日1000封受限。
为了避免第一个邮箱账号达到每日上限(邮件异常会返回错误码554,提示:Expected response code 354 but got code "554", with message "554 5.5.3 RP:TRC),项目还继续发送邮件,则启动备用邮箱号发送。
第一步:首先先配置.env配置备用邮件账号数据
#备用邮箱号 BACKUP_MAIL_DRIVER=smtp BACKUP_MAIL_HOST=smtp.qiye.163.com BACKUP_MAIL_PORT=465 [email protected] BACKUP_MAIL_PASSWORD=XXXXXXXXXXX [email protected] BACKUP_MAIL_FROM_NAME=XXXXX系统(备用) BACKUP_MAIL_ENCRYPTION=ssl
第二步:在config目录新建文件名为backupMail.php
env('BACKUP_MAIL_DRIVER', 'smtp'),
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/
'host' => env('BACKUP_MAIL_HOST', 'smtp.mailgun.org'),
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
'port' => env('BACKUP_MAIL_PORT', 587),
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => [
'address' => env('BACKUP_MAIL_FROM_ADDRESS', '[email protected]'),
'name' => env('BACKUP_MAIL_FROM_NAME', 'Example'),
],
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => env('BACKUP_MAIL_ENCRYPTION', 'tls'),
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => env('BACKUP_MAIL_USERNAME'),
'password' => env('BACKUP_MAIL_PASSWORD'),
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
|--------------------------------------------------------------------------
|
| If you are using Markdown based email rendering, you may configure your
| theme and component paths here, allowing you to customize the design
| of the emails. Or, you may simply stick with the Laravel defaults!
|
*/
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
];
第三步:在Services目录新建个EmailServices.php文件。
'发送邮件失败,错误信息:' . $e->getMessage(),
'aAddressee' => '收件人:' . json_encode($aAddressee),
'aCC' => '抄送人:' . json_encode($aCC),
'requestData' => '请求信息:' . json_encode($aRequests)
];
SendMailJob::dispatch(explode('、', MedliveConfig::getValueByKey('accept_error_msg')), [], $aErrorRequest, '发送邮件失败', 'sendWrong', $user_id, 'backupMail');
}
info('发送邮件失败,错误信息1:' . $e->getMessage());
}
}
/**
* 测试发邮件
*/
public static function testSendEmail()
{
try {
echo('----发邮件开始----
');
$mailConfig = \request('source');
if ($mailConfig) {
$mailConfig = 'backupMail';
} else {
$mailConfig = 'mail';
}
$aAddressee = ['[email protected]']; //本地测试,收件人
$aCC = [];//本地测试 抄送人
SendMailJob::dispatch($aAddressee, $aCC, ['wrong_emails' => []], '测试发邮件', 'wrongNotice', 0, $mailConfig);
echo('----发邮件结束----
');
} catch (\Throwable $e) {
dd('发送邮件失败,错误信息:' . $e->getMessage());
}
}
}
第四步:由于发邮件使用的是队列,在Mail目录新建OrderShipped.php文件
subject = $subject;
$this->order = $order;
$this->viewName = !empty($viewName) ? $viewName : 'shipped';
$this->mailConfig = $mailConfig;
}
/**
* 构建消息。
*
* @return $this
*/
public function build()
{
$build = $this->from(config($this->mailConfig . '.username'), config($this->mailConfig . '.from.name'))
->view('emails.orders.' . $this->viewName)
->subject($this->subject);
if (data_get($this->order, 'push_file')) {
$push_file = public_path('/uploadfile' . data_get($this->order, 'push_file'));
if (file_exists($push_file)) {
$build = $build->attach($push_file, ['as' => '稿件附件.' . pathinfo($push_file, PATHINFO_EXTENSION)]);
}
}
if (data_get($this->order, 'headimg_path')) {
$headimg_path = public_path('/uploadfile' . data_get($this->order, 'headimg_path'));
if (file_exists($headimg_path)) {
$build = $build->attach($headimg_path, ['as' => '头图附件.' . pathinfo($headimg_path, PATHINFO_EXTENSION)]);
}
}
if (data_get($this->order, 'video_path')) {
$video_path = public_path('/uploadfile' . data_get($this->order, 'video_path'));
if (file_exists($video_path)) {
$build = $build->attach($video_path, ['as' => '视频附件.' . pathinfo($video_path, PATHINFO_EXTENSION)]);
}
}
if (data_get($this->order, 'live_screenshot', [])) {
//视频截图
foreach ($this->order['live_screenshot'] as $k => $file) {
$file = public_path('/uploadfile' . '/' . $file);
if (file_exists($file)) {
$build = $build->attach($file, ['as' => '视频截图' . ($k + 1) . '.' . pathinfo($file, PATHINFO_EXTENSION)]);
}
}
}
if (data_get($this->order, 'live_data_file', [])) {
//直播数据附件
foreach ($this->order['live_data_file'] as $k => $live_data_file) {
$live_data_file = public_path('/uploadfile' . '/' . $live_data_file);
if (file_exists($live_data_file)) {
$build = $build->attach($live_data_file, ['as' => '直播数据附件' . ($k + 1) . '.' . pathinfo($live_data_file, PATHINFO_EXTENSION)]);
}
}
}
return $build;
}
}
第五步:在Jobs目录新建文件SendMailJob.php
aAddressee = $aAddressee;
$this->aCC = $aCC;
$this->aRequests = $aRequests;
$this->subject = $subject;
$this->viewName = $viewName;
$this->user_id = $user_id;
$this->mailConfig = $mailConfig;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
// 设置新的邮箱账号
$transport = new \Swift_SmtpTransport(config($this->mailConfig . '.host'), config($this->mailConfig . '.port'), config($this->mailConfig . '.encryption'));
$transport->setUsername(config($this->mailConfig . '.username'));
$transport->setPassword(config($this->mailConfig . '.password'));
$mailer = new \Swift_Mailer($transport);
// 发送前实例化
app(Mailer::class)->setSwiftMailer($mailer);
info('发送的邮箱账号地址——' . config($this->mailConfig . '.from.address'));
try {
Mail::to(array_filter($this->aAddressee))
->cc(array_filter($this->aCC))
->send(new OrderShipped($this->aRequests, $this->subject, $this->viewName, $this->mailConfig));
$is_success = 1;
} catch (\Exception $e) {
if (config('app.env') == 'production') {
$aErrorRequest = [
'msg' => '发送邮件失败,错误信息:' . $e->getMessage(),
'aAddressee' => '收件人:' . json_encode($this->aAddressee),
'aCC' => '抄送人:' . json_encode($this->aCC),
'requestData' => '请求信息:' . json_encode($this->aRequests)
];
SendMailJob::dispatch(explode('、', MedliveConfig::getValueByKey('accept_error_msg')), [], $aErrorRequest, '发送邮件失败', 'sendWrong', $this->user_id, 'backupMail');
}
info(config($this->mailConfig . '.from.address') . '——发送邮件队列抛出异常,错误信息2:' . $e->getMessage());
if ($e->getCode() == 554) {
/*
* Expected response code 354 but got code "554", with message "554 5.5.3 RP:TRC
* 发送的邮件内容包含了未被网易许可的信息,或违背了网易的反垃圾服务条款,或是达到最大上限每日1000封受限。
* 超出使用备用账号
*/
info('------超出每日邮箱最大上限------使用备用账号发送-----');
SendMailJob::dispatch($this->aAddressee, $this->aCC, $this->aRequests, $this->subject, $this->viewName, $this->user_id, 'backupMail');
}
$is_success = 0;
}
//保存发邮件数据
SendEmailLog::saveSendLog([
'requestData' => json_encode($this->aRequests),
'addressee' => json_encode($this->aAddressee),
'cc' => json_encode($this->aCC),
'subject' => $this->subject,
'template_view_name' => $this->viewName,
'failures' => json_encode(Mail::failures()),
'user_id' => $this->user_id,
'mail_from_address' => config($this->mailConfig . '.from.address'),
'is_success' => $is_success
]);
}
}