在实验室摸鱼不想干活儿,想着不如趁着工作时间把博客的功能完善一下,于是搜了一些教程,让本站现在支持发送邮件!
注:本文参考了第三方教程:网页链接。正文内容可能意思相近,但并非直球机翻,而是加上本人理解后写成,亦无复制粘贴,如有版权问题请联系本站点管理员。
一、安装并配置 mSMTP
Debian 系统在 2019 年 3 月时停止支持 sSMTP,推荐使用 mSMTP,且 mSMTP 完全适配 sendmail
的功能,因此本站使用 mSMTP 作为服务器的 SMTP 客户端。
首先,安装 mSMTP 和 mSMTP-mta,后者是为 msmtp
创建一个别名为 sendmail
,从而实现更好的兼容性。
sudo apt install msmtp msmtp-mta
mSMTP 的配置文件可以放在两个地方并且都是可选的:/etc/msmtprc
和 ~/.msmtprc
,并且在 /usr/share/doc/msmtp/examples
下有对应的示例配置文件。
笔者选择在用户目录下建立配置文件(~/.msmtprc
),内容去密后如下:
defaults # Use the mail submission port 587 instead of the SMTP port 25. port 587 # Always use TLS. tls on tls_starttls on # Set User log file path logfile /var/log/msmtp # A mail service account qqmail # Host name of the SMTP server host smtp.qq.com # Envelope-from address from username@example.com # Authentication. auth on user username password fakepassword # Set a default account account default : qqmail
上述配置文件主要进行了两方面工作:default
后和 account qqmail
之前,描述了 mSMTP 的一些默认设置,如启用 tls ,指定日志文件等,account qqmail
描述了一个名为 qqmail
(可以随便起)的邮箱账户,其后面则是描述了如何访问该 SMTP 邮件服务器的一系列信息,如主机名(host
)等。具体每行配置的含义可以参考注释或者 mSMTP 文档。
配置完成后,可以先测试一下 mSMTP 能否工作。新建一个文件比如 testmail
,输入如下内容:
From: 发件人 <username@example.com> To: 收件人 <recipient@example.com> Subject: 测试 msmtp 这是一封用 mSMTP 发送的测试邮件。
然后在命令行输入以下命令来将上述文件作为邮件发送出去,注意修改收件人(recipient@example.com
)为你发送邮件的目标邮箱:
cat testmail | msmtp recipient@example.com
如果你发送成功,mSMTP 会在日志文件 /var/log/msmtp
(记得自己建一个日志文件并给 mSMTP 访问权限,不然日志会直接输出到标准输出中)中留下发送邮件的记录。发送失败也会有日志记录,可以根据日志文件来 debug。
如果上述内容没有问题,使用如下命令启动 mSMTP 服务来方便 php 调用:
sudo systemctl start msmtpd.service
sudo systemctl status msmtpd.service
执行完后可以看到输出显示 mSMTP 正在运行。
二、配置 php 使用 mSMTP 来发送邮件(可选)
为了让 php 能够用上 mSMTP,我们可以修改 php 配置文件中的 sendmail_path
来显式指定 php 使用 mSMTP 来发送邮件。当然如果安装了 mSMTP-mta,由于 sendmail
将会作为一个别名指向 mSMTP,因此即使不编辑配置文件也可以,故本步骤是可选的。
首先找到你要修改的配置文件位置:
sudo find / -name php.ini
一般会找到两个配置文件:/etc/php/7.4/fpm/php.ini
和 /etc/php/7.4/cli/php.ini
,笔者服务器的 nginx 上使用的是 fpm
因此编辑第一个配置文件,在其中找到 sendmail_path
这一项并填写其为 mSMTP 的路径(在 bash 中执行 whereis msmtp
来得到)即可。
接下来测试 php 能否正常使用 mSMTP,新建一个文件 testmail.php
并输入(记得把收件人邮箱改成你要接收邮件的邮箱):
<?php
$to = "recipient@example.com";
$subj = "测试邮件";
$body = "这是一个用 php mail() 函数发送的测试邮件";
mail($to, $subj, $body);
?>
然后命令行执行:
php testmail.php
如果发送成功,接收邮箱可以收到邮件,mSMTP 日志文件也会有发送记录。
三、配置 WordPress 发送邮件
配置 WordPress 发送邮件需要修改 WordPress 的子主题,如果你不知道子主题是什么,那么笔者强烈建议你前往 WordPress 官网了解什么是子主题,并在子主题文件夹下修改 functions.php
文件。子主题可以有效地继承父主题的同时应用子主题的自定义功能,而不必直接修改父主题文件,从而避免主题更新导致的一些列问题(如自定义功能丢失)。
打开子主题的 functions.php
文件,并在其中添加以下内容:
add_action( 'phpmailer_init', 'send_smtp_email' );
function send_smtp_email( $phpmailer ) {
$phpmailer->IsSMTP();
$phpmailer->Host = SMTP_HOST;
$phpmailer->SMTPAuth = SMTP_AUTH;
$phpmailer->Port = SMTP_PORT;
$phpmailer->Username = SMTP_USER;
$phpmailer->Password = SMTP_PASS;
$phpmailer->SMTPSecure = SMTP_SECURE;
$phpmailer->From = SMTP_FROM;
$phpmailer->FromName = SMTP_NAME;
}
其原理是,WordPress 自带的方法 wp_mail()
使用 PHPMailer()
类来发送 SMTP 邮件。而 WordPress 的 phpmailer_init()
这一 action 钩子允许我们操纵对象 phpmailer
。因此我们在上述文件中定义了一个函数 send_smtp_email()
,并将该函数绑定到 action phpmailer_init
上,从而实现通过 phpmailer
对象来发送 SMTP 邮件。
函数 send_smtp_email()
中的 SMTP_XXXX
是一系列预定义的内容,为了安全,我们不把这些内容直接放在主题文件中,而是放在 WordPress 根目录下的 wp-config.php
内:
define( 'SMTP_HOST', 'smtp.example.com' ); // The mail server name
define( 'SMTP_PORT', '587' ); // SMTP port number
define( 'SMTP_SECURE', 'tls' ); // Encryption system tls
define( 'SMTP_AUTH', true ); // Use SMTP authentication
define( 'SMTP_USER', 'username@example.com' ); // Username for SMTP authentication
define( 'SMTP_PASS', 'password' ); // Password for SMTP authentication
define( 'SMTP_FROM', 'username@example.com' ); // SMTP From email address
define( 'SMTP_NAME', 'sendername' ); // sender name, for example: sendername<username@example.com>
将上述文件放在 wp-config.php
文件内(注意放在 ABSPATH
之前),WordPress 就配置完成了,你可以在站点上发个评论来测试看看是否会收到通知邮件(前提是打开了 WordPress 邮件通知,评论没有被反垃圾评论插件拦截,评论通过审核)。
四、没收到邮件怎么办
先检查你是否让 WordPress 真的发送邮件了,检查 WordPress 设置,是否勾选上了邮件通知选项,或者是否真的触发了 WordPress 应当发送邮件的操作(比如上节中所说的评论需要通过反垃圾评论插件检测且通过审核)。
如果收不到邮件,可以看看是不是发到垃圾箱里了,或者检查 mSMTP 日志是不是被 SMTP 服务器判定为垃圾邮件。
如果收不到邮件且上述 debug 方法仍然不管用,看 mSMTP 日志找不到发送邮件的记录,那么可以在子主题的 functions.php
中加一个 debug 函数来帮助我们调试:
// functions used for debug mail errors, log is stored at SERVER_ROOT_DIR/mail.log
add_action('wp_mail_failed', 'smtplog_mailer_errors', 10, 1);
function smtplog_mailer_errors( $wp_error ) {
$fn = ABSPATH . '/mail.log';
$fp = fopen($fn, 'a');
fputs($fp, "Mailer Error: " . $wp_error->get_error_message() . "\n");
fclose($fp);
}
该函数会记录 WordPress 发送邮件时候遇到的错误,日志存储在 WordPress 文件夹根目录的 mail.log
中,打开该日志即可查看出错的原因并进行相应的修改。
五、参考资料
- https://www.e-tinkers.com/2020/09/simple-steps-to-setup-wordpress-smtp-email-without-a-plugin/
- https://wpwebsitetools.com/how-to-send-mail-in-wordpress-without-a-plugin/
评论测试