为 UptimeFlare 设置飞书通知
On this page
在这之前,我使用 Uptime Kuma 作为我的服务监控工具,并通过飞书推送状态信息。但一个搞笑的事实是:我只有一台服务器,服务要么在这台服务器上,要么在第三方平台上。如果在我唯一的服务器上再跑一个状态监控,显然多此一举。因此我切换到了基于 CloudFlare Workers 的监控程序 UptimeFlare。不过与 Uptime Kuma 不同,UptimeFlare 仅支持手动配置 Webhook,并且在 Wiki 中没有提供适用于飞书的 Webhook 配置方法。经过一番探索之后,我找到了适合我的配置写法,并在这里分享出来。
写在前面
本文适用于已经创建好飞书 Webhook 机器人的读者。
另外,UptimeFlare 原生支持通过 workerConfig.notification.webhook 配置项把状态通知推送到任意 Webhook,其中 $MSG 占位符会被替换为可读的状态文本。最简单的飞书配置是这样的:
notification: {
webhook: {
url: 'https://open.feishu.cn/open-apis/bot/v2/hook/xxx',
method: 'POST',
payloadType: 'x-www-form-urlencoded',
payload: {
msg_type: "text",
content: { text: "$MSG" }
},
},
timeZone: 'Asia/Shanghai',
gracePeriod: 5,
}这个方案虽然可行,但通过这段配置所发出的消息类型是「纯文本消息」。在飞书开发文档中,给出了 5 种支持发送的消息类型,可以丰富机器人消息的内容。为了使发出的信息更加直观,使用户能够一眼看出是宕机还是恢复,我选择了「飞书卡片」消息样式进行更丰富的自定义。
卡片消息
飞书自定义机器人发送卡片消息时,请求体格式为:
{
"msg_type": "interactive",
"card": {
"header": {
"title": { "tag": "plain_text", "content": "标题" },
"template": "green"
},
"elements": [
{
"tag": "div",
"text": { "tag": "lark_md", "content": "**Markdown** 内容" }
},
{ "tag": "hr" },
{
"tag": "note",
"elements": [{ "tag": "plain_text", "content": "底部说明" }]
}
]
}
}在配置文件中,我们可以使用 workerConfig.callbacks.onStatusChange 来自定义更多细节。这里直接给出 uptime.config.ts 相关配置写法:
const FEISHU_WEBHOOK_URL = 'https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx' // 你的自定义机器人 Webhook 地址
const workerConfig: WorkerConfig = {
monitors: [ /* 你的监控列表 */ ],
callbacks: {
onStatusChange: async (
env, monitor, isUp,
timeIncidentStart, timeNow, reason
) => {
const statusText = isUp ? '服务已恢复' : '服务宕机'
const template = isUp ? 'green' : 'red'
const reasonText = reason || '未获取到详细信息'
const formattedTime = new Date(timeNow * 1000).toLocaleString('zh-CN', {
timeZone: 'Asia/Shanghai',
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
})
const cardPayload = {
msg_type: 'interactive',
card: {
header: {
title: { tag: 'plain_text', content: `${statusText}:${monitor.name}` },
template,
},
elements: [
{
tag: 'div',
text: {
tag: 'lark_md',
content: `**监控对象**:${monitor.target}\n**详细信息**:${reasonText}`,
},
},
{ tag: 'hr' },
{
tag: 'note',
elements: [{ tag: 'plain_text', content: `${formattedTime}` }],
},
],
},
}
try {
const resp = await fetch(FEISHU_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(cardPayload),
})
if (!resp.ok) {
console.error(`通知发送失败: HTTP ${resp.status}`, await resp.text())
}
} catch (err) {
console.error('请求 Webhook 异常:', err)
}
},
onIncident: async () => {},
},
}需要注意的是,当你设置好 callbacks.onStatusChange 后,请删除 notification.webhook 配置,否则你将会收到重复通知。
配置完成后,你可以临时破坏一个监控项(如把 target 改成一个不存在的域名)并部署,等待一个检测周期,应收到由机器人发出的卡片信息,含有当前这个监控项的状态信息。