告别评论邮件通知:用Bark实现ios即时通知

2,751字 60阅 0评

亚马逊SES服务的高冷

从FarBox自部署后,就在申请亚马逊的SES服务。换了两个区,一直被拒绝移除沙盒,导致博文在评论后收不到邮件。
于是想办法绕过这个服务,在搜索一圈后,要不更换评论系统,要不修改博客系统文件。第三方评论系统以前尝试过,没有中意的;修改系统文件没有那个能力,也不想动原生系统中的文件。

寻找解决方法

因为这段时间OpenClaw特别火,鬼使神差的想到,如果在Vps上部署OpenClaw,让它监控博客评论,有新的评论就发送邮件或者是微信通知可行吗?打开Gemini开始咨询。

可以用ai来检测吗?如果有新评论就发邮件通知或者微信通知?

这是一个非常敏锐的设计师直觉!答案是肯定的,而且这正是目前最流行的“低代码”自动化方案。
 
既然亚马逊 SES 的大门关上了,我们可以利用 AI 和自动化工具(如 Make.com, ZapierPipedream)来充当“勤务兵”。
 
这里有几种不需要折腾 SES,利用 AI 和自动化工具实现监控的方案:
 

方案一:利用 RSS 监控 + AI 转发(最省心)

 
Farbox 2.0 通常会提供评论的 RSS Feed(或者你可以通过 API 获取最近评论)。
 
1. 自动化工具:使用 Make.com (原 Integromat)。
2. 流程
* 监控:设置一个每 15 分钟检查一次的 RSS 触发器。
* AI 过滤(可选):把评论内容传给 ChatGPT API,让它判断是否是垃圾内容,或者总结评论大意。
* 通知:通过 SMTP 节点(直接填你的 QQ/网易邮箱)发邮件,或者通过 Bark/Pushover 发送手机强力推送。
 

 

方案二:利用“微信通知”机器人(最快)

 
如果你希望有人评论时,微信立刻“叮”地响一声,可以用 Server酱PushDeer
 
1. 在你的评论提交逻辑(如果是自定义评论框)或者通过监控脚本触发。
2. AI 介入:你可以让 AI 识别评论者的语气。比如,如果是你的偶像留言,AI 可以发送“大咖来访!”的特殊提醒;如果是杠精,AI 直接过滤掉不通知你。
 


 

🚀 针对你现状的最优解:Waline + Vercel + AI

 
既然你是完美主义者,我推荐你用 Waline 替换 Farbox 原生评论。它能完美集成 AI 检测:
 
1. AI 自动反垃圾:Waline 内置支持 Akismet(反垃圾),也可以接入 AI API,自动识别并拦截那种乱发广告的评论。
2. 多渠道通知:它原生支持:
* 邮件通知(你只需填入 QQ 邮箱的授权码即可,不需要 SES)。
* 微信通知(通过 Server酱)。
* Telegram/钉钉/飞书
 

  1. 部署简单:部署在 Vercel(免费且无需备案),数据库用 LeanCloud 或 MongoDB。   ---   ### 🎨 如果你想用 AI 帮你写这个“监控脚本”   如果你想保留 Farbox 默认评论,但想写个脚本来监控:   我们可以用 Python 写一个极简的 AI 脚本,运行在 GitHub Actions 上(完全免费):  
  2. 第一步:脚本每小时读取一次你的博客评论页面。
  3. 第二步:AI 对比上一次的数据,发现有新内容。
  4. 第三步:AI 格式化内容,通过 邮件微信 API 发给你。   你想尝试哪种路径?  
  5. 路径 A:换掉 Farbox 默认评论,用更漂亮的 Waline(自带邮件+微信通知,配置最简单)。
  6. 路径 B:保留现状,我帮你写一个能运行在云端的 AI 监控脚本。   对于设计师来说,路径 A 的视觉控制力最强;路径 B 则像是在“精修”现有的空间。你倾向于哪个?

在Gemini给出的三种方案,喜欢第二种,但是经过微信通知需要认证微信公众号,这是个麻烦的事,然后询问了Gemini解决办法,它给出了两种方案。
方案一:利用「Server酱」或「PushDeer」(最推荐,零开发)
方案二:利用「Bark」(如果你用 iPhone,这是最高级的体验)
于是就加了条件:FarBox原生评论系统+Bark这种方式。

具体操作步骤

第一步:在 iPhone 上准备 Bark
1.在 App Store 下载 Bark。

2.打开 App,你会得到一个专属链接,类似:https://api.day.app/你的Key/。

第二步:修改 Jade 模板
在你放置评论框的地方,加入一段简单的 JavaScript。假设你的提交按钮 ID 或 Class 是固定的:

// 这是一个极简的拦截器
document.addEventListener('DOMContentLoaded', function() {
    // 找到 Farbox 的评论表单
    var commentForm = document.getElementById('comment-form'); 
    
    if (commentForm) {
        commentForm.addEventListener('submit', function() {
            // 当用户点击提交时,立刻向你的 VPS 或直接向 Bark 发送请求
            // 注意:为了不影响评论提交,我们用 fetch 的 keepalive 模式
            fetch('https://api.day.app/你的Key/有人在博客评论啦!?group=Blog&isArchive=1&sound=calypso', {
                mode: 'no-cors',
                keepalive: true
            });
        });
    }
});

这个方案的优缺点
优点:

快:真正的“零延迟”,点击即弹窗。

原生感:不需要换掉 Farbox 的评论系统,保持纯正。

完全免费:不需要 SES,不需要备案。

缺点:

无法拦截垃圾评论:因为它是监听“点击”动作,如果有人乱填东西点提交,你也会收到弹窗(哪怕 Farbox 后台最后判定为垃圾评论)。

无法显示具体内容:因为点击瞬间内容还没存入后台,这个弹窗只能告诉你“有人点提交了”,不能显示具体的评论文字(除非再写复杂的 JS 去抓取输入框的值)。

一些小坑

在经过几轮代码修改后终于可以收到通知了,但是也发现了新的问题。
只要点击提交评论就会触发通知,不论有没有填写验证码或者其他信息。
加入了需要填写验证码并点击提交评论才进行通知的条件,又发现验证码输入错误,点击提交评论同样也会通知。
怎样实现完成评论了才进行通知呢?于是想到了检测评论列表,评论列表各层级出现新的评论才进行通知。

完整脚本代码

        // 评论手机通知
        script.
            document.addEventListener('DOMContentLoaded', function() {
                (function() {
                    // --- 1. 配置信息 ---
                    const barkKey = "R2M9************yWvdQU"; // Bark App 的身份密钥,决定通知发给谁
                    const blogOwnerName = "潘Sir"; // 用于排除博主自己回复时的通知
                    
                    // --- 2. 确定监控目标 ---
                    // 尝试定位一级评论列表 (ul.comments),如果找不到就扩大范围找整个评论区 (#comments)
                    const targetNode = document.querySelector('ul.comments') || document.querySelector('#comments');
                    
                    // 如果页面没有评论功能或找不到指定容器,则直接退出,不运行后续代码
                    if (!targetNode) {
                        console.log("未找到评论列表容器,监听跳过");
                        return;
                    }
            
                    // --- 3. 定义“观察者”逻辑 ---
                    // MutationObserver 会在指定的 DOM 节点发生变化时触发回调函数
                    const observer = new MutationObserver(function(mutationsList) {
                        // 遍历所有发生的变动记录
                        mutationsList.forEach(function(mutation) {
                            // 只有当“子节点列表”(childList) 增加新内容时才处理
                            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                                // 遍历所有新增加的节点(可能有多个)
                                mutation.addedNodes.forEach(function(node) {
                                    // 排除掉纯文本(如换行符)或注释,只处理 HTML 元素节点
                                    if (node.nodeType !== 1) return;
            
                                    // 在新增节点中寻找评论者名字和评论内容
                                    // 这里的逻辑兼顾了节点本身或其子元素,确保二级评论也能被捕获
                                    const authorElement = node.querySelector('.author-name b') || (node.classList && node.classList.contains('author-name') ? node : null);
                                    const contentElement = node.querySelector('.comment_content') || (node.classList && node.classList.contains('comment_content') ? node : null);
                                    
                                    // 如果既没抓到作者也没抓到内容,说明这个变动不是评论,直接跳过
                                    if (!authorElement && !contentElement) return;
            
                                    // 获取具体的文字内容,如果获取失败则提供兜底文字
                                    const author = authorElement ? authorElement.innerText : "新访客";
                                    const content = contentElement ? contentElement.innerText : "发表了新评论";
            
                                    // --- 4. 过滤逻辑 ---
                                    // 如果评论者名字包含博主昵称,说明是博主在回复,不发送通知
                                    if (author.indexOf(blogOwnerName) !== -1) return;
            
                                    // --- 5. 构造 Bark 推送请求参数 ---
                                    const title = encodeURIComponent("💬 收到新回复: " + author); // 编码通知标题
                                    const body = encodeURIComponent(content.substring(0, 50)); // 编码评论正文(截取前50字)
                                    const jumpUrl = encodeURIComponent(window.location.href); // 编码当前页面 URL,实现点击通知跳转
                                    const iconUrl = encodeURIComponent("https://blog.nastree.cn/_direct/site_avatar.png"); // 通知显示的图标
            
                                    // 拼接 Bark API 的完整请求地址,设置分组(group)、音效(sound)和自动归档(isArchive)
                                    const barkUrl = `https://api.day.app/${barkKey}/${title}/${body}?group=Blog&sound=calypso&isArchive=1&icon=${iconUrl}&url=${jumpUrl}`;
            
                                    // --- 6. 发送通知 ---
                                    // 创建一个虚拟的 Image 对象并设置其 src,利用浏览器加载图片的特性完成 GET 请求
                                    new Image().src = barkUrl;
                                    console.log("【Bark】已捕获层级评论并尝试发送通知");
                                });
                            }
                        });
                    });
            
                    // --- 4. 启动“哨兵” ---
                    // childList: true 监听子节点增删;subtree: true 开启深度监听(关键:解决二级评论问题)
                    observer.observe(targetNode, { childList: true, subtree: true });
                    console.log("【深度监控已启动】支持二级与多级评论监听...");
                })();
            });

总结

自部署服务端项目地址:Bark

  • 全层级提醒:支持文章下的一级评论,以及所有层级的“楼中楼”回复通知。
  • 点击即跳转:点击手机横幅通知,直接打开浏览器并精准跳转到该篇博文。
  • 品牌化Logo:通知带有博客专属头像,一眼识别消息来源,视觉上更专业。
  • 博主自动免扰:识别博主昵称,当你回复读者时,系统自动静默,不会触发自我提醒。
  • 信息自动截取:自动抓取评论前 50 字显示,确保通知内容干练不臃肿。
  • 点对点极速推送:绕过 Amazon SES 等邮件中转服务,实现从浏览器到手机的毫秒级推送。
  • 结果导向通知:仅在评论确认上墙(发表成功)后发出信号,确保每一声风铃都有意义。

All Posts

Comments
Write a Comment