From 841740f19a3e304dd70466f9abff8f1f13ee89fa Mon Sep 17 00:00:00 2001 From: Alone88 Date: Sat, 12 Sep 2026 09:50:56 -0700 Subject: [PATCH] feat: add WPUSH notification provider (#3066) Add WPUSH as a notification channel for Qinglong panel settings and sample notify scripts (Python/JS), using POST https://api.wpush.cn/api/v1/send with success code === 0. Supports optional channel and topic_code. --- back/data/notify.ts | 10 +++++++- back/services/notify.ts | 28 +++++++++++++++++++++ sample/config.sample.sh | 10 ++++++++ sample/notify.js | 54 +++++++++++++++++++++++++++++++++++++++++ sample/notify.py | 37 ++++++++++++++++++++++++++++ src/locales/en-US.json | 5 +++- src/locales/zh-CN.json | 5 +++- src/utils/config.ts | 22 +++++++++++++++++ 8 files changed, 168 insertions(+), 3 deletions(-) diff --git a/back/data/notify.ts b/back/data/notify.ts index b1230f8b..e9e5c5fd 100644 --- a/back/data/notify.ts +++ b/back/data/notify.ts @@ -21,6 +21,7 @@ export enum NotificationMode { 'ntfy' = 'ntfy', 'wxPusherBot' = 'wxPusherBot', 'openiLink' = 'openiLink', + 'wpush' = 'wpush', } abstract class NotificationBaseInfo { @@ -172,6 +173,12 @@ export class OpeniLinkNotification extends NotificationBaseInfo { public openiLinkContextToken = ''; } +export class WpushNotification extends NotificationBaseInfo { + public wpushApiKey = ''; + public wpushChannel = ''; + public wpushTopicCode = ''; +} + export interface NotificationInfo extends GoCqHttpBotNotification, GotifyNotification, @@ -195,4 +202,5 @@ export interface NotificationInfo NtfyNotification, WxPusherBotNotification, WxPusherSptNotification, - OpeniLinkNotification {} + OpeniLinkNotification, + WpushNotification {} diff --git a/back/services/notify.ts b/back/services/notify.ts index 3e492774..e92269a5 100644 --- a/back/services/notify.ts +++ b/back/services/notify.ts @@ -37,6 +37,7 @@ export default class NotificationService { ['wxPusherBot', this.wxPusherBot], ['wxPusherSpt', this.wxPusherSpt], ['openiLink', this.openiLink], + ['wpush', this.wpush], ]); private title = ''; @@ -947,4 +948,31 @@ export default class NotificationService { throw new Error(error.response ? error.response.body : error); } } + private async wpush() { + const { wpushApiKey, wpushChannel, wpushTopicCode } = this.params; + const url = 'https://api.wpush.cn/api/v1/send'; + const json: Record = { + apikey: `${wpushApiKey}`, + title: `${this.title}`, + content: `${this.content}`, + channel: `${wpushChannel || 'wechat'}`, + }; + if (wpushTopicCode) { + json.topic_code = `${wpushTopicCode}`; + } + try { + const res = await httpClient.post(url, { + ...this.gotOption, + json, + }); + if (res.code === 0) { + return true; + } else { + throw new Error(JSON.stringify(res)); + } + } catch (error: any) { + throw new Error(error.response ? error.response.body : error); + } + } + } diff --git a/sample/config.sample.sh b/sample/config.sample.sh index a5e88e05..cecf7095 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -276,3 +276,13 @@ export OPENILINK_HUB_URL="" export OPENILINK_CONTEXT_TOKEN="" ## 其他需要的变量,脚本中需要的变量使用 export 变量名= 声明即可 + +## 23. WPUSH +## 官方文档: https://wpush.cn/docs +## WPUSH_APIKEY (必填) 在 https://wpush.cn/settings 获取,以 WPUSH 开头 +export WPUSH_APIKEY="" +## 推送渠道,支持 wechat/app/sms/mail/webhook/dingtalk/feishu/wechat_work/clawbot/qqbot,默认 wechat +export WPUSH_CHANNEL="wechat" +## 可选,Topic 广播编码;填写后按 Topic 推送 +export WPUSH_TOPIC_CODE="" + diff --git a/sample/notify.js b/sample/notify.js index c466a314..35dcce1d 100644 --- a/sample/notify.js +++ b/sample/notify.js @@ -162,6 +162,11 @@ const push_config = { OPENILINK_APP_TOKEN: '', // OpeniLink 的 app_token,在 OpeniLink Hub 后台安装 App 后获取 OPENILINK_HUB_URL: '', // OpeniLink Hub 地址,默认为 https://hub.openilink.com,自建 Hub 时填写自己的地址 OPENILINK_CONTEXT_TOKEN: '', // OpeniLink 的 context_token,用于标识消息会话上下文,可从消息事件中获取 + + // WPUSH 官方文档: https://wpush.cn/docs + WPUSH_APIKEY: '', // WPUSH 的 API Key,在 https://wpush.cn/settings 获取 + WPUSH_CHANNEL: 'wechat', // 推送渠道,支持 wechat/app/sms/mail/webhook/dingtalk/feishu/wechat_work/clawbot/qqbot + WPUSH_TOPIC_CODE: '', // 可选,Topic 广播编码 }; for (const key in push_config) { @@ -1494,6 +1499,54 @@ function wxPusherSptNotify(text, desp) { }); } + + +function wpushNotify(text, desp) { + return new Promise((resolve) => { + const { WPUSH_APIKEY, WPUSH_CHANNEL, WPUSH_TOPIC_CODE } = push_config; + if (WPUSH_APIKEY) { + const body = { + apikey: `${WPUSH_APIKEY}`, + title: `${text}`, + content: `${desp}`, + channel: `${WPUSH_CHANNEL || 'wechat'}`, + }; + if (WPUSH_TOPIC_CODE) { + body.topic_code = WPUSH_TOPIC_CODE; + } + const options = { + url: `https://api.wpush.cn/api/v1/send`, + body: JSON.stringify(body), + headers: { + 'Content-Type': 'application/json', + }, + timeout, + }; + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log('WPUSH 发送通知消息失败!\n', err); + } else { + if (data.code === 0) { + console.log('WPUSH 发送通知消息成功!'); + } else { + console.log( + `WPUSH 发送通知消息异常:${data.message || JSON.stringify(data)}`, + ); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }); + } else { + resolve(); + } + }); +} + function openiLinkNotify(text, desp) { return new Promise((resolve) => { const { OPENILINK_APP_TOKEN, OPENILINK_HUB_URL, OPENILINK_CONTEXT_TOKEN } = @@ -1674,6 +1727,7 @@ async function sendNotify(text, desp, params = {}) { wxPusherNotify(text, desp), // wxpusher wxPusherSptNotify(text, desp), // wxpusher SPT openiLinkNotify(text, desp), // OpeniLink + wpushNotify(text, desp), // WPUSH ]); } diff --git a/sample/notify.py b/sample/notify.py index 7b10d993..eb2ebb0b 100644 --- a/sample/notify.py +++ b/sample/notify.py @@ -147,6 +147,11 @@ push_config = { 'OPENILINK_APP_TOKEN': '', # OpeniLink 的 app_token,在 OpeniLink Hub 后台安装 App 后获取 官方文档: https://openilink.com/docs/hub/apps 'OPENILINK_HUB_URL': '', # OpeniLink Hub 地址,默认为 https://hub.openilink.com,自建 Hub 时填写自己的地址 'OPENILINK_CONTEXT_TOKEN': '', # OpeniLink 的 context_token,用于标识消息会话上下文,可从消息事件中获取 + + # WPUSH 官方文档: https://wpush.cn/docs + 'WPUSH_APIKEY': '', # WPUSH 的 API Key,在 https://wpush.cn/settings 获取 + 'WPUSH_CHANNEL': 'wechat', # 推送渠道,支持 wechat/app/sms/mail/webhook/dingtalk/feishu/wechat_work/clawbot/qqbot + 'WPUSH_TOPIC_CODE': '', # 可选,Topic 广播编码 } # fmt: on @@ -956,6 +961,36 @@ def wxpusher_spt(title: str, content: str) -> None: print(f"wxpusher SPT 推送失败!错误信息:{response.get('msg')}") + +def wpush(title: str, content: str) -> None: + """ + 通过 WPUSH 推送消息。 + 官方文档: https://wpush.cn/docs + """ + if not push_config.get("WPUSH_APIKEY"): + return + + print("WPUSH 服务启动") + + url = "https://api.wpush.cn/api/v1/send" + data = { + "apikey": push_config.get("WPUSH_APIKEY"), + "title": title, + "content": content, + "channel": push_config.get("WPUSH_CHANNEL") or "wechat", + } + if push_config.get("WPUSH_TOPIC_CODE"): + data["topic_code"] = push_config.get("WPUSH_TOPIC_CODE") + + headers = {"Content-Type": "application/json"} + response = requests.post(url=url, json=data, headers=headers, timeout=15).json() + + if response.get("code") == 0: + print("WPUSH 推送成功!") + else: + print(f'WPUSH 推送失败!错误信息:{response.get("message") or response}') + + def openilink(title: str, content: str) -> None: """ 通过 OpeniLink 推送消息。 @@ -1162,6 +1197,8 @@ def add_notify_function(): notify_function.append(wxpusher_spt) if push_config.get("OPENILINK_APP_TOKEN"): notify_function.append(openilink) + if push_config.get("WPUSH_APIKEY"): + notify_function.append(wpush) if not notify_function: print(f"无推送渠道,请检查通知变量是否正确") return notify_function diff --git a/src/locales/en-US.json b/src/locales/en-US.json index dd38d0b6..b4005cb2 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -661,5 +661,8 @@ "失败次数": "Failure count", "最新日志": "Latest log", "加载失败": "Failed to load", - "重试": "Retry" + "重试": "Retry", + "WPUSH的API Key,在 https://wpush.cn/settings 获取,参考 https://wpush.cn/docs": "WPUSH API Key from https://wpush.cn/settings, see https://wpush.cn/docs", + "推送渠道,支持 wechat/app/sms/mail/webhook/dingtalk/feishu/wechat_work/clawbot/qqbot,默认 wechat": "Channel: wechat/app/sms/mail/webhook/dingtalk/feishu/wechat_work/clawbot/qqbot, default wechat", + "可选,Topic 广播编码;填写后按 Topic 推送,参考 https://wpush.cn/docs": "Optional Topic code for broadcast; see https://wpush.cn/docs" } diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json index 667d9b9d..164516c4 100644 --- a/src/locales/zh-CN.json +++ b/src/locales/zh-CN.json @@ -661,5 +661,8 @@ "失败次数": "失败次数", "最新日志": "最新日志", "加载失败": "加载失败", - "重试": "重试" + "重试": "重试", + "WPUSH的API Key,在 https://wpush.cn/settings 获取,参考 https://wpush.cn/docs": "WPUSH的API Key,在 https://wpush.cn/settings 获取,参考 https://wpush.cn/docs", + "推送渠道,支持 wechat/app/sms/mail/webhook/dingtalk/feishu/wechat_work/clawbot/qqbot,默认 wechat": "推送渠道,支持 wechat/app/sms/mail/webhook/dingtalk/feishu/wechat_work/clawbot/qqbot,默认 wechat", + "可选,Topic 广播编码;填写后按 Topic 推送,参考 https://wpush.cn/docs": "可选,Topic 广播编码;填写后按 Topic 推送,参考 https://wpush.cn/docs" } diff --git a/src/utils/config.ts b/src/utils/config.ts index 3140c091..d3572cd2 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -82,6 +82,7 @@ export default { { value: 'wxPusherBot', label: 'wxPusher' }, { value: 'wxPusherSpt', label: 'WxPusher(极简推送SPT-推荐)' }, { value: 'openiLink', label: 'OpeniLink' }, + { value: 'wpush', label: 'WPUSH' }, { value: 'chat', label: intl.get('群晖chat') }, { value: 'email', label: intl.get('邮箱') }, { value: 'lark', label: intl.get('飞书机器人') }, @@ -378,6 +379,27 @@ export default { required: true, }, ], + wpush: [ + { + label: 'wpushApiKey', + tip: intl.get( + 'WPUSH的API Key,在 https://wpush.cn/settings 获取,参考 https://wpush.cn/docs', + ), + required: true, + }, + { + label: 'wpushChannel', + tip: intl.get( + '推送渠道,支持 wechat/app/sms/mail/webhook/dingtalk/feishu/wechat_work/clawbot/qqbot,默认 wechat', + ), + }, + { + label: 'wpushTopicCode', + tip: intl.get( + '可选,Topic 广播编码;填写后按 Topic 推送,参考 https://wpush.cn/docs', + ), + }, + ], openiLink: [ { label: 'openiLinkAppToken',