В двух словах ситуация: mail.ru добавил наш ip в черный список. Теперь наши клиенты, у которых ящик на маиле не могут сменить пароль, подтвердить заказ по имейлу и т.д. Было решено отправлять на маиловские сервисы почту через smtp.
Проблема: письма не уходят. SUCCESS_EXEC у событий отправки письма: N. Через стандартный mail() письма уходят корректно.
Вот функция custom_mail:
Вот класс Mail:
Искал проблему, начал логировать checkStatus. Выяснил, что при отправке
код возвращается не 250, а 554. Соответственно происходит просто die(). А теперь вопрос - почему возвращается 554 и как с этим бороться?
Проблема: письма не уходят. SUCCESS_EXEC у событий отправки письма: N. Через стандартный mail() письма уходят корректно.
Вот функция custom_mail:
Код |
---|
function custom_mail($to, $subject, $message, $additional_headers, $additional_parameters){ if(loadClass('Mail')){ $data = Array( 'to' => $to, 'title' => $subject, 'text' => $message ); $tmp = explode('@', $to); $tmp1 = explode('.', $tmp[1]); if(($tmp1[0] == 'mail') || ($tmp1[0] == 'inbox') || ($tmp1[0] == 'bk') || ($tmp1[0] == 'list')){ return Mail::sendMail($data); } else { return @mail($to, $subject, $message, $additional_headers); } } } |
Код |
---|
class Mail{ private static function read_socet($smtp_conn) { $data=""; while($str = fgets($smtp_conn,515)) { $data .= $str; if(substr($str,3,1) == " ") { break; } } return $data; } private static function send_comand($connection,$comand){ fputs($connection,$comand); } private static function getHeader($conf){ $header="Date: ".date("D, j M Y G:i:s")." +0700\r\n"; $header.="From: =?cp-1251?Q?".str_replace("+","_",str_replace("%","=",urlencode($conf['my_name'])))."?= <" . $conf['from'] . ">\r\n"; $header.="X-Mailer: The Bat! (v3.99.3) Professional\r\n"; //$header.="Reply-To: =?UTF-8?Q?".str_replace("+","_",str_replace("%","=",urlencode('ГЊГ*ГЄГ±ГЁГ¬')))."?= <login@mail.ru>\r\n"; $header.="X-Priority: 3 (Normal)\r\n"; $header.="Message-ID: <172562218.".date("YmjHis")."@".$conf['domain'].">\r\n"; $header.="To: =?cp-1251?Q?".str_replace("+","_",str_replace("%","=",urlencode($conf['name_rec'])))."?= <".$conf['to'].">\r\n"; $header.="Subject: " . $conf['title'] . "\r\n"; $header.="MIME-Version: 1.0\r\n"; $header.="Content-Type: " . $conf['type'] . "; charset=cp-1251\r\n"; $header.="Content-Transfer-Encoding: 8bit\r\n"; return $header; } private static function checkStatus($connection, $codeOK){ $data = SELF::read_socet($connection); $code = substr($data,0,3); //echo '<br> == '.$data.'<br>'; if($codeOK != $code) die('Fatal error'); return true; } private static function getMailText($data) { if(!empty(__DIR__ . '/. ./templates/window/mail/' . $data['template']. '.tpl')) $file = __DIR__ . '/. ./templates/window/mail/' . $data['template']. '.tpl'; if(!empty($file) && file_exists($file)) { ob_start(); include $file; $html = ob_get_contents(); ob_end_clean(); } return !empty($html) ? $html : $data['text']; } private static function get_smtp_connection($type = 'yandex.ru') { switch($type){ case 'yandex.ru' : return fsockopen("ssl://smtp.yandex.ru", 465,$errno, $errstr, 10); break; case 'mail.ru' : return fsockopen("smtp.mail.ru", 25,$errno, $errstr, 10); break; default: return null; } } private static function getConfig() { return array( 'login' => 'login', //Здесь мои логин и пароль 'pass' => 'password', 'domain' => 'yandex.ru', 'name_rec' => '', 'to' => 'info@nstopt.ru', 'my_name' => admin@nstopt.ru', 'title' => 'title', 'from' => 'admin@nstopt.ru', 'copy' => '', 'type' => 'text/html' ); } private static function reconf($data, &$conf) { $conf['name_rec'] = !empty($data['name_rec']) ? $data['name_rec'] : $conf['name_rec']; $conf['to'] = !empty($data['to']) ? $data['to'] : $conf['to']; $conf['my_name'] = !empty($data['my_name']) ? $data['my_name'] : $conf['my_name']; $conf['title'] = !empty($data['title']) ? $data['title'] : $conf['title']; $conf['type'] = !empty($data['type']) ? $data['type'] : $conf['type']; } static function sendMail($data){ if($connection = SELF::get_smtp_connection()) { $conf = SELF::getConfig(); SELF::reconf($data,$conf); $header = SELF::getHeader($conf); //$text = SELF::getMailText($data); $text = $data['text']; SELF::checkStatus($connection,220); SELF::send_comand($connection, "EHLO " . $conf['domain'] . "\r\n"); SELF::checkStatus($connection,250); SELF::send_comand($connection, "AUTH LOGIN\r\n"); SELF::checkStatus($connection,334); SELF::send_comand($connection, base64_encode($conf['login'])."\r\n"); SELF::checkStatus($connection,334); SELF::send_comand($connection, base64_encode($conf['pass'])."\r\n"); SELF::checkStatus($connection,235); SELF::send_comand($connection, "MAIL FROM: " . $conf['login'] . "@" . $conf['domain'] . "\r\n"); SELF::checkStatus($connection,250); SELF::send_comand($connection, "RCPT TO:" . $conf['to'] . "\r\n"); SELF::checkStatus($connection,250); SELF::send_comand($connection, "DATA\r\n"); SELF::checkStatus($connection,354); SELF::send_comand($connection, $header."\r\n".$text."\r\n.\r\n"); SELF::checkStatus($connection,250); if(!empty($conf['copy'])){ //====================================== SELF::send_comand($connection, "MAIL FROM: " . $conf['login'] . "@" . $conf['domain'] . "\r\n"); SELF::checkStatus($connection,250); SELF::send_comand($connection, "RCPT TO:" . $conf['copy'] . "\r\n"); SELF::checkStatus($connection,250); SELF::send_comand($connection, "DATA\r\n"); SELF::checkStatus($connection,354); SELF::send_comand($connection, $header."\r\n".$text."\r\n.\r\n"); SELF::checkStatus($connection,250); //============================================ } SELF::send_comand($connection, "QUIT\r\n"); SELF::checkStatus($connection,221); return true; } else { return false; } } } |
Код |
---|
SELF::send_comand($connection, $header."\r\n".$text."\r\n.\r\n"); SELF::checkStatus($connection,250); |
код возвращается не 250, а 554. Соответственно происходит просто die(). А теперь вопрос - почему возвращается 554 и как с этим бороться?