如何让PHPMailer autoresponder按收件邮箱返回不同HTML内容
基于PHPMailer的自动回复功能实现问题解决
问题场景
需要实现自动回复功能:
- 当外部用户发送邮件至
no-reply@example.com时,自动回复指定HTML文本1 - 当发送至
info@example.com时,自动回复指定HTML文本2
尝试通过判断$mail->toAddress或$mail->recipient字段设置不同回复内容,但均未生效,以下是完整代码及尝试片段:
完整代码
<?php if (!isset($_GET['api_key']) || $_GET['api_key'] !== 'VALUE-OF-API') { echo "Access denied!"; exit; } $unwantedEmails = array( 'no-reply', 'noreply', 'no-return', 'noreturn', 'automessage', 'auto-message', 'notification', 'support', 'postmaster', 'do-not-reply', 'donotreply', 'auto-reply', 'automated-reply', 'auto-response', 'out-of-office', 'vacation-reply', 'autoresponder', 'auto-responder', 'auto-reply', 'auto-reply-system', 'auto-message', 'auto-notification', 'automated-message', 'automated-response', 'automated-email', 'no-reply-needed', 'noreply-necessary', 'no-reply-requested', 'auto-no-reply', 'do-not-reply-automated', 'automated-no-reply', 'auto-response-only', 'automated-reply-only', 'no-reply-auto', 'auto-message-no-reply', 'noreply-automatic', 'no-reply-message', 'automated-donotreply', 'auto-no-return', 'automated-no-return', 'no-reply-auto-message', 'noreply-auto-response', 'auto-response-noreply' ); require 'vendor/autoload.php'; use PhpImap\Mailbox; use PHPMailer\PHPMailer\PHPMailer; // IMAP服务器连接信息 $hostname = '{imap.mail.me.com:993/imap/ssl/novalidate-cert}'; $username = 'example@icloud.com'; $password = 'xxx'; $mailbox = new Mailbox($hostname, $username, $password); $answeredEmailsFile = 'answered_mails.txt'; $mailsIds = $mailbox->searchMailbox('ALL', SORTDATE, true); $answeredEmails = []; if (file_exists($answeredEmailsFile)) { $answeredEmails = unserialize(file_get_contents($answeredEmailsFile)); } if (!empty($mailsIds)) { foreach ($mailsIds as $mailId) { if (!is_array($answeredEmails) || !in_array($mailId, $answeredEmails)) { $mail = $mailbox->getMail($mailId, false); $from = $mail->fromAddress; $isUnwantedEmail = false; foreach ($unwantedEmails as $unwantedEmail) { if (stripos($from, $unwantedEmail) !== false) { $isUnwantedEmail = true; break; } } if (!$isUnwantedEmail) { $subject = $mail->subject; $date = $mail->date; $email_body = $mail->textPlain; echo "From: $from<br>"; echo "Subject: $subject<br>"; echo "Date: $date<br>"; echo "<br>"; sendAutoresponder($from, $subject, $email_body); $answeredEmails[] = $mailId; } else { echo "No E-Mail sent to $from because rule do not reply to '$from'<br>"; } } } $fileHandle = fopen($answeredEmailsFile, 'w'); if ($fileHandle) { fwrite($fileHandle, serialize($answeredEmails)); fclose($fileHandle); } else { echo "Error: Failed to open the file for writing."; } } else { echo "No new mails found."; } function sendAutoresponder($recipient, $subject, $body) { $mail = new PHPMailer(); $mail->isSMTP(); $mail->Host = 'smtp.mail.me.com'; $mail->Port = 587; $mail->SMTPSecure = 'tls'; $mail->SMTPAuth = true; $mail->Username = 'example@icloud.com'; $mail->Password = 'xxx'; $mail->setFrom('no-reply@example.com', 'noreply@example.com'); $mail->addReplyTo('noreply@example.com', 'noreply@example.com'); $mail->addAddress($recipient); $mail->Subject = '### Auto Message ###'; $mail->CharSet = 'UTF-8'; $mail->isHTML(true); $mail->Body = '<html><body>Text for no-reply@example.com here!</body></html>'; // 疑问:如何根据收件邮箱设置自定义回复内容? $mail->addCustomHeader('Precedence', 'bulk'); $mail->addCustomHeader('Auto-Submitted', 'auto-generated'); if (!$mail->send()) { echo 'E-Mail konnte nicht gesendet werden.'; echo 'Mailer Error: ' . $mail->ErrorInfo; } else { echo 'Autoresponded to ' . $recipient . ' sent.'; } } ?>
尝试的无效代码片段
// 判断邮件是否发送到no-reply地址 if (stripos($mail->toAddress, 'no-reply@example.com') !== false) { $email_body = "<html><body>E-Mail empfangen an no-reply@example.com</body></html>"; } else { $email_body = "<html><body>E-Mail empfangen an info@example.com</body></html>"; }
// 判断邮件是否发送到no-reply地址 if (stripos($mail->recipient, 'no-reply@example.com') !== false) { $email_body = "<html><body>E-Mail empfangen an no-reply@example.com</body></html>"; } else { $email_body = "<html><body>E-Mail empfangen an example.com</body></html>"; }
问题原因
使用的PhpImap库中,Mail对象的收件人信息并非存放在toAddress或recipient字段,而是存储在$mail->to数组中(数组元素为包含邮箱地址的对象),因为单封邮件可能包含多个收件人,所以需要遍历该数组匹配目标邮箱。
解决方案
步骤1:在主逻辑中匹配目标收件邮箱并选择回复内容
在获取邮件后,遍历$mail->to数组判断收件邮箱,生成对应的回复HTML内容,再将该内容传递给sendAutoresponder函数:
// ... 原有代码 ... if (!$isUnwantedEmail) { $subject = $mail->subject; $date = $mail->date; $email_body = $mail->textPlain; echo "From: $from<br>"; echo "Subject: $subject<br>"; echo "Date: $date<br>"; echo "<br>"; // 新增:判断邮件收件邮箱,选择对应回复内容 $replyHtml = ''; foreach ($mail->to as $toRecipient) { $toEmail = $toRecipient->mail; if ($toEmail === 'no-reply@example.com') { $replyHtml = '<html><body>Text for no-reply@example.com here!</body></html>'; break; } elseif ($toEmail === 'info@example.com') { $replyHtml = '<html><body>Text for info@example.com here!</body></html>'; break; } } // 兜底:如果匹配不到指定邮箱,设置默认回复内容 if (empty($replyHtml)) { $replyHtml = '<html><body>Default auto-reply text here!</body></html>'; } // 修改:传递回复HTML内容给函数 sendAutoresponder($from, $subject, $email_body, $replyHtml); $answeredEmails[] = $mailId; } // ... 原有代码 ...
步骤2:修改sendAutoresponder函数接收回复内容参数
更新函数定义,新增$replyHtml参数,并将其赋值给$mail->Body:
function sendAutoresponder($recipient, $subject, $body, $replyHtml) { $mail = new PHPMailer(); $mail->isSMTP(); $mail->Host = 'smtp.mail.me.com'; $mail->Port = 587; $mail->SMTPSecure = 'tls'; $mail->SMTPAuth = true; $mail->Username = 'example@icloud.com'; $mail->Password = 'xxx'; $mail->setFrom('no-reply@example.com', 'noreply@example.com'); $mail->addReplyTo('noreply@example.com', 'noreply@example.com'); $mail->addAddress($recipient); $mail->Subject = '### Auto Message ###'; $mail->CharSet = 'UTF-8'; $mail->isHTML(true); // 修改:使用传入的回复HTML内容 $mail->Body = $replyHtml; $mail->addCustomHeader('Precedence', 'bulk'); $mail->addCustomHeader('Auto-Submitted', 'auto-generated'); if (!$mail->send()) { echo 'E-Mail konnte nicht gesendet werden.'; echo 'Mailer Error: ' . $mail->ErrorInfo; } else { echo 'Autoresponded to ' . $recipient . ' sent.'; } }
说明
$mail->to数组中的每个元素是一个对象,其mail属性存储收件人邮箱地址- 遍历数组匹配到目标邮箱后立即跳出循环,避免重复匹配
- 增加兜底逻辑,确保即使没有匹配到指定邮箱也能发送默认回复
内容的提问来源于stack exchange,提问作者user21420849
相关产品推荐
相关产品推荐

