优化 WordPress 评论回复通知邮件 解决回复评论提交速度巨慢问题

用上 G Suite 后,域名邮箱自然也托管到 Google,Gmail 配合 Gmail SMTP 插件使用,还行。更改后回复评论提交速度巨慢,肯定与这个评论回复通知邮件有关。

WordPress 回复评论提交速度巨慢?

症状:主题带评论回复邮件通知功能,新评论提交速度正常,只是回复评论提交速度巨慢。

理想解决办法:使用 wp_schedule_single_event 实现评论回复异步发送邮件通知,这样回复评论提交速度就正常了。

原本使用 VPS Postfix 直接发送,虽然基本上会进垃圾邮件,但是回复评论提交速度很快。再次尝试使用 wp_schedule_single_event 延迟发送评论回复通知邮件看看能不能改善一下这个问题,以前折腾过,经常会重复发送邮件或者不发,这次是死活不发……不知道哪里出问题,放弃……

折腾心不死,昨天又折腾,没找到更好的方法,最简单还是使用 wp_schedule_single_event 延时异步发送。再看之前的教程,貌似找到了问题所在:

wp_schedule_single_event 后面的参数需要是 action,不是函数,所以需要创建一个action。

WordPress 官方也是这么干!重新修改一下代码,测试,速度回来了,邮件也正常发送,看样子是成功了。

老头修改版 WordPress 评论回复异步发送通知邮件代码

代码中不包含 smtp,博客环境能正常发送邮件前提下,代码放主题 functions.php 文件即可(可能需要根据主题实际修改匹配)。

2021-04-20 更新:去除查看回复链接中的 /comment-page-1

2021-04-26 更新:wp_schedule_single_event 还是爱不起,已弃用。

/* 评论回复邮件通知 */
function comment_mail_notify($comment_id) {
$comment = get_comment($comment_id);
$content=$comment->comment_content;
$match_count=preg_match_all('/<a href="#comment-([0-9]+)?" rel="nofollow">/si',$content,$matchs);
if($match_count>0){
foreach($matchs[1] as $parent_id){
comment_mail_notify_sendmail($parent_id,$comment);
}
} elseif ($comment->comment_parent!='0'){
$parent_id=$comment->comment_parent;
comment_mail_notify_sendmail($parent_id,$comment);
} else {
$parent_id=$comment_id;
comment_mail_notify_sendmail($parent_id,$comment);
}
}
add_action('comment_mail_notify_async', 'comment_mail_notify');

function comment_mail_schedule_notify_async( $comment_id ) {
wp_schedule_single_event( time(), 'comment_mail_notify_async', [$comment_id] );
}
add_action('comment_post', 'comment_mail_schedule_notify_async');
add_action('wp_set_comment_status', 'comment_mail_schedule_notify_async');

function comment_mail_notify_sendmail($parent_id,$comment){
$tobackup = get_option('admin_email');//同时发送一份备份通知邮件到管理员邮箱
$author_email=$comment->comment_author_email;//评论者邮箱
$to = trim(get_comment($parent_id)->comment_author_email);//被回复者邮箱
$spam_confirmed = $comment->comment_approved;//comment_approved 等于1:通过审核的评论;0:待审核的评论;trash: 回收站的评论;spam : 垃圾评论
$wp_email = 'i@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])); // 发信 e-mail
if ( ($spam_confirmed == '1') && ( $to != $author_email ) ){
$subject = 'Re:《'.get_the_title($comment->comment_post_ID).' - ' . get_option("blogname") . '》';
$message_html = '<!DOCTYPE html><html style="font-size:100%;margin:0;padding:0"><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>您在《'.get_the_title($comment->comment_post_ID).' - ' . get_option("blogname") . '》的评论有新回复</title><style type="text/css">.wp-smiley{width:23px!important;height:auto!important;max-height:none!important;margin-right:5px;}</style><div bgcolor="#f5efe0" style="background:#f5efe0;clear:both!important;display:block!important;max-width:600px!important;margin:0 auto;padding:16px;border-width:0;box-shadow:0 1px 2px rgba(9,2,1,.1),0 0 10px rgba(0,0,0,.06)"><h1 style="font-weight:400;font-size:1.35em;color:#333;margin:0 0 10px;padding-bottom:10px;border-bottom:1px solid rgba(0,0,0,.08)"><a style="text-decoration:none;color:#333" href="'.get_option('home').'" target="_blank">'.get_option("blogname").'</a></h1><p style="font-size:14px;color:#354450;font-weight:400;margin:20px 0 0;padding:0">'.trim(get_comment($parent_id)->comment_author).',您好!您在文章《'.get_the_title($comment->comment_post_ID).'》发表的评论:</p><p style="background-color:#f9f9f9;padding:15px;margin:10px 0;font-size:14px;color:#354450;line-height:1.6em;font-weight:normal">'.nl2br(get_comment($parent_id)->comment_content).'</p><p style="font-size:14px;color:#354450;font-weight:400;margin:20px 0 0;padding:0">'.trim($comment->comment_author).'给您回复如下:</p><p style="background-color:#f9f9f9;padding:15px;margin:10px 0;font-size:14px;color:#354450;line-height:1.6em;font-weight:normal">'.nl2br($comment->comment_content).'</p><p style="font-size:14px;color:#354450;line-height:1.6em;font-weight:400;margin:20px 0;padding:0">您可以点击 <a style="text-decoration:none;color:#5692BC" href="'.htmlspecialchars(str_replace('/comment-page-1', '', get_comment_link($parent_id,array("type" => "all")))).'" target="_blank">查看完整回复</a>,也欢迎您再次光临 <a style="text-decoration:none;color:#5692BC" href="'. get_option("home").'" target="_blank">'.get_option("blogname").'</a>。祝您天天开心!</p><p style="color:#999;font-size:12px;font-weight:400;margin:0;padding:10px 0 0;border-top:1px solid rgba(0,0,0,.08)">本邮件由博客评论系统自动发出,意在新评论通知。可直接回复联系博主。</p></div>';
$message_plain = '您在《'.get_the_title($comment->comment_post_ID).' - ' . get_option("blogname") . '》的评论有新回复'."\r\n\r\n".trim(get_comment($parent_id)->comment_author).',您好!您在文章《'.get_the_title($comment->comment_post_ID).'》发表的评论:'."\r\n".nl2br(strip_tags(get_comment($parent_id)->comment_content))."\r\n\r\n".trim($comment->comment_author).'给您回复如下:'."\r\n".nl2br(strip_tags($comment->comment_content))."\r\n\r\n".'您可以通过下面链接查看完整回复,也欢迎再次光临'.get_option("blogname").'。祝您天天开心!'."\r\n".htmlspecialchars(str_replace('/comment-page-1', '', get_comment_link($parent_id,array("type" => "all"))))."\r\n\r\n".'本邮件由博客评论系统自动发出,意在新评论通知。可直接回复联系博主。';
}
$message_html = str_replace("*uniqueID*", substr(md5(uniqid() . microtime()), 0, 5), convert_smilies($message_html));
//Hook phpmailer init action, then force change message_type to alt.https://blog.lwl12.com/read/abandon-duoshuo-hole-log.html
global $phpmailer;
add_action('phpmailer_init', function (&$phpmailer) use ($message_html, $message_plain){
$phpmailer->isHTML(true);
$phpmailer->Body = $message_html;
$phpmailer->AltBody = $message_plain;
$phpmailer->CharSet = 'utf-8';
$phpmailer->Encoding = 'base64';
$phpmailer->MessageID = '<' . md5($message_plain.microtime().uniqid()).'@'.preg_replace("/^www\./", "", parse_url(esc_url( home_url('/') ), PHP_URL_HOST)).'>';
});
$headers = "Reply-To: ".trim($comment->comment_author)."-".get_option('blogname')." <".$author_email."> " . "\n";

wp_mail( $to, $subject, $message_html, $headers );
if( $to != $tobackup ){
wp_mail( $tobackup, $subject, $message_html, $headers );
}
}
/* 评论回复邮件通知 END */

WordPress 评论回复通知邮件代码(@ZE3kr 版本)

@ZE3kr 代码地址:Github,同样代码放主题 functions.php 文件即可(可能需要根据主题实际修改匹配)

<?php
function tlo_comment_mail_notify($comment_id) {
global $comment_author;
$comment = get_comment($comment_id);
$parent_id = $comment->comment_parent ? $comment->comment_parent : '';
$spam_confirmed = $comment->comment_approved;
$from = $comment->comment_author_email;
$to = get_comment($parent_id)->comment_author_email;
if (($parent_id != '') && ($spam_confirmed != 'spam') && $from != $to && $to != get_bloginfo('admin_email') ) {
$blog_name = get_option('blogname');
$blog_url = site_url();
$post_url = get_permalink( $comment->comment_post_ID );
$comment_author = $comment->comment_author;
$subject = 'Re: '.html_entity_decode(get_the_title($comment->comment_post_ID));
$headers[] = 'Reply-To: '.$comment_author.' <'.$comment->comment_author_email.'>';
$comment_parent = get_comment($parent_id);
$comment_parent_date = tlo_get_comment_date( $comment_parent );
$comment_parent_time = tlo_get_comment_time( $comment_parent );
$message = <<<HTML
<!DOCTYPE html>
<html lang="zh">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>$blog_name</title>
</head>
<body>
<style type="text/css">
img {
max-width: 100%; height: auto;
}
</style>
<div class="content">
<div>
<p>$comment->comment_content</p>
</div>
</div>
<div class="footer" style="margin-top: 10px">
<p style="color: #777; font-size: small">
&mdash;
<br>
直接回复此邮件可单独与回复者交流,或者<a href="$post_url#comment-$comment_id">在 $blog_name 上查看</a>。
<br>
你收到这封邮件是因为你在 $blog_name 上的评论得到了回复。
</p>
</div>
<blockquote type="cite">
<div>在 {$comment_parent_date},{$comment_parent_time},$comment_parent->comment_author &lt;<a href="mailto: $comment_parent->comment_author_email">$comment_parent->comment_author_email</a>&gt; 写到:</div>
<br>
<div class="content">
<div>
<p>$comment_parent->comment_content</p>
</div>
</div>
</blockquote>
</body>
</html>
HTML;
add_filter( 'wp_mail_content_type', 'tlo_mail_content_type' );
add_filter( 'wp_mail_from_name', 'tlo_mail_from_name' );
wp_mail( $to, $subject, $message, $headers );
}
}
add_action('tlo_comment_post_async', 'tlo_comment_mail_notify');

function tlo_comment_mail_notify_async($comment_id) {
wp_schedule_single_event( time(), 'tlo_comment_post_async', [$comment_id] );
}
add_action('comment_post', 'tlo_comment_mail_notify_async');
// add_action('comment_post', 'tlo_comment_mail_notify');

function tlo_mail_content_type() {
return 'text/html';
}
function tlo_mail_from_name() {
global $comment_author;
return $comment_author;
}

function tlo_get_comment_time( $comment ) {
$date = mysql2date(get_option('time_format'), $comment->comment_date, true);

return apply_filters( 'tlo_get_comment_time', $date, $comment );
}
function tlo_get_comment_date( $comment ) {
$date = mysql2date(get_option('date_format'), $comment->comment_date);

return apply_filters( 'tlo_get_comment_date', $date, $comment );
}

两个版本按需取其中一个即可,可能需要根据实际环境修改匹配。

后记:wp_schedule_single_event 不工作?

使用 wp_schedule_single_event 大大半年,Gmail 发送邮件通知看起来也还正常,不过最近升级 WordPress 后发现又基本上不会发送评论回复通知邮件了,降级到 WordPress 5.7 问题依旧,改代码,还是一样。

好吧,还是折腾不动。换回 VPS Postfix 发信算了,虽然就算折腾上 OpenDKIM 邮件认证,通知邮件仍然大概率进入垃圾邮件信箱,但是起码回复评论提交速度正常。

2021-04-26,老头目前在用版本:vps 配置好 Postfix,博客环境能正常发送邮件,代码放主题 functions.php 文件即可(可能需要根据主题实际修改匹配)。

/* 评论回复邮件通知 */
//指定发件 Email 地址为 noreply@xx.com
function theme_custom_wp_mail_from( $original_email_address ) {
return str_replace( 'wordpress@', 'noreply@', $original_email_address );
}
add_filter( 'wp_mail_from', 'theme_custom_wp_mail_from' );
//指定发件人名称为 博客名
function theme_wp_mail_from_name( $original_email_from ) {
return get_option('blogname');
}
add_filter( 'wp_mail_from_name', 'theme_wp_mail_from_name' );
function comment_mail_notify($comment_id) {
$comment = get_comment($comment_id);
$content=$comment->comment_content;
$match_count=preg_match_all('/<a href="#comment-([0-9]+)?" rel="nofollow">/si',$content,$matchs);
if($match_count>0){
foreach($matchs[1] as $parent_id){
comment_mail_notify_sendmail($parent_id,$comment);
}
} elseif ($comment->comment_parent!='0'){
$parent_id=$comment->comment_parent;
comment_mail_notify_sendmail($parent_id,$comment);
} else {
$parent_id=$comment_id;
comment_mail_notify_sendmail($parent_id,$comment);
}
}
add_action('comment_post', 'comment_mail_notify');
add_action('wp_set_comment_status', 'comment_mail_notify');
function comment_mail_notify_sendmail($parent_id,$comment){
$tobackup = get_option('admin_email');//同时发送一份到管理员邮箱
$author_email=$comment->comment_author_email;//评论人邮箱
$to = trim(get_comment($parent_id)->comment_author_email);//被回复人邮箱
$spam_confirmed = $comment->comment_approved;
if ( ($spam_confirmed == '1') && ( $to != $author_email ) ){
$subject = 'Re:《'.get_the_title($comment->comment_post_ID).' - ' . get_option("blogname") . '》';
$message_html = '<!DOCTYPE html><html style="font-size:100%;margin:0;padding:0"><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>您在《'.get_the_title($comment->comment_post_ID).' - ' . get_option("blogname") . '》的评论有新回复</title><style type="text/css">.wp-smiley{width:23px!important;height:auto!important;max-height:none!important;margin-right:5px;}</style><div bgcolor="#f5efe0" style="background:#f5efe0;clear:both!important;display:block!important;max-width:600px!important;margin:0 auto;padding:16px;border-width:0;box-shadow:0 1px 2px rgba(9,2,1,.1),0 0 10px rgba(0,0,0,.06)"><h1 style="font-weight:400;font-size:1.35em;color:#333;margin:0 0 10px;padding-bottom:10px;border-bottom:1px solid rgba(0,0,0,.08)"><a style="text-decoration:none;color:#333" href="'.get_option('home').'" target="_blank">'.get_option("blogname").'</a></h1><p style="font-size:14px;color:#354450;font-weight:400;margin:20px 0 0;padding:0">'.trim(get_comment($parent_id)->comment_author).',您好!您在文章《'.get_the_title($comment->comment_post_ID).'》发表的评论:</p><p style="background-color:#f9f9f9;padding:15px;margin:10px 0;font-size:14px;color:#354450;line-height:1.6em;font-weight:normal">'.nl2br(get_comment($parent_id)->comment_content).'</p><p style="font-size:14px;color:#354450;font-weight:400;margin:20px 0 0;padding:0">'.trim($comment->comment_author).'给您回复如下:</p><p style="background-color:#f9f9f9;padding:15px;margin:10px 0;font-size:14px;color:#354450;line-height:1.6em;font-weight:normal">'.nl2br($comment->comment_content).'</p><p style="font-size:14px;color:#354450;line-height:1.6em;font-weight:400;margin:20px 0;padding:0">您可以点击 <a style="text-decoration:none;color:#5692BC" href="'.htmlspecialchars(str_replace('/comment-page-1', '', get_comment_link($parent_id,array("type" => "all")))).'" target="_blank">查看完整回复</a>,也欢迎您再次光临 <a style="text-decoration:none;color:#5692BC" href="'. get_option("home").'" target="_blank">'.get_option("blogname").'</a>。祝您天天开心!</p><p style="color:#999;font-size:12px;font-weight:400;margin:0;padding:10px 0 0;border-top:1px solid rgba(0,0,0,.08)">本邮件由博客评论系统自动发出,意在新评论通知。可直接回复联系博主。</p></div>';
$message_plain = '您在《'.get_the_title($comment->comment_post_ID).' - ' . get_option("blogname") . '》的评论有新回复'."\r\n\r\n".trim(get_comment($parent_id)->comment_author).',您好!您在文章《'.get_the_title($comment->comment_post_ID).'》发表的评论:'."\r\n".nl2br(strip_tags(get_comment($parent_id)->comment_content))."\r\n\r\n".trim($comment->comment_author).'给您回复如下:'."\r\n".nl2br(strip_tags($comment->comment_content))."\r\n\r\n".'您可以通过下面链接查看完整回复,也欢迎再次光临'.get_option("blogname").'。祝您天天开心!'."\r\n".htmlspecialchars(str_replace('/comment-page-1', '', get_comment_link($parent_id,array("type" => "all"))))."\r\n\r\n".'本邮件由博客评论系统自动发出,意在新评论通知。可直接回复联系博主。';
}
$message_html = str_replace("*uniqueID*", substr(md5(uniqid() . microtime()), 0, 5), convert_smilies($message_html));
//https://blog.lwl12.com/read/abandon-duoshuo-hole-log.html
global $phpmailer;
add_action('phpmailer_init', function (&$phpmailer) use ($message_html, $message_plain){
$phpmailer->isHTML(true);
$phpmailer->Body = $message_html;
$phpmailer->AltBody = $message_plain;
$phpmailer->CharSet = 'utf-8';
$phpmailer->Encoding = 'base64';
$phpmailer->MessageID = '<' . md5($message_plain.microtime().uniqid()).'@'.preg_replace("/^www\./", "", parse_url(esc_url( home_url('/') ), PHP_URL_HOST)).'>';
});
$headers = "Reply-To: ".trim($comment->comment_author)."-".get_option('blogname')." <".$author_email."> " . "\n";
wp_mail( $to, $subject, $message_html, $headers );
if( $to != $tobackup ){
wp_mail( $tobackup, $subject, $message_html, $headers );
}
}
/* 评论回复邮件通知 end */

除非注明,垃圾站文章均为网络收集,本文地址 https://cyhour.com/1382/,转载时烦请以链接形式注明原始出处。
声明:我们不销售主机,选主机需合法使用。任何主机需定期备份,防止数据丢失。信息以实际为准,评测仅供参考不代表权威!
🍄:Netflix 奈飞 YouTube 合租

WordPress 博客网站数据库和文件备份插件 BackWPup 兼容 PHP8 版本

老头使用 BackWPup 这款 WordPress 博客网站数据库和文件备份插件好几年了,测试过使用备份的 sql 数据库文件和 XML 文件恢复,没有问题。 以前使用虚拟主机的时候使用 BackWPup 备份,一份直接上传 DropBox,一份 Email 发送到邮箱。后来换了 VPS,就只备份到 VPS 本地,然后使用脚本连同其它备份…

老头博客开始支持 TLS 1.3

TLS 1.3 目前只是 draft 版本,而支持 TLS 1.3 的 OpenSSL 1.1.1 的 draft-18 分支也只是开发者版本,所以,暂时最好不要用在生产环境。 其实前几天就折腾过 lnmp 1.4 升级 nginx 1.13.7,想顺手加上 TLS 1.3 支持,无奈折腾一圈以失败告终。 lnmp 1.4 更新至 nginx 1.12.2 lnm…

ThinkPad E450C 换电池

ThinkPad E450C 是内置电池,换起来比较费劲,基本上要把整机拆散。 百度经验有详细的拆机教程——联想(Thinkpad)E450 E450C 拆机教程,螺丝卸掉,一步一步,慢慢拆,不要用蛮力,基本上不会出啥问题。 按理是要把主板拆下来才可以拿出电池更换,不过我是偷懒换。把红色地方螺丝拆掉,主板轻轻…
浏览: 51 标签:  ,  , 

Adobe Flash Player 修改版 及可用 Flash Player 模拟扩展 Win10 可用

Adobe 在2020年12月31日后将不再支持 Adobe Flash Player,从2021年1月12日开始,阻止 Flash 内容在 Flash Player 中运行。截图 虽然不喜欢 Adobe Flash Player,但是有些网站目前仍然离不开 Adobe Flash Player,过渡解决方法是:安装中国特供版 Adobe Flash Player 或者安装网友修改 Adobe Flash…

Comments:34

  1. 你竟然还依靠Google了!测试一下通知。

    2020.07.07 14:36 # 回复
    1楼
  2. 看不懂,只会拿现成的插件用。

    2020.07.07 20:03 # 回复
    2楼
  3. 这两大段代码都是放function.php里吗?

    2020.07.07 20:57 # 回复
    3楼
    • @xinsenz 对,放主题functions.php文件里面。
      有可能需要根据主题实际修改一下。

      2020.07.07 21:19 # 回复
    • @xinsenz 不好意思,只要用其中一段即可。一个是老杨在用,一个是 @ZE3kr 版本。

      2020.07.07 21:59 # 回复
  4. 我都不去折腾代码,直接插件。。。省事、省心

    2020.07.08 07:51 # 回复
    4楼
  5. 学习一种新方法。Google发件慢多半是你服务器到Google速度慢吧,gmail的话用api发件可能好点。

    2020.07.08 18:08 # 回复
    5楼
  6. 发送邮件我用的阿里云的邮件推送!

    2020.07.08 21:45 # 回复
    6楼
  7. 问问,这几天梯子是不是全部给干死了???我备用的都不行了

    2020.07.11 19:37 # 回复
    7楼
  8. Typecho观望中

    2020.08.04 18:03 # 回复
    8楼
  9. 博主回复一下我的评论,让我看看 邮件通知的样式漂亮不。哈哈哈。

    2020.09.14 17:37 # 回复
    9楼
  10. 正好在找这个东西,哈哈。。原来杨哥早出了个教程,昨天还和林兄讨论如何解决wordpress的邮件通知导致的评论提交速度变慢,刚好在喂马檗柴那看到你的评论,实在是太好了。

    2021.04.25 23:13 # 回复
    10楼
    • @老麦 原理:异步发送通知邮件即可提高回复评论提交速度,使用 wp_schedule_single_event 实现最简单,不过这货可能会不工作,不知道是哪里出问题。

      还有一个笨办法是使用主机/VPS发信,这样速度不会慢,缺点是大概率进垃圾邮件。

      2021.04.26 11:47 # 回复
      • @老头 那你博客现在用的是什么方案?我感觉在你这里提交评论速度还可以。

        2021.04.26 12:41 # 回复
        • @老麦 更新了,看最后的后记,vps 发信。

          2021.04.26 13:04 # 回复
          • @老头 好的,如果不拖慢评论提交又能收到评论邮件通知,就已经很完美了。今晚回家研究一下~

            2021.04.26 13:23 # 回复
  11. 我想问的是,直接把你提供的代码选择一个复制到functions.php这里就解决了吗?还是说要配合插件?

    2021.04.25 23:16 # 回复
    11楼
    • @老麦 代码不包含smtp,博客环境可以正常发送邮件前提下,复制到functions.php就可以(也可能需要适配主题)。不过最近发现wp_schedule_single_event又不干活了…,

      2021.04.26 07:20 # 回复

发表留言

Vultr 送$100,搬瓦工年付最低$49,优惠码 BWH3HYATVBJW,更多推荐VPS信息