告别消息孤岛:青龙面板自定义通知渠道全攻略
你是否还在为青龙面板(QingLong)的通知功能局限于几种固定渠道而烦恼?当默认的钉钉、企业微信通知无法满足团队协作需求时,手动检查任务状态不仅耗时还容易遗漏关键信息。本文将带你从零开始构建专属通知渠道,无需复杂编程知识,只需三步即可让青龙面板的任务结果实时推送至任何你需要的平台。
为什么需要自定义通知渠道?
青龙面板作为一款支持Python3、JavaScript、Shell、Typescript的定时任务管理平台(Timed task management platform),其通知系统是任务监控的核心组件。默认情况下,系统已集成Bark、钉钉、企业微信等主流渠道,但在实际使用中仍会遇到以下痛点:
- 团队内部使用飞书、Slack等协作工具,需要跨平台消息同步
- 特殊场景下需要推送至私有部署的消息系统(如Gotify、PushDeer)
- 运维需求需要将任务结果存入数据库或触发后续自动化流程
- 国内网络环境限制导致部分国际服务不稳定
通过自定义通知渠道,你可以完美解决这些问题,让任务监控更贴合实际工作流。
准备工作:了解青龙通知系统架构
在开始编码前,我们先通过架构图了解青龙通知系统的工作原理:
系统核心通知逻辑位于以下文件:
- JavaScript示例:sample/notify.js
- Python示例:sample/notify.py
这两个文件定义了通知系统的基础架构,包括:
- 请求封装(HTTP客户端)
- 配置加载(从环境变量读取参数)
- 通知分发(根据配置调用不同渠道实现)
- 错误处理与日志输出
第一步:创建通知函数模板
无论你选择JavaScript还是Python,青龙通知系统都遵循相同的设计模式。以下是两种语言的基础模板,选择你熟悉的一种进行开发即可。
JavaScript模板(推荐)
在sample/notify.js文件中,每个通知渠道都遵循统一的函数结构:
function customNotify(title, desp) {
return new Promise((resolve) => {
// 1. 从配置读取必要参数
const { CUSTOM_API_KEY, CUSTOM_URL } = push_config;
// 2. 参数校验
if (!CUSTOM_API_KEY || !CUSTOM_URL) {
console.log("自定义通知配置未完善,跳过推送");
resolve();
return;
}
// 3. 构建请求参数
const options = {
url: `${CUSTOM_URL}`,
json: {
title: title,
content: desp,
apiKey: CUSTOM_API_KEY,
timestamp: new Date().getTime()
},
headers: {
'Content-Type': 'application/json'
},
timeout: 15000
};
// 4. 发送请求并处理响应
$.post(options, (err, resp, data) => {
try {
if (err) {
console.log('自定义通知发送失败😞\n', err);
} else {
if (data.code === 200) {
console.log('自定义通知发送成功🎉');
} else {
console.log(`自定义通知返回异常: ${data.message}`);
}
}
} catch (e) {
$.logErr(e, resp);
} finally {
resolve();
}
});
});
}
Python模板
如果你更熟悉Python,可以在sample/notify.py中添加:
def custom_notify(title: str, content: str) -> None:
"""
自定义通知渠道实现
"""
# 1. 从配置读取参数
api_key = push_config.get("CUSTOM_API_KEY")
url = push_config.get("CUSTOM_URL")
# 2. 参数校验
if not api_key or not url:
print("自定义通知配置未完善,跳过推送")
return
print("自定义通知服务启动")
# 3. 构建请求参数
headers = {"Content-Type": "application/json", "X-API-Key": api_key}
data = {
"title": title,
"content": content,
"timestamp": int(time.time())
}
# 4. 发送请求并处理响应
try:
response = requests.post(
url=url,
json=data,
headers=headers,
timeout=15
)
response.raise_for_status() # 抛出HTTP错误
result = response.json()
if result.get("code") == 200:
print("自定义通知推送成功!")
else:
print(f"自定义通知返回异常: {result.get('message')}")
except requests.exceptions.RequestException as e:
print(f"自定义通知发送失败: {str(e)}")
第二步:实现具体通知逻辑
下面以两个实用场景为例,展示如何实现完整的自定义通知功能。
场景一:推送至飞书群机器人
飞书作为字节跳动推出的协作平台,在国内企业中使用广泛。以下是适配飞书群机器人的实现:
function feishuNotify(text, desp) {
return new Promise((resolve) => {
const { FSKEY } = push_config;
if (!FSKEY) {
resolve();
return;
}
console.log("飞书通知服务启动");
const url = `https://open.feishu.cn/open-apis/bot/v2/hook/${FSKEY}`;
const data = {
"msg_type": "interactive",
"card": {
"elements": [
{
"tag": "div",
"text": {
"content": `**${text}**\n${desp}`,
"tag": "lark_md"
}
}
],
"header": {
"title": {
"content": "青龙任务通知",
"tag": "plain_text"
}
}
}
};
$.post({
url: url,
json: data,
headers: {"Content-Type": "application/json"}
}, (err, resp, data) => {
if (err) {
console.log("飞书通知失败😞", err);
} else if (data.code === 0) {
console.log("飞书通知成功🎉");
} else {
console.log(`飞书通知异常: ${data.msg}`);
}
resolve();
});
});
}
场景二:存储至MongoDB数据库
对于需要持久化存储任务结果的场景,可以直接将通知数据写入数据库:
def mongodb_notify(title: str, content: str) -> None:
"""
将任务结果存入MongoDB
"""
from pymongo import MongoClient
# 从环境变量获取数据库配置
mongo_uri = push_config.get("MONGO_URI")
db_name = push_config.get("MONGO_DB", "qinglong_notify")
collection_name = push_config.get("MONGO_COLLECTION", "task_results")
if not mongo_uri:
print("MongoDB配置缺失,跳过存储")
return
try:
# 连接数据库
client = MongoClient(mongo_uri)
db = client[db_name]
collection = db[collection_name]
# 插入通知数据
document = {
"title": title,
"content": content,
"timestamp": datetime.datetime.now(),
"status": "success",
"task_id": re.search(r'task_(\w+)', title).group(1) if re.search(r'task_(\w+)', title) else None
}
result = collection.insert_one(document)
print(f"任务结果已存入MongoDB: {result.inserted_id}")
except Exception as e:
print(f"MongoDB存储失败: {str(e)}")
第三步:配置与启用自定义渠道
完成通知函数后,还需要以下步骤使其生效:
1. 添加配置参数
在配置对象中添加必要的参数定义(以JavaScript为例):
const push_config = {
// ... 原有配置 ...
// 自定义渠道配置
CUSTOM_API_KEY: '', // 自定义服务API密钥
CUSTOM_URL: '', // 自定义服务地址
MONGO_URI: '', // MongoDB连接字符串
MONGO_DB: 'qinglong', // 数据库名称
FSKEY: '' // 飞书机器人密钥
};
// 从环境变量加载配置
for (const key in push_config) {
const v = process.env[key];
if (v) push_config[key] = v;
}
2. 注册通知函数
在通知分发逻辑中添加新渠道的调用:
async function sendNotify(text, desp) {
// ... 原有通知调用 ...
// 添加自定义渠道
await feishuNotify(text, desp);
await mongodbNotify(text, desp);
// 等待所有通知完成
await Promise.all([
// ... 原有通知Promise ...
feishuNotify(text, desp),
mongodbNotify(text, desp)
]);
}
3. 设置环境变量
最后在青龙面板的环境变量设置中添加:
# 飞书配置
FSKEY=your_feishu_bot_key
# MongoDB配置
MONGO_URI=mongodb://user:password@localhost:27017/
MONGO_DB=task_db
MONGO_COLLECTION=results
# 自定义Webhook配置
CUSTOM_URL=https://your-service.com/api/notify
CUSTOM_API_KEY=your_secret_key
调试与测试技巧
为确保自定义通知渠道稳定工作,建议使用以下调试方法:
-
本地测试:直接运行通知脚本进行单元测试
# 测试JavaScript通知 node sample/notify.js "测试标题" "测试内容" # 测试Python通知 python3 sample/notify.py "测试标题" "测试内容" -
日志查看:通过青龙面板的日志页面或文件查看通知执行情况
-
错误处理:实现完善的异常捕获,参考sample/notify.js中的错误处理模式
-
性能考量:对于耗时操作(如数据库写入),建议使用异步执行避免阻塞主进程
高级技巧:构建可复用通知模块
对于频繁变更通知需求的场景,可以进一步封装为可插拔模块:
// 通知管理器类
class NotificationManager {
constructor() {
this.channels = {};
}
// 注册通知渠道
registerChannel(name, handler) {
this.channels[name] = handler;
}
// 批量发送通知
async sendAll(title, content, channels = []) {
const tasks = channels.map(channel =>
this.channels[channel]?.(title, content) || Promise.resolve()
);
return Promise.all(tasks);
}
}
// 使用示例
const manager = new NotificationManager();
manager.registerChannel('feishu', feishuNotify);
manager.registerChannel('mongodb', mongodbNotify);
// 在任务完成后调用
manager.sendAll('任务完成', '执行结果...', ['feishu', 'mongodb']);
总结与最佳实践
通过本文介绍的方法,你已经掌握了青龙面板自定义通知渠道的完整流程。以下是几点最佳实践建议:
- 安全性:敏感信息(如API密钥)务必通过环境变量传入,避免硬编码
- 可维护性:每个通知渠道单独实现,保持函数短小精悍
- 兼容性:遵循原有代码风格,使用Promise处理异步操作
- 可扩展性:设计时考虑未来可能的多渠道扩展需求
- 监控:为自定义通知添加日志输出,便于问题排查
青龙面板的通知系统设计具有良好的扩展性,通过本文介绍的方法,你可以将任务结果推送至任何平台或服务。无论是团队协作工具、数据库还是自定义API,都能完美集成,让定时任务管理更加智能化、个性化。
现在就动手改造你的通知系统吧!如果有任何问题,欢迎查阅官方文档或提交issue参与社区讨论。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



