Hexo 使用 Valine-Admin 管理评论的小改进

意外之喜

最近发现,本博客的访问量有增多的趋势,也渐渐有访客在博文下留言。从热心网友的评论中,我感受到本博客还是帮助了一些人的,甚是欣慰。

不过,因为博客使用的评论功能比较有限,我又没有开启评论提醒,常常会错过网友的评论,没有办法及时回复。

Valine-Admin

本博客使用 Next 主题自带的 Valine 评论插件,该插件自带的邮件提醒功能使用的是 LeanCloud 的密码重置邮件提醒,只能传递昵称、邮箱两个属性,所以邮件提醒链接无法直达指定文章页,效果不是很令人满意了。

Valine-Admin 是一个对 Valine 评论系统的拓展应用,可增强 Valine 的邮件通知功能。基于 Leancloud 的云引擎与云函数。可以提供邮件 通知站长@ 通知 的功能,而且还支持自定义邮件通知模板。

Valine-Admin 的使用说明在它的官方 repo 中也已经说明得很清楚了,具体可以查看 这里。对于评论量不是很多的大多数人,一般会使用免费版的 LeanCloud 容器。然而,天下没有完全免费的午餐。免费版是有强制性休眠策略的,不能 24 小时运行:

  • 每天必须休眠 6 个小时
  • 30 分钟没有外部请求,则休眠
  • 休眠后如果有新的外部请求实例则马上启动(但激活时此次发送邮件会失败)

Valine-Admin 给的方案是「设置定时器,每天 7 - 23 点每 20 分钟访问一次」,一开始我是觉得挺好的,不过回头想了想,也不是十分的合理。如果访客恰好在这个时间段以外评论,那就又错过了。

解决方案

最后想了一个比较稳妥的解决方案,当用户准备输入内容时,即输入框获取到焦点时,前端 JS 访问一次 LeanCloud 容器。当用户输入完,确定回复时,容器基本也处于运行中的状态,也就能够正常地发送通知邮件。

实现方法也比较简单,修改 Next 主题,添加自定义 JS 脚本,同时 Valine-Admin 增加 Access-Control-Allow-Origin 响应头即可,感兴趣的可以往下看。

引入自定义 JS

修改 themes/next/layout/_scripts/commons.swig,在 js_commons 数组中添加一条记录 src/valine-warmup.js。新建自定义 JS 文件 themes/next/source/js/src/valine-warmup.js,内容如下。

1
2
3
4
5
6
7
8
9
10
11
$(document).ready(function() {

if ($('#veditor').length > 0) {
$('#veditor').focus(function() {
$.get('https://hunterx.leanapp.cn/', function(res) {
// console.log(res)
})
})
}

});

跨域解决

如果不设置容器可跨域访问,浏览器控制台会有相应的报错,但是不会影响 LeanCloud 容器从休眠状态切换到运行中状态。如果没有强迫症,也可以忽略跨域问题。

Fork 一份 Valine-Admin 的代码,修改 app.js,在适当的位置(第 34 行下方)添加以下代码。或者直接使用我的仓库 HunterXuan/Valine-Admin 进行部署。

1
2
3
4
5
6
7
8
9
// add headers
app.use(function(req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');

// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
next();
});

The End

改造之后,每次尝试输入评论的时候,会触发一次网络请求,确保 LeanCloud 将处于「运行中」的状态,提醒邮件能够正常发送。测试发现,首次唤醒需要的时间在 5s 左右。一条有「质量」的评论,时间应该不至于短于 5s 吧,所以在我的可接受范围内。

后面试用了下 原版 Valine-Admin,发现已经通过 LeanCloud 的定时器功能解决休眠和漏发的问题,在这里还是推荐下原版吧哈哈。