iT邦幫忙

0

PHP+Gmailer(5.5)+Gmail連續發送會錯誤 454 4.7.0 Too many login attempts

PHP 7.4
Gmailer 5.5
Gmail不是免費的,是付費的 Gsuit (id@custom.com)
少量發送沒有問題,但是當超過90~100封左右時就會出現錯誤

CLIENT -> SERVER: [credentials hidden] SERVER -> CLIENT: 454 4.7.0 Too many login attempts, please try again later. d5sm9100213pfo.186 - gsmtp
SMTP ERROR: Password command failed: 454 4.7.0 Too many login attempts, please try again later. d5sm9100213pfo.186 - gsmtp
SMTP Error: Could not authenticate. CLIENT -> SERVER: QUIT

上網查有一說是可以加上 $mail->SMTPKeepAlive = true; //保持登入狀態
以解決上述問題,但是經過測試問題還是一樣發生,想請教應該怎麼做才是正確的?
謝謝
以下是發送用的程式內容:

<?php
  //發送對象名單陣列遞迴發送
  foreach ($mail_list_array as $key=>$office_email){
    if($office_email!=''){
      //-------E-mail資訊-------
      $EDM_Date = time();//date("Y-m-d_H:i:s");//發送日期戳記
      $EDM_Title = $row_list[0]['title'];//標題
      $EDM_addAddress = "$office_email";//收件者
      $EDM_From = "";//來源信箱
      $EDM_Writer_mail = "";//回覆信箱
      $EDM_Writer = "";//作者
      $EDM_AltBody = "";//提示

      //-------發送信箱-------
      $Username[0]="id1@custom.com";   $Password[0]="pwd";
      $Username[1]="id2@custom.com";   $Password[1]="pwd";

      //-------發送模式-------
      $send_mode = 2;
      $sender_sn = $key % 2; //0;
      $file_title = $row_list[0]['type'];

      //Create a new PHPMailer instance
      $mail = new PHPMailer();
      $mail->isSMTP();
      $mail->CharSet = 'UTF-8';
      $mail->SMTPDebug = SMTP::DEBUG_SERVER;
      $GLOBALS['debug'] = '';
      $mail->Debugoutput = function($str, $level) {
        $GLOBALS['debug'] .= "\t$str";
      };
      $mail->Host = 'smtp.gmail.com';
      $mail->Port = 465;
      $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
      $mail->SMTPKeepAlive = true; //保持登入狀態
      $mail->SMTPAuth = true;
      $mail->Username = $Username[$sender_sn];
      $mail->Password = $Password[$sender_sn];
      $mail->setFrom($EDM_From,$EDM_Writer);
      $mail->addReplyTo($EDM_Writer_mail,$EDM_Writer);
      $mail->addAddress($EDM_addAddress);
      $mail->Subject = $EDM_Title;
      $mail->msgHTML($EDM_HTML);
      $mail->AltBody = $EDM_AltBody;

      if(filter_var($EDM_addAddress, FILTER_VALIDATE_EMAIL)){//檢查發送對象email格式
        //驗證 email domain
        $domain = explode("@", $EDM_addAddress);
        if(checkdnsrr($domain[1],"MX")) {
          //有效 MX
          //格式正確->發送
          if ($send_mode? !$mail->send() : 1) {
            //發送錯誤
            $status = "error";
          } else {
            //發送成功
            $status = "OK";
          }
        } else {
          //無效 MX
          //格式錯誤->不發送
          $status = "E-mail格式(Domain)不正確";
        }
      }else{
        //格式錯誤->不發送
        $status = "E-mail格式不正確";
      }
    }
    $mail->clearAddresses(); //清除發信對象
    $mail->clearAllRecipients(); //清除發信對象
  }
  //發送狀態:完成
  $mail->smtpClose(); //登出帳號 斷開SMTP
?>
Wang.W iT邦新手 5 級 ‧ 2021-09-07 14:11:00 檢舉
我好像找出問題了,迴圈設錯層級了
Wang.W iT邦新手 5 級 ‧ 2021-09-08 13:18:02 檢舉
補充一點,迴圈最好加上 sleep(3); 做一下秒數延遲
不然量大時還是有 error 的情況發生
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
japhenchen
iT邦超人 1 級 ‧ 2021-09-07 14:01:33
最佳解答

你應該把最開頭的foreach放到new PHPMailer()之後,只要產生一次smtp連接就可以發送多次,不要一封信一個連接,不然你一定會收到"Too many login attempt"的錯誤訊息

$mail = new PHPMailer();
$mail->isSMTP();
$mail->CharSet = 'UTF-8';
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$GLOBALS['debug'] = '';
$mail->Debugoutput = function($str, $level) {
    $GLOBALS['debug'] .= "\t$str";
};
$mail->Host = 'smtp.gmail.com';
$mail->Port = 465;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->SMTPKeepAlive = true; //保持登入狀態
$mail->SMTPAuth = true;
$mail->Username = $Username[$sender_sn];
$mail->Password = $Password[$sender_sn];
$mail->setFrom($EDM_From,$EDM_Writer);
$mail->addReplyTo($EDM_Writer_mail,$EDM_Writer);

foreach ($mail_list_array as $key=>$office_email){
    $mail->addAddress($EDM_addAddress);
    $mail->addAddress($EDM_addAddress);
    $mail->Subject = $EDM_Title;
    $mail->msgHTML($EDM_HTML);
    $mail->AltBody = $EDM_AltBody;

    if(filter_var($EDM_addAddress, FILTER_VALIDATE_EMAIL)){//檢查發送對象email格式
    //驗證 email domain
    $domain = explode("@", $EDM_addAddress);
    if(checkdnsrr($domain[1],"MX")) {
        //有效 MX
        //格式正確->發送
        if ($send_mode? !$mail->send() : 1) {
            //發送錯誤
            $status = "error";
        } else {
            //發送成功
            $status = "OK";
        }
    } else {
        //無效 MX
        //格式錯誤->不發送
        $status = "E-mail格式(Domain)不正確";
    }
    }else{
        //格式錯誤->不發送
        $status = "E-mail格式不正確";
    }
    $mail->clearAddresses(); //清除發信對象
    $mail->clearAllRecipients(); //清除發信對象
}
//發送狀態:完成
$mail->smtpClose(); //登出帳號 斷開SMTP          
      
Wang.W iT邦新手 5 級 ‧ 2021-09-07 14:11:53 檢舉

問完才發現到是迴圈層級的問題,謝謝提醒

我要發表回答

立即登入回答