部署n8n
n8n是开源自动化工作流,可以拿来做一些神奇的事情(自己发掘)。
开始部署(Docker)
其实官方仓库的README已经给了,就2条指令(
拉不下来镜像的自己找加速源或者梯子(
# 创建一个卷给n8n用,不然会有权限问题
docker volume create n8n_data
# 创建n8n的容器
docker run -it --rm --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n
# 其实完全可以写成如下的命令
# -it基础之上加了个d,表示后台运行
# 添加了重启策略
# 使用环境变量指定了公网访问的地址(不然用的时候会变成http://localhost:5678,每次都得改)
docker run -itd --restart always --name n8n -e WEBHOOK_URL=https://example.com -p 5678:5678 -v n8n_data:/home/node/.n8n n8nio/n8n
完成以上步骤之后就可以在浏览器中打开n8n了,下面我再给一个Nginx反代的配置
# HTTP -> HTTPS
server {
listen 80;
server_name n8n.example.org;
return 301 https://$server_name$request_uri;
}
# HTTPS
server {
listen 443 ssl;
server_name n8n.example.org;
# SSL证书,根据实际情况写
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Rea $remote_addr;
proxy_set_header X-Forwarded-Host $http_host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Nginx-Proxy true;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
# Websocket需要,不然会有问题
proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade;
# 容器暴露的地址
proxy_pass http://127.0.0.1:5678;
# 上传的最大文件尺寸
client_max_body_size 200m;
}
}
部署UptimeFlare
这个是托管在Cloudflare(确实赛博菩萨,这才是真神) Worker的状态监控服务
看这里吧,还有图(实际上是懒得写了)
配置n8n工作流
这里以OneBot V11协议为例(协议端自己探索,比如napcat)
- 使用WebHook作为起点,其配置如下:
1.1 为了传递更多数据,HTTP请求方式写:POST
1.2 PATH随意,默认是实例的编号(不要和别的冲突,其实UUID也行)
1.3 Authentication 认证方式看情况写,但是不能不写,为了安全
1.4 响应根据情况选,我选择的是Using 'Response to Webhook' Node - 第二个节点使用Respond to Webhook(什么都不用配置)
- 第三个节点使用Code,这里需要写一点代码,因为要处理消息
// 取出请求标头 const headers = $input.first().json.headers; // 取出请求体 const body = $input.first().json.body; // 计算时间(uptime flare回传的是秒级别的时间戳,所以需要乘1000) const timeIncidentStart = new Date(body.timeIncidentStart * 1000); // 这里存最终的消息和参数 const res = []; // 要发送的消息 const msg = `🌐服务: ${body.monitorName} 状态: ${body.isUp ? '✅运行' : '❌故障'} 🕒时间: ${timeIncidentStart.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }).replace(/\//g, '-')} 💬原因: ${body.reason}`; // 从请求标头获取发送目标(参照下面的结构定义) headers.target.split(',').forEach((i) => { // isPrivate表示是否私聊 // target表示发送的目标(私聊就是QQ号,群聊就是群号) res.push({ isPrivate: i.startsWith('private_'), target: i.replace(/[a-z_]/g, ''), msg: msg }) }) // 存入主体 $input.first().json.body = res; return $input.first().json.body;
- 添加if节点(用于区分群聊和私聊,因为5的节点一个节点只能发送同一种类型的消息)
4.1 Conditions 中使用表达式形式,并直接在fx中写{{ $json.isPrivate }}
然后后面is true
- 安装n8n-nodes-onebot节点
- 配置OneBot节点,发送群消息和私聊消息写法一样:User Name or ID或Group Name or ID写为
{{ $json.target }}
,然后在Message栏中写{{ $json.msg }}
结构定义
- 必填请求标头
标头 | 值 |
---|---|
target | private_11223344,public_66778899 |
authorization | 认证令牌 |
- 请求体
{ "monitorName": "US - United States Server (AS979) - 154040", "isUp": true, "timeIncidentStart": 1741860850, "timeNow": 1741861248, "reason": "OK" }
配置UptimeFlare状态变更回调
在uptime.config.ts的callbacks里面的onStatusChange中写如下代码
onStatusChange: async (
env: any,
monitor: any,
isUp: boolean,
timeIncidentStart: number,
timeNow: number,
reason: string
) => {
// This callback will be called when there's a status change for any monitor
// Write any Typescript code here
const payload = {
monitorName: monitor.name,
isUp: isUp,
timeIncidentStart: timeIncidentStart,
timeNow: timeNow,
reason: reason,
};
try {
const response = await fetch('这里是Webhook的端点', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': '这里写令牌',
'Target': '这里写通知目标'
},
body: JSON.stringify(payload),
});
console.log(response);
} catch (error) {
console.error(error);
}
// This will not follow the grace period settings and will be called immediately when the status changes
// You need to handle the grace period manually if you want to implement it
},
Comments | NOTHING