Я создал скрипт, который отправляет по электронной почте некоторые данные отслеживания для каждого отправленного заказа клиента.
Скрипт построен с помощью PHPMailer и отправляет электронные письма через Google SMTP-Relay Service.
Во время тестирования все работало как положено. Загрузка протестирована с 100 электронными письмами, хотя и на один и тот же адрес электронной почты, все выполнено, как и ожидалось. Нет дубликатов или пропущенных писем.
Однако вскоре после выхода в эфир мне сказали, что несколько клиентов получили десятки электронных писем с подробностями отслеживания других клиентов.
С пользователями gmail они получили отслеживающее электронное письмо другого клиента со своим адресом электронной почты как отправленное.
Пользователи Outlook получают электронное письмо другого клиента со многими электронными письмами в зоне отправления.
Я просмотрел код, протестировал и проверил вывод каждой функции, полностью потерянный там, где он мог пойти не так.
Ниже приведен процесс sudo сценария. Посмотрим, не мог бы кто-нибудь дать несколько советов о том, как можно решить эту проблему.
- Получить список электронных писем в одномерный массив.
- Создание экземпляра PHPMailer
- Для каждого электронного письма в массиве отправьте электронное письмо, дождитесь ИСТИННОГО ответа, если ЛОЖЬ, ПОДОЖДИТЕ 5 с, повторите попытку 3 раза, если превышаете ПРОДОЛЖИТЬ.
- После завершения сценарий завершается.
Другие заметки
Сценарий запускается планировщиком задач Windows.
Выполнение сценария займет около 2-10 минут в зависимости от того, сколько попыток выполнено, хотя планировщик настроен на запуск каждые 5 минут, но задание в планировщике настроено так, чтобы не запускать несколько экземпляров задачи, если запущено существующее .
Любые предложения будут великолепны.
Приветствия
Фрагмент кода. Надеюсь, предоставит достаточную идею.
Общий процесс - вызов скрипта sendTrackingEmails () из Dispatcher_cl.php, где он затем использует различные функции из MyCustomerMailer.php. MyCustomerMailer.php - более или менее абстрактный слой для PHPMailer.
Dispatcher_cl.php
public function sendTrackingEmails() {
try{
$this->processLog[] = __FUNCTION__;
/*
1.Get list of emails
2.Loop and send emails
*/
$ordersSent = array();
$ordersFailed = array();
$result = false;
$emailListAndInfo = $this->getEmailListAndInfo();
if($emailListAndInfo===false){
//No orders to dispatch emails. So do nothing.
$result = false;
}else{
$mail = new MyCustomMailer_cl();
if($mail->setSMTPParam('default')===true){
foreach($emailListAndInfo as $customer){
$sentFrom = array();
$replyTo = array();
$emailTo = array($customer['email'],$customer['name']);
$subject = array();
$body = null;
/*
Preset email settings for each brand.
When adding vendors, remember to add a BODY template and VENDOR ID to the SQL in [m_getEmailListAndInfo]
*/
if($customer['vendor_id']==3){
//Diamondphoto
$sentFrom = array('no-reply@email.com','Your order has been shipped');
$replyTo = array('no-reply@email.com','Your order has been shipped');
$subject = "Tracking for order {$customer['vendorOrderId']}";
$body = $this->getEmailTemplateFor(3,$customer);
}else{
/*
If vendor_id does not match existing setup, set TRYCOUNT to 99 as indicator and skip remaining execution.
Next script-run will not pick up this record due to 99 will be greater than the usual preset TRYCOUNT.
*/
$this->setTryCountForOrder($customer['order_id'],99);
continue;
}
$emailPackage['sentFrom'] = $sentFrom;
$emailPackage['replyTo'] = $replyTo;
$emailPackage['emailTo'] = $emailTo;
$emailPackage['subject'] = $subject;
$emailPackage['body'] = $body;
$mail->setupEmail($emailPackage);
for($i=1;$i<=$this->emailTryCount;$i++){
// $emailSentResult = $mail->send();
$emailSentResult = false;
if($emailSentResult===true){
$setFlagResult = $this->setSentFlagForOrder($customer['order_id'],$i);
if($setFlagResult===true){
$ordersSent[] = $customer['order_id'];
break;
}else{
throw new Exception("Update sent-flag for order {$customer['order_id']} failed.");
}
}else if($emailSentResult===false AND $i<$this->emailTryCount){
$this->setTryCountForOrder($customer['order_id'],$i);
// sleep($this->emailWaitTimer);
continue;
}else if($emailSentResult===false AND $i==$this->emailTryCount){
$this->setTryCountForOrder($customer['order_id'],$i);
$ordersFailed[] = $customer['order_id'];
}
}//End sending/attempting to send tracking email.
}//End of looping through the emailing list.
}//End of validation SMTP parameters.
$result = array('sent' =>$ordersSent
,'failed'=>$ordersFailed);
}//End of section for EMAIL-LIST exist
return $result;
}catch(Exception $e){
$this->processLog[] = __FUNCTION__.$e->getMessage();
throw $e;
}
}
MyCustomerMailer.php
<?PHP
require 'class/PHPMailer5.2/PHPMailerAutoload.php';
class MyCustomMailer_cl{
public $processLog = array();
private $dbConnect = null;
private $phpMailer = null;
private $SMTPDebug = null;
private $Debugoutput = null;
private $Host = null; //smtp.gmail.com OR smtp-relay.gmail.com
private $Port = null; //587
private $SMTPSecure = null; //tls or ssl
private $SMTPAuth = null; //true or false
private $Username = null;
private $Password = null;
private $sentFrom = array(); //array('example@gmail.com','Joe Doe');
private $replyTo = array(); //array('example@gmail.com','Joe Doe');
private $emailTo = array(); //array('example@gmail.com','Joe Doe');
private $subject = null; //Plain text
private $body = null; //Plain text
public function __construct() {
try{
$this->processLog[] = __FUNCTION__;
}catch(Exception $e){
$this->processLog[] = __FUNCTION__.$e->getMessage();
throw $e;
}
}
/*******************************************************************
SET functions
********************************************************************/
public function setSMTPParam($param) {
/*
$param can be a text string 'default' or an array.
$param = array( 'SMTPDebug' =>null
,'Debugoutput' =>null
,'Host' =>null
,'Port' =>null
,'SMTPSecure' =>null
,'SMTPAuth' =>null
,'Username' =>null
,'Password' =>null
);
*/
try{
$this->processLog[] = __FUNCTION__;
$paramError = 0;
$result = false;
if($param=='default'){
$param = array( 'SMTPDebug' =>0
,'Debugoutput' =>'html'
,'Host' =>'smtp-relay.gmail.com' //smtp.gmail.com OR smtp-relay.gmail.com
,'Port' =>587
,'SMTPSecure' =>'tls'
,'SMTPAuth' =>true
,'Username' =>"myEmail@email.com"
,'Password' =>"myPassword"
);
}else if(!is_array($param)){
throw new Exception('ERROR1901155: SMTP parameter is not an array.');
}
//Validation - 2019.01.17 need more work, script randomly fails check here.
foreach($param as $parameter){
if($parameter==='' OR is_null($param)){
$paramError++;
}
}
if($paramError==0){
$this->SMTPDebug = $param['SMTPDebug'];
$this->Debugoutput = $param['Debugoutput'];
$this->Host = $param['Host'];
$this->Port = $param['Port'];
$this->SMTPSecure = $param['SMTPSecure'];
$this->SMTPAuth = $param['SMTPAuth'];
$this->Username = $param['Username'];
$this->Password = $param['Password'];
$this->phpMailer = new PHPMailer;
$this->phpMailer->isSMTP();
$this->phpMailer->SMTPDebug = $this->SMTPDebug;
$this->phpMailer->Debugoutput = $this->Debugoutput;
$this->phpMailer->Host = $this->Host;
$this->phpMailer->Port = $this->Port;
$this->phpMailer->SMTPSecure = $this->SMTPSecure;
$this->phpMailer->SMTPAuth = $this->SMTPAuth;
$this->phpMailer->Username = $this->Username;
$this->phpMailer->Password = $this->Password;
$result = true;
}
return $result;
}catch(Exception $e){
$this->processLog[] = __FUNCTION__.$e->getMessage();
throw $e;
}
}
public function setupEmail($data) {
try{
$this->processLog[] = __FUNCTION__;
$this->sentFrom = $data['sentFrom'];
$this->phpMailer->setFrom($this->sentFrom[0],$this->sentFrom[1]);
$this->replyTo = $data['replyTo'];
$this->phpMailer->addReplyTo($this->replyTo[0],$this->replyTo[1]);
$this->emailTo = $data['emailTo'];
$this->phpMailer->addAddress($this->emailTo[0],$this->emailTo[1]);
$this->subject = $data['subject'];
$this->phpMailer->Subject = $this->subject;
$this->body = $data['body'];
$this->phpMailer->msgHTML($this->body);
}catch(Exception $e){
$this->processLog[] = __FUNCTION__.$e->getMessage();
throw $e;
}
}
public function send() {
try{
$this->processLog[] = __FUNCTION__;
$result = false;
if (!$this->phpMailer->send()) {
// throw new exception("error20190114: Failed to send at final stage.");
$result = false;
}else{
$result = true;
}
return $result;
}catch(Exception $e){
$this->processLog[] = __FUNCTION__.$e->getMessage();
throw $e;
}
}
public function sendWithRetry($attempt=3,$waitTime=5) {
try{
$this->processLog[] = __FUNCTION__;
$result = false;
for($i=1;$i<=$attempt;$i++){
if(!$this->phpMailer->send()){
if($i==$attempt){
break;
}else{
continue;
}
}else{
$result=true;
break;
}
}
return $result;
}catch(Exception $e){
$this->processLog[] = __FUNCTION__.$e->getMessage();
throw $e;
}
}
}
?>