# 利用 serv00 为 waline 加入异步邮件推送

事情的起因是因为有人在我网站评论了但我没看到,一直过了很久才发现回复,于是就想为我的 waline 加入一个邮件推送,及时提醒评论区的动态,以及提醒评论者评论的回复。

# waline 自带推送的缺点

waline 自带的邮件推送会使评论这个过程变得很慢,甚至直接失败。后面在大佬文章里知道 Waline 是在评论时直接进行发送邮件的,同步进行发信便会导致评论耗时较长,很影响用户体验,有时评论需要耗时几秒甚至超时。
幸好这个大佬也做出了解决方案,使用异步发信的方式,利用 Waline 可以设置一个 Webhook 地址,开发了这个项目

# 利用 serv00 部署项目

秉承着能白嫖绝不付费的理念,我选择了利用 serv00 来实现这个项目。总体分为三步 ①设置域名邮箱(可选,如果你选择用大厂 smtp 服务此过程可以省略)②项目本体的运行和保活 ③设置 waline 的 webhook 地址并重新部署

# 设置域名邮箱(可选)

这里其实任意一个 smtp 服务都可以,例如 163 邮箱。如果想要使用域名邮箱也可以选择其它的提供商,也可以选择使用 serv00 提供的免费的域名邮箱,这里给一个大佬的配置教程
记录下你的 SMTP 服务器地址,账号和密码备用

# 项目本体的运行和保活

# 放行端口

根据 serv00 邮件中给的地址进入面板,放行两个 tcp 端口,记录下两个端口

假设一个为 111 一个为 222

# Add a New Website

在侧边栏中选择 WWW websites 然后选择 Add New Website

KeyValue
Domain你晚点要用的webhook的域名 (也可以把原有的 USERNAME.serv00.net 删掉后重新添加,)
Website Typeproxy
Proxy Targetlocalhost
Proxy URL留空
Proxy port你准备用来部署 waline_mailer 的端口(假定你使用了刚刚开放的 111 端口)
Use HTPPSFalse
DNS supportTrue

添加完新站点后,继续点击上方的 Manage SSL certificates ,接着在出口 IP 的右侧点击 Manage ,再点击 Add certificate :

TypeDomain
Generate Let’s Encrypted certificate与刚刚添加的站点域名保持一致(如果是原有的 USERNAME.serv00.net ,可以省略此步)

但是注意,由于 serv00 可能已经处于被墙的状态,这里建议使用托管在 cf 上的域名,后续我们可以开启 cf 小黄云拯救被墙

建议此处即开启 cf 小黄云

# SSH 操作

根据邮件给的信息,ssh 登入执行

devil binexec on && killall -u $(whoami)

接着断开 SSH 并重新连接,输入以下命令:

#更新go环境
# 创建安装目录
mkdir -p ~/local/soft && cd ~/local/soft
# 下载编译好的 go1.22 的程序包
wget https://dl.google.com/go/go1.22.0.freebsd-amd64.tar.gz
# 解压
tar -xzvf go1.22.0.freebsd-amd64.tar.gz
# 删除压缩文件
rm go1.22.0.freebsd-amd64.tar.gz
# 修改 .profile 文件
echo 'export PATH=~/local/soft/go/bin:$PATH' >> ~/.profile
# 使 .profile 的修改生效
source ~/.profile
# 检查 go 版本
go version

下面开始安装 waline_mailer,这里选择刚刚新建的网站为安装目录 **~/domains/ 刚刚填入的域名 /**
切换至安装目录后开始执行

git clone https://github.com/soxft/waline-async-mail && cd waline-async-mail
go get github.com/go-playground/locales
go build -o waline_mailer main.go
cp config.example.yaml config.yaml
chmod +x waline_mailer

下面修改 config.yaml 为你的配置文件,主要修改的有网站名称,主人邮箱,推送方式和 smtp 配置

修改完成后执行
(nohup redis-server --port 另一个未使用的端口,比如这里应该为222 >/dev/null 2>&1 &) && cd /home/USERNAME/domains/域名/waline-async-mail && nohup ./waline_mailer >/dev/null 2>&1 &
如果成功启动了,那么我们就可以关闭程序了,然后进行保活操作

# 保活

再次添加一个网站,前缀随意,我们只需要用它来保活

进入 ~/domains/这个新的域名/public_nodejs
删除该目录下的 public 文件夹,并在 public_nodejs 文件夹内放置文件 app.js
app.js 的内容如下:

var http = require('http');
var { exec } = require('child_process');
var server = http.createServer(function(req, res) {
    exec('ps aux', function(error, stdout, stderr) {
        if (error) {
            res.writeHead(500, { 'Content-Type': 'text/plain' });
            res.end(`Error executing command: ${error.message}\n`);
            return;
        }
        if (stderr) {
            res.writeHead(500, { 'Content-Type': 'text/plain' });
            res.end(`Command stderr: ${stderr}\n`);
            return;
        }
        // 获取当前时间并转换为 UTC+8
        var now = new Date();
        var utc8Time = new Date(now.getTime() + 8 * 60 * 60 * 1000);
        var timeString = utc8Time.toISOString().replace('T', ' ').replace('Z', '');
        // 在输出中加入当前访问时间
        var output = `Current time (UTC+8): ${timeString}\n\n${stdout}`;
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end(output);
    });
});
    exec("pgrep -laf waline_mailer", function (err, stdout, stderr) {
      if (stdout.includes("waline_mailer")) { 
        console.log("正在运行");
      } else { 
        exec( exec(
          "`(nohup redis-server --port 另一个未使用的端口,比如这里应该为222 >/dev/null 2>&1 &) && cd /home/USERNAME/domains/域名/waline-async-mail && nohup ./waline_mailer >/dev/null 2>&1 &`",
          function (err, stdout, stderr) { 
            if (err) { 
              console.log("保活-调起 命令执行执行错误:" + err);
            } else { 
              console.log("保活-调起 命令行执行成功!");
            }
          }
        );
      }
    });
server.listen(3000, function() {重试
    console.log('Server is listening on port 3000'); 重试
});

注意修改文件中所执行的启动命令,与之前测试启动的命令相同即可
访问新建的这个域名,刷新几次,看到./waline_mailer 后即为启动成功,我们只需要监控这个域名即可实现对该程序的保活
可以使用以下公共服务对网页进行监控:

1 cron-job.org

2 UptimeRobot

同时,你也可以选择自建 Uptime-Kuma 等服务进行监控。

最后加入一个定时对自己 ssh 连接的命令,防止因为超过三个月未连接而被官方封号

指令为 sshpass -p '密码' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -tt 用户名@地址 "exit"

# 启用 webhook 并重新部署

在 vercel 的 waline 项目中添加环境变量 webhook,值为你设置的 webhook 的 url
然后重新部署项目完成!

# 至此,部署已经完成

感谢 soxft saika 大佬的异步邮件推送方案和 serv00 保活方案,接下来体验一个不卡评论的邮件推送!