前言 在前不久,LeanCloud 发布公告 ,宣布其停止新用户注册和新应用创建,且将于 2027 年 1 月 12 日停止服务。
此时我刚捣鼓好 Valine 的邮件通知系统没有多久,但可惜的是我不得不面对现实。由于 Valine 官方基本沉寂,我大概率等不来一个好的替代方案(Valine 仅支持 LeanCloud 作为数据库)。在这段时间忙完自己的论文后,终于有了时间来处理博客事务,研究了一天成功将博客的评论系统进行了迁移,故有此文。
评论系统迁移 一些可能需要提前注意的事项 迁移到 Waline 可能需要你有一个自己的域名 (因为要绑定一个子域名作为评论管理系统页面),如果你没有自己的域名,可以考虑购买一个或使用其他评论系统作为替代(即本文内容对你可能无用)。此外,本博客基于 hexo+butterfly 搭建,一些后续的调整可能在其他主题中不适用 。
Waline 部署 这一部分内容主要来自:Waline 官方教程 —— 快速上手 ,并针对部分内容进行细节补充。
部署服务端及创建数据库 这两个部分基本与上述官方教程无异,虽然当前 Vercel 页面布局可能存在些许不同,但总体流程没有变化,所以请根据官方教程进行操作:
绑定域名 在完成以上两步后,点击项目页面左侧的 Domains,在弹出页面里点击 Add Existing 将弹出以下窗口:
此时,请根据你的域名,填入以下地址模板:[你个人想要的前缀].[你的域名],以我的博客 biojuse.com 为例,我想要前缀代表评论,因此我最终的选择为:
comment.biojuse.com(comment 为前缀,biojuse.com 为域名)
这里使用的域名即后续的 serverURL 。
由于还没创建有关的子域名,此时其会显示错误(Invalid Configuration),点击 Learn More 我们可以看到以下信息:
复制保存此处的 Value 后 ,请先根据自己的域名服务商创造子域名。以腾讯云 为例:
打开腾讯云域名控制台:链接
选择自己的域名,点击解析 。
在 DNS 记录中,如果你在 GitHub 上托管博客,那么你应该已有几条与 GitHub 有关的记录,例如:
新建记录,主机填写之前添加的 domain 前缀,记录类型选择 A,记录值填写之前复制的 Value :
填写完毕后,点击确认添加该记录,过段时间刷新 Vercel project 中 Domains(点击 Refresh),若其通过则上述工作完成:
类似地,如果你的域名 DNS 是在 CloudFlare 中管理的,可以在左侧 DNS-记录 里进行类似操作:
至此,Waline 服务端/数据库/管理端均已完成。访问 <serverURL>/ui/register 进行注册,首个注册的人会被设定成管理员 。管理员登陆后,可以看到管理界面,并对评论进行相关操作。
Hexo+Butterfly 切换至 Waline 此处我使用的 Hexo+Butterfly 版本为 V4.4.0,该版本中要正常使用 Waline 评论系统,需要经过以下几点操作:
在 _config.butterfly.yml 中修改 comments 并添加 waline 配置:
1 2 3 4 5 6 7 8 9 10 11 comments: use: Waline text: true lazyload: true count: true waline: serverURL: <填写你的 serverURL,结尾无需斜杠> bg: pageview: false option:
可选 :结合 waline.pug 以及官网文档 ,如果想修改评论框中的文字(默认为 '欢迎评论'),可以在 option 中添加 locale,再在 locale 中添加 placeholder,在 placeholder 中指定你想替换的字符。更多 option 可见文档说明。
由于最新的 Waline (v3) 在 butterfly v4.4.0 中存在问题,这里需手动修改配置文件使其替换为 Waline v2 。具体而言,搜索并打开 butterfly theme 中的 plugins.yml 文件,将其中的 waline_js 及 waline_css 替换为以下内容:
1 2 3 4 5 6 7 8 9 10 waline_js: name: '@waline/client@2' file: dist/waline.min.js other_name: waline version: 2.6 .3 waline_css: name: '@waline/client@2' file: dist/waline.css other_name: waline version: 2.6 .3
进行以上修改后,你应该能发现博客的评论系统正确地变为了 Waline。
评论数据迁移 先前的评论并不在 Waline 中保存,为了保持评论数据一致,需要从其他系统迁移过来。
本文展示的为 Valine+LeanCloud 转移至 Waline 的操作方式,如果你的评论数据原先存储在其他平台,也可以参考本文的方式进行对应调整。
从 LeanCloud 下载评论数据 打开 LeanCloud 控制台,选中自己博客的评论管理项目,点击左侧的 数据存储-导入导出,选择 数据导出,勾选 限定 Class,勾选 Comment 并点击导出。
后续你会在邮箱里收到相关的文件,解压后会得到一个 .jsonl 文件,里面存储了博客中所有的评论数据 ,假设其名为 a.jsonl,留作后用。
从 Waline 管理界面中导出数据 打开 Waline 管理界面,点击左上角 管理-导入导出,点击导出按钮获得文件 waline.json,这里导出数据的目的仅为获取管理员信息 ,并与 LeanCloud 数据合并。
运行 Python 获得整合后的 Waline 评论数据 新建 python 脚本文件,输入以下内容(根据注释部分将一些文件路径换为自己对应的文件路径 )并运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 import jsonobjs = [] with open ("xxx.jsonl" , "r" , encoding="utf-8" ) as f: f.readline() for line in f: obj = json.loads(line) objs.append(obj) target_attributes = [ "user_id" , "comment" , "ip" , "link" , "mail" , "nick" , "pid" , "rid" , "sticky" , "status" , "like" , "ua" , "url" , "objectId" , "insertedAt" , "createdAt" , "updatedAt" , ] new_objs = [] for obj in objs: new_obj = {} for key in target_attributes: if key in obj: if key != "insertedAt" : new_obj[key] = obj[key] else : new_obj[key] = obj[key]["iso" ] else : new_obj[key] = None new_objs.append(new_obj) waline_json = json.load(open ('waline.json' , 'r' )) waline_json["data" ]["Comment" ] = new_objs with open ("waline.integrate.json" , "w" , encoding="utf-8" ) as f: json.dump(waline_json, f, ensure_ascii=False , indent=4 )
以上脚本运行完成后,打开 Waline 管理界面,点击左上角 管理-导入导出,点击导入按钮,将输出的文件(此处即 waline.integrate.json)导入,即可将 LeanCloud 中的评论数据全部迁移至 Waline 中。
开通邮件提示功能 Waline 开通邮件通知的方式与 Valine 极其相近,涉及到的环境变量详细可见:Waline-功能-评论通知
具体而言,先打开 Vercel 中的对应项目,点击左侧栏中 Settings,再点击 Environmental Variables。在环境变量列表中,点击 Add Environment Variable,输入以下环境变量(加粗的 key 为必填 ,其他为选填):
Key
Value
SMTP_SERVICE
SMTP 邮件发送服务提供商(QQ 邮箱则填写 'QQ',163 邮箱则填写 '163')
SMTP_USER
SMTP 邮件发送服务的用户名,一般为登录邮箱
SMTP_PASS
SMTP 邮件发送服务的密码,开通 SMTP 及设置授权码的教程可见此处 ,注意不要和登录密码混为一谈
SMTP_SECURE
填写 'true' 即可
SITE_NAME
网站名称(例如 Juse's blog)
SITE_URL
网站网址(例如 https://biojuse.com)
AUTHOR_EMAIL
博主邮箱,用来接收新评论通知(可选择填写与 SMTP_USER 相同的值)
SENDER_NAME
自定义发送邮件的发件人(例如 Juse)
SENDER_EMAIL
自定义发送邮件的发件地址(可选择填写与 SMTP_USER 相同的值)
MAIL_SUBJECT
自定义评论回复邮件标题
MAIL_TEMPLATE
自定义评论回复邮件内容
MAIL_SUBJECT_ADMIN
自定义新评论通知邮件标题
MAIL_TEMPLATE_ADMIN
自定义新评论通知邮件内容
后四个 Key 可以填写一些相关变量 作为补充(具体可见此处 ),例如:
MAIL_SUBJECT:{{site.name|safe}} 上的评论收到了回复,此处 {{site.name|safe}} 会变为 SITE_NAME 填写的值。
MAIL_SUBJECT_ADMIN:{{site.name|safe}} 上有新评论了,同上。
MAIL_TEMPLATE:以下给出一个博主本人基于 ChatGPT 润色生成的简易模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <div style ="max-width:600px;margin:40px auto;padding:0 20px;font-family:Arial,Helvetica,sans-serif;color:#333;line-height:1.6;font-size:14px;background:#ffffff;border:1px solid #e5e5e5;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,0.05);" > <div style ="padding:20px 25px;border-bottom:1px solid #f0f0f0;background:#f9fbfc;border-radius:8px 8px 0 0;" > <h2 style ="font-size:16px;margin:0;color:#0c99c8;font-weight:600;" > 您在 <a href ="{{site.url}}" target ="_blank" style ="color:#0c99c8;text-decoration:none;" > {{site.name|safe}}</a > 上的评论有新回复</h2 > </div > <div style ="padding:25px 25px 10px 25px;" > <p style ="margin:0 0 10px 0;font-size:14px;" > {{parent.nick}},您曾发表评论:</p > <div style ="background:#f5f7f8;border-left:3px solid #0c99c8;padding:12px 15px;margin:12px 0;border-radius:4px;word-wrap:break-word;" > {{parent.comment|safe}}</div > <p style ="margin:15px 0 10px 0;font-size:14px;" > <strong > {{self.nick}}</strong > 回复说:</p > <div style ="background:#f5f7f8;border-left:3px solid #5cb85c;padding:12px 15px;margin:12px 0;border-radius:4px;word-wrap:break-word;" > {{self.comment|safe}}</div > <p style ="margin-top:20px;font-size:14px;" > 您可以点击 <a href ="{{site.postUrl}}" target ="_blank" style ="color:#0c99c8;text-decoration:none;" > 查看完整回复</a > 。欢迎再次访问 <a href ="{{site.url}}" target ="_blank" style ="color:#0c99c8;text-decoration:none;" > {{site.name|safe}}</a > 。</p > </div > <div style ="padding:15px 25px;font-size:12px;color:#888;background:#fafafa;border-top:1px solid #f0f0f0;border-radius:0 0 8px 8px;text-align:center;" > 本邮件为系统自动发送,请勿直接回复。</div > </div >
MAIL_TEMPLATE_ADMIN:同上,给出博主本人模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <div style ="max-width:600px;margin:40px auto;padding:0 20px;font-family:Arial,Helvetica,sans-serif;color:#333;line-height:1.6;font-size:14px;background:#ffffff;border:1px solid #e5e5e5;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,0.05);" > <div style ="padding:20px 25px;border-bottom:1px solid #f0f0f0;background:#f9fbfc;border-radius:8px 8px 0 0;" > <h2 style ="font-size:16px;margin:0;color:#0c99c8;font-weight:600;" > 您在 <a href ='{{site.url}}' target ='_blank' style ='color:#0c99c8;text-decoration:none;' > {{site.name|safe}}</a > 上的文章有了新的评论</h2 > </div > <div style ="padding:25px 25px 10px 25px;" > <p style ="margin:0 0 10px 0;font-size:14px;" > <strong > {{self.nick}}</strong > 评论说:</p > <div style ="background:#f5f7f8;border-left:3px solid #5cb85c;padding:12px 15px;margin:12px 0;border-radius:4px;word-wrap:break-word;" > {{self.comment|safe}}</div > <p style ="margin-top:20px;font-size:14px;" > 您可以点击 <a href ='{{site.postUrl}}' target ='_blank' style ='color:#0c99c8;text-decoration:none;' > 查看评论的完整內容</a > 。</p > </div > <div style ="padding:15px 25px;font-size:12px;color:#888;background:#fafafa;border-top:1px solid #f0f0f0;border-radius:0 0 8px 8px;text-align:center;" > 本邮件为系统自动发送,请勿直接回复。</div > </div >
在所有环境变量填写成功后,对 Vercel 项目进行重新部署 ,邮件提示功能即可生效。
后记 至此,所有的评论数据/功能已从 Valine+LeanCloud 移植到 Waline+Neon,在此特作记录,以帮助其他可能有需要的朋友。