WordPress 不用插件,通过 SMTP 实现邮件发送功能

在实验室摸鱼不想干活儿,想着不如趁着工作时间把博客的功能完善一下,于是搜了一些教程,让本站现在支持发送邮件!

注:本文参考了第三方教程:网页链接。正文内容可能意思相近,但并非直球机翻,而是加上本人理解后写成,亦无复制粘贴,如有版权问题请联系本站点管理员。

一、安装并配置 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/

《WordPress 不用插件,通过 SMTP 实现邮件发送功能》上有1条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据