〇、起因

2024年10月15日,我发现我的博客评论系统挂了。具体表现为无法评论,也无法获取评论数据,Twikoo 管理员界面也进不去。

打开控制台看到了 Uncaught (in promise) 206 类似的错误,分析发现是 Twikoo 评论系统在与服务器通信时遇到了问题。

这次错误的出现,外加上之前采用的是 Hugging Face 部署方案,无法使用邮件通知功能,我决定采用 Netlify 部署方案重新配置 Twikoo 评论系统。


今天,我在图书馆坐了一整天,本来以为很快能解决,却因为自己对云函数等前端知识掌握不深刻,导致解决问题的过程有点长。中午的时候还没午睡,脑袋昏昏沉沉地忙活了一天。中间几度崩溃想放弃,但最后还是坚持着把问题解决了😋!

下面的记录只会挑重点记录,网络上有很多教程的东西这里就不会再重复叙述了!

一、指定 MongoDB 数据库

1.1 问题说明

这个问题发生在我迁移云函数部署方案时,原来的 Hugging Face 部署方案使用的 MongoDB 数据库名称为 twikoo,但是 Netlify 部署方案采用的 MongoDB 数据库名称为 test。这就导致了,原来在 twikoo 数据库中存储的数据无法在 test 数据库中使用。

图 1.1.1 两个不同的 MongoDB 数据库

遇到这个情况通常有两种解决方案:

  1. 将 twikoo 数据库的数据导出,复制一份到 test 数据库。
  2. 想办法让 Netlify 部署方案直接使用 twikoo 数据库

1.2 解决方法

第一个解决方案不符合我的做事风格,所以我经过琢磨和理解,最后在 twikoo 官方文档中理解了这句话:

6.(可选)默认的连接字符串没有指定数据库名称,Twikoo 会连接到默认的名为 test 的数据库。如果需要在同一个 MongoDB 里运行其他业务或供多个 Twikoo 实例使用,建立加入数据库名称并配置对应的 ACL。

也就是说我们可以在复制的“数据库连接字符串”中指定数据库名称,例如:mongodb+srv://<username>:<password>@xxxxx.xxxxxx.mongodb.net/twikoo?xxxxx

当然,你还可以通过 ACL(访问控制列表)设置不同的权限。

1.3 其他说明

我也不记得当初配置 Hugging Face 部署方案时是否是自己指定的数据库名称,还是说其默认数据库名称就是 twikoo(我觉得应该是我自己设置的,然后时间久了我忘记了)。正因为如此,我觉得这个内容必须要记录一下!

另外,我发现在 Github 某个相关仓库中一个 Issue 中有提到这个问题,还未被解决:tangly1024/NotionNext #2360

二、锁定 Netlify 云函数版本

2.1 问题说明

之所以要干这个事情是因为我发现我的 Twikoo 已经完成所有配置后,Turnstile 小组件却莫名其妙不工作了(这个问题困扰了我几乎一个下午,也可能是头脑不清醒导致的胡乱操作吧😥)。

我尝试过在 Cloudflare 重新配置 Turnstile 小组件重新部署 Netlify 云函数修改 Netlify 云函数环境变量以及一些乱七八糟的尝试(我也不知道为什么要那么做,可能确实没休息好)。最后,我在快放弃时(图书馆要闭关了),我尝试了一个看似无关的操作:修复前端 Twikoo 与云函数 Twikoo 版本不一致的问题(也可能是我的开发经验指引着我吧🙄~),然后成功解决了问题。

2.2 解决方法

观察 Netlify 部署后的云函数文件 package-lock.json 的内容,我发现其指定了 Twikoo 版本为 1.6.39。但是我本地任然使用的是 Twikoo 1.6.31,这也在 Twikoo 管理界面给出了提示(已经修复了,不截图了)。

图 2.2.1 package-lock.json 部分相关内容

所以,我们只需要在自己 fork 的 twikoo-netlify 仓库中修改 package.json 文件内容为:

1
2
3
4
5
6
7
{
"dependencies": {
"twikoo-netlify": "1.6.31",
"twikoo-func": "1.6.31",
"twikoo-vercel": "1.6.31"
}
}

进行版本锁定,然后重新部署 Netlify 云函数即可。不放心的话可以检查一下部署后的 package-lock.json 文件内容,搜索关键字:twikoo

2.3 补充说明

注意,网络上很多教程都未指出一个问题,就是配置 Twikoo 的 Turnstile 小组件一定是前后端双配置,也就是需要在“Twikoo 管理界面”和“云函数环境变量”中都进行配置。这里给出我自己的配置方法:

  • Cloudflare > Turnstile > 添加 Turnstile 小组件:
    • 记录站点秘钥秘钥这两个值。
  • Twikoo 管理界面 > 配置管理 > 反垃圾 :
    • 配置 TURNSTILE_SITE_KEYTURNSTILE_SECRET_KEY 项。
  • Netlify 云函数管理界面 > Site configuration > Environment variables :
    • 添加 TURNSTILE_KEYTURNSTILE_SECRET 这两个环境变量,然后重新部署一下云函数。

下面是对照表:

变量Turnstile 小组件的对应值
Twikoo 配置参数 TURNSTILE_SITE_KEY站点秘钥
Twikoo 配置参数 TURNSTILE_SECRET_KEY秘钥
云函数环境变量 TURNSTILE_KEY站点秘钥
云函数环境变量 TURNSTILE_SECRET秘钥

注意:除此之外,还有个要注意的地方就是在配置 Turnstile 小组件的“域”的时候,要包含所有需要使用该组件的域名(三级域名不同也要指明,关于这一点 Cloudflare 官方在配置页面也有提示),例如:seayj.cnwww.seayj.cn 都需要填写。

三、更改评论通知配置

3.1 IM 通知

相关配置的官方说明文档

之前使用的是“企业微信应用消息推送”,但是现在这个好像行不太通了,我试了很久也没有成功。好像要配置 IP 白名单之类的,我也没深入研究,也懒得弄了。

后来尝试了“WxPusher 微信推送平台”,使用感受还不错(速度快、操作简单),还是比较推荐的。

3.2 邮件通知

邮件通知这个东西不被 Twikoo 的 Hugging Face 部署方案所支持(端口被屏蔽),这次切换到 Netlify 部署方案后,我好好整理了一下邮件通知的相关内容。

3.2.1 SMTP 设置

这里强烈不推荐使用 Outlook 的邮箱进行配置,不知道为什么这东西很难配置成功(我在网上发现很多人也都是这情况),反正挺抽象的。虽然以前使用 Valine 评论的时候成功过一次,不过也是折腾了非常久。总之,不要使用 Outlook 邮箱来设置 Twikoo 的评论邮件通知。

3.2.1 邮件通知模板

还有个新发现的问题就是 Outlook 客户端不支持常见 CSS 属性的问题,查阅资料发现 Outlook 客户端好像遵守的是 Word 排版那一套东西,所以邮件通知模板需要做兼容处理。具体兼容方法暂时未探究,有兴趣自己去查阅一下吧!

下面我直接给出“张洪 Heo”大佬的邮件通知模板:

1
<div class="page flex-col"><div class="box_3 flex-col" style="  display: flex;  position: relative;  width: 100%;  height: 206px;  background: #ef859d2e;  top: 0;  left: 0;  justify-content: center;"><div class="section_1 flex-col" style="  background-image: url(&quot;这里更改为你的网站图标&quot;);  position: absolute;  width: 152px;  height: 152px;  display: flex;  top: 130px;  background-size: cover;"></div></div><div class="box_4 flex-col" style="  margin-top: 92px;  display: flex;  flex-direction: column;  align-items: center;"><div class="text-group_5 flex-col justify-between" style="  display: flex;  flex-direction: column;  align-items: center;  margin: 0 20px;"><span class="text_1" style="  font-size: 26px;  font-family: PingFang-SC-Bold, PingFang-SC;  font-weight: bold;  color: #000000;  line-height: 37px;  text-align: center;">嘿!你在&nbsp;${SITE_NAME}&nbsp;博客中收到一条新回复。</span><span class="text_2" style="  font-size: 16px;  font-family: PingFang-SC-Bold, PingFang-SC;  font-weight: bold;  color: #00000030;  line-height: 22px;  margin-top: 21px;  text-align: center;">你之前的评论&nbsp;&nbsp;${SITE_NAME} 博客中收到来自&nbsp;${NICK}&nbsp;的回复</span></div><div class="box_2 flex-row" style="  margin: 0 20px;  min-height: 128px;  background: #F7F7F7;  border-radius: 12px;  margin-top: 34px;  display: flex;  flex-direction: column;  align-items: flex-start;  padding: 32px 16px;  width: calc(100% - 40px);"><div class="text-wrapper_4 flex-col justify-between" style="  display: flex;  flex-direction: column;  margin-left: 30px;  margin-bottom: 16px;"><span class="text_3" style="  height: 22px;  font-size: 16px;  font-family: PingFang-SC-Bold, PingFang-SC;  font-weight: bold;  color: #C5343E;  line-height: 22px;">${PARENT_NICK}</span><span class="text_4" style="  margin-top: 6px;  margin-right: 22px;  font-size: 16px;  font-family: PingFangSC-Regular, PingFang SC;  font-weight: 400;  color: #000000;  line-height: 22px;">${PARENT_COMMENT}</span></div><hr style="    display: flex;    position: relative;    border: 1px dashed #ef859d2e;    box-sizing: content-box;    height: 0px;    overflow: visible;    width: 100%;"><div class="text-wrapper_4 flex-col justify-between" style="  display: flex;  flex-direction: column;  margin-left: 30px;"><hr><span class="text_3" style="  height: 22px;  font-size: 16px;  font-family: PingFang-SC-Bold, PingFang-SC;  font-weight: bold;  color: #C5343E;  line-height: 22px;">${NICK}</span><span class="text_4" style="  margin-top: 6px;  margin-right: 22px;  font-size: 16px;  font-family: PingFangSC-Regular, PingFang SC;  font-weight: 400;  color: #000000;  line-height: 22px;">${COMMENT}</span></div><a class="text-wrapper_2 flex-col" style="  min-width: 106px;  height: 38px;  background: #ef859d38;  border-radius: 32px;  display: flex;  align-items: center;  justify-content: center;  text-decoration: none;  margin: auto;  margin-top: 32px;" href="${POST_URL}"><span class="text_5" style="  color: #DB214B;">查看详情</span></a></div><div class="text-group_6 flex-col justify-between" style="  display: flex;  flex-direction: column;  align-items: center;  margin-top: 34px;"><span class="text_6" style="  height: 17px;  font-size: 12px;  font-family: PingFangSC-Regular, PingFang SC;  font-weight: 400;  color: #00000045;  line-height: 17px;">此邮件由评论服务自动发出,直接回复无效。</span><a class="text_7" style="  height: 17px;  font-size: 12px;  font-family: PingFangSC-Regular, PingFang SC;  font-weight: 400;  color: #DB214B;  line-height: 17px;  margin-top: 6px;  text-decoration: none;" href="${SITE_URL}">前往博客</a></div></div></div>

注意:需要自己手动将代码中的这里更改为你的网站图标内容更改为网站图标图片的 url 地址。

四、总结

永远不要小瞧网站维护这项工作,因为看似简单的事情,需要你掌握的知识还是比较多的。如果自己的知识面不够宽阔,掌握不是很牢固,理解不是很深刻,那么你就会花费相对更多的时间去弥补这些你所缺失的东西(对于我这种业余前端,属实有点遭罪😢)。

不过还是很庆幸自己坚持着,遇到些困难也是常有的事儿,毕竟谁的成长不经历坎坷和颠簸?