优化 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 4.2+ 使用 Twemoji 替换默认 Emoji 表情

WordPress 4.2+ 新增 Twitter Em❤️ji 表情,但是默认使用的 CDN —— https://s.w.org/images/core/emoji/11.2.0/72x72/ 在国内无法正常访问。解决办法有两个,一是把表情本地化,二是替换掉默认的链接。 🎉 😜 👯 🍻 🎈 🎤 🎮 🚀 🌉 ✨ 使用 Twitter 官方提供 MaxCDN 服务 Twitter 官方提供 MaxCDN 服务…
浏览: 46 标签:  ,  ,  ,  , 

WordPress 随机显示名人格言 + PHP 毒鸡汤

在 编程随想 博客看到个不错的功能——随机显示博主精选的名人格言,稍稍折腾,我也加上了这功能了(在首页随机显示我喜欢的句子)。 :razz: 网上(官网的是英文版的格言)有现成的插件。一个很简单的插件,其实可以集成到 functions.php 去。不过格言也存放在插件的php文件里面,集成到 functions.…
浏览: 61 标签:  ,  ,  , 

Gravatar 头像被墙及解决方案

Gravatar 头像真是一言难尽,时而正常时而抽风时而无法访问……就一个 Gravatar 头像,这有啥好强(现代通假字)的呢?(据说是被其它服务连累?) 解决办法 - 调用 ssl/cn 头像链接 历史解决办法:调用 ssl 头像链接——https还是没被墙的,而且速度还不错,直接调用这个最简单了。主题 functions.…

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信息