From 955c7377d7fd0357338e8f0a74767eb2ea3f2d64 Mon Sep 17 00:00:00 2001
From: FanchangWang <2651919937@qq.com>
Date: Fri, 13 Dec 2024 14:13:34 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20wxPusher=20=E6=8E=A8?=
=?UTF-8?q?=E9=80=81=E9=80=9A=E9=81=93=E3=80=82wxPusher=20=E5=AE=98?=
=?UTF-8?q?=E6=96=B9=E6=96=87=E6=A1=A3:=20https://wxpusher.zjiecode.com/do?=
=?UTF-8?q?cs/=20(#2594)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 增加 wxPusher 推送方式
* 补全 wxPusher 推送方式代码
* fix js 方法多进行了一次 JSON 格式化
---
back/data/notify.ts | 12 +++++--
back/services/notify.ts | 46 ++++++++++++++++++++++++++
sample/config.sample.sh | 11 ++++++-
sample/notify.js | 71 +++++++++++++++++++++++++++++++++++++++++
sample/notify.py | 57 +++++++++++++++++++++++++++++++++
src/locales/en-US.json | 3 ++
src/locales/zh-CN.json | 3 ++
src/utils/config.ts | 18 +++++++++++
8 files changed, 218 insertions(+), 3 deletions(-)
diff --git a/back/data/notify.ts b/back/data/notify.ts
index 12c62e4f..ed52ba6c 100644
--- a/back/data/notify.ts
+++ b/back/data/notify.ts
@@ -21,6 +21,7 @@ export enum NotificationMode {
'webhook' = 'webhook',
'chronocat' = 'Chronocat',
'ntfy' = 'ntfy',
+ 'wxPusherBot' = 'wxPusherBot',
}
abstract class NotificationBaseInfo {
@@ -150,6 +151,13 @@ export class NtfyNotification extends NotificationBaseInfo {
public ntfyTopic = '';
public ntfyPriority = '';
}
+
+export class WxPusherBotNotification extends NotificationBaseInfo {
+ public wxPusherBotAppToken = '';
+ public wxPusherBotTopicIds = '';
+ public wxPusherBotUids = '';
+}
+
export interface NotificationInfo
extends GoCqHttpBotNotification,
GotifyNotification,
@@ -170,5 +178,5 @@ export interface NotificationInfo
WebhookNotification,
ChronocatNotification,
LarkNotification,
- NtfyNotification {}
-
+ NtfyNotification,
+ WxPusherBotNotification {}
diff --git a/back/services/notify.ts b/back/services/notify.ts
index 526121a5..17ea4586 100644
--- a/back/services/notify.ts
+++ b/back/services/notify.ts
@@ -36,6 +36,7 @@ export default class NotificationService {
['lark', this.lark],
['chronocat', this.chronocat],
['ntfy', this.ntfy],
+ ['wxPusherBot', this.wxPusherBot],
]);
private title = '';
@@ -696,6 +697,51 @@ export default class NotificationService {
}
}
+ private async wxPusherBot() {
+ const { wxPusherBotAppToken, wxPusherBotTopicIds, wxPusherBotUids } = this.params;
+ // 处理 topicIds,将分号分隔的字符串转为数组
+ const topicIds = wxPusherBotTopicIds ? wxPusherBotTopicIds.split(';')
+ .map(id => id.trim())
+ .filter(id => id)
+ .map(id => parseInt(id)) : [];
+
+ // 处理 uids,将分号分隔的字符串转为数组
+ const uids = wxPusherBotUids ? wxPusherBotUids.split(';')
+ .map(uid => uid.trim())
+ .filter(uid => uid) : [];
+
+ // topic_ids 和 uids 至少要有一个
+ if (!topicIds.length && !uids.length) {
+ throw new Error('wxPusher 服务的 TopicIds 和 Uids 至少配置一个才行');
+ }
+
+ const url = `https://wxpusher.zjiecode.com/api/send/message`;
+ try {
+ const res: any = await got
+ .post(url, {
+ ...this.gotOption,
+ json: {
+ appToken: wxPusherBotAppToken,
+ content: `
${this.title}
${this.content}
`,
+ summary: this.title,
+ contentType: 2,
+ topicIds: topicIds,
+ uids: uids,
+ verifyPayType: 0
+ },
+ })
+ .json();
+
+ if (res.code === 1000) {
+ return true;
+ } else {
+ throw new Error(JSON.stringify(res));
+ }
+ } catch (error: any) {
+ throw new Error(error.response ? error.response.body : error);
+ }
+ }
+
private async chronocat() {
const { chronocatURL, chronocatQQ, chronocatToken } = this.params;
diff --git a/sample/config.sample.sh b/sample/config.sample.sh
index 7d2d0dde..1249ae6f 100644
--- a/sample/config.sample.sh
+++ b/sample/config.sample.sh
@@ -230,8 +230,17 @@ export NTFY_URL=""
export NTFY_TOPIC=""
export NTFY_PRIORITY="3"
+## 21. wxPusher
+## 官方文档: https://wxpusher.zjiecode.com/docs/
+## 管理后台: https://wxpusher.zjiecode.com/admin/
+## wxPusher 的 appToken
+export WXPUSHER_APP_TOKEN=""
+## wxPusher 的 topicIds,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
+export WXPUSHER_TOPIC_IDS=""
+## wxPusher 的 用户ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
+export WXPUSHER_UIDS=""
-## 21. 自定义通知
+## 22. 自定义通知
## 自定义通知 接收回调的URL
export WEBHOOK_URL=""
## WEBHOOK_BODY 和 WEBHOOK_HEADERS 多个参数时,直接换行或者使用 $'\n' 连接多行字符串,比如 export dd="line 1"$'\n'"line 2"
diff --git a/sample/notify.js b/sample/notify.js
index 77af6536..debd8b9b 100644
--- a/sample/notify.js
+++ b/sample/notify.js
@@ -105,6 +105,12 @@ const push_config = {
NTFY_URL: '', // ntfy地址,如https://ntfy.sh,默认为https://ntfy.sh
NTFY_TOPIC: '', // ntfy的消息应用topic
NTFY_PRIORITY: '3', // 推送消息优先级,默认为3
+
+ // 官方文档: https://wxpusher.zjiecode.com/docs/
+ // 管理后台: https://wxpusher.zjiecode.com/admin/
+ WXPUSHER_APP_TOKEN: '', // wxpusher 的 appToken
+ WXPUSHER_TOPIC_IDS: '', // wxpusher 的 主题ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
+ WXPUSHER_UIDS: '', // wxpusher 的 用户ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
};
for (const key in push_config) {
@@ -1246,6 +1252,70 @@ function ntfyNotify(text, desp) {
});
}
+function wxPusherNotify(text, desp) {
+ return new Promise((resolve) => {
+ const { WXPUSHER_APP_TOKEN, WXPUSHER_TOPIC_IDS, WXPUSHER_UIDS } = push_config;
+ if (WXPUSHER_APP_TOKEN) {
+ // 处理topic_ids,将分号分隔的字符串转为数组
+ const topicIds = WXPUSHER_TOPIC_IDS ? WXPUSHER_TOPIC_IDS.split(';')
+ .map(id => id.trim())
+ .filter(id => id)
+ .map(id => parseInt(id)) : [];
+
+ // 处理uids,将分号分隔的字符串转为数组
+ const uids = WXPUSHER_UIDS ? WXPUSHER_UIDS.split(';')
+ .map(uid => uid.trim())
+ .filter(uid => uid) : [];
+
+ // topic_ids uids 至少有一个
+ if (!topicIds.length && !uids.length) {
+ console.log("wxpusher 服务的 WXPUSHER_TOPIC_IDS 和 WXPUSHER_UIDS 至少设置一个!!\n取消推送");
+ return resolve();
+ }
+
+ const body = {
+ appToken: WXPUSHER_APP_TOKEN,
+ content: `${text}
${desp}
`,
+ summary: text,
+ contentType: 2,
+ topicIds: topicIds,
+ uids: uids,
+ verifyPayType: 0
+ };
+
+ const options = {
+ url: 'https://wxpusher.zjiecode.com/api/send/message',
+ body: JSON.stringify(body),
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ timeout
+ };
+
+ $.post(options, (err, resp, data) => {
+ try {
+ if (err) {
+ console.log('wxpusher发送通知消息失败!\n', err);
+ } else {
+ if (data.code === 1000) {
+ console.log('wxpusher发送通知消息完成!');
+ } else {
+ console.log(`wxpusher发送通知消息异常:${data.msg}`);
+ }
+ }
+ } catch (e) {
+ $.logErr(e, resp);
+ } finally {
+ resolve(data);
+ }
+ });
+ } else {
+ console.log('wxpusher 服务的 WXPUSHER_APP_TOKEN 未设置!!\n取消推送');
+ resolve();
+ }
+ });
+}
+
function parseString(input, valueFormatFn) {
const regex = /(\w+):\s*((?:(?!\n\w+:).)*)/g;
@@ -1376,6 +1446,7 @@ async function sendNotify(text, desp, params = {}) {
webhookNotify(text, desp), // 自定义通知
qmsgNotify(text, desp), // 自定义通知
ntfyNotify(text, desp), // Ntfy
+ wxPusherNotify(text, desp), // wxpusher
]);
}
diff --git a/sample/notify.py b/sample/notify.py
index 02fd5f0e..717d619e 100644
--- a/sample/notify.py
+++ b/sample/notify.py
@@ -126,6 +126,10 @@ push_config = {
'NTFY_URL': '', # ntfy地址,如https://ntfy.sh
'NTFY_TOPIC': '', # ntfy的消息应用topic
'NTFY_PRIORITY':'3', # 推送消息优先级,默认为3
+
+ 'WXPUSHER_APP_TOKEN': '', # wxpusher 的 appToken 官方文档: https://wxpusher.zjiecode.com/docs/ 管理后台: https://wxpusher.zjiecode.com/admin/
+ 'WXPUSHER_TOPIC_IDS': '', # wxpusher 的 主题ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
+ 'WXPUSHER_UIDS': '', # wxpusher 的 用户ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
}
# fmt: on
@@ -835,6 +839,57 @@ def ntfy(title: str, content: str) -> None:
else:
print("Ntfy 推送失败!错误信息:", response.text)
+
+def wxpusher_bot(title: str, content: str) -> None:
+ """
+ 通过 wxpusher 推送消息。
+ 支持的环境变量:
+ - WXPUSHER_APP_TOKEN: appToken
+ - WXPUSHER_TOPIC_IDS: 主题ID, 多个用英文分号;分隔
+ - WXPUSHER_UIDS: 用户ID, 多个用英文分号;分隔
+ """
+ if not push_config.get("WXPUSHER_APP_TOKEN"):
+ print("wxpusher 服务的 WXPUSHER_APP_TOKEN 未设置!!\n取消推送")
+ return
+
+
+ url = "https://wxpusher.zjiecode.com/api/send/message"
+
+ # 处理topic_ids和uids,将分号分隔的字符串转为数组
+ topic_ids = []
+ if push_config.get("WXPUSHER_TOPIC_IDS"):
+ topic_ids = [int(id.strip()) for id in push_config.get("WXPUSHER_TOPIC_IDS").split(";") if id.strip()]
+
+ uids = []
+ if push_config.get("WXPUSHER_UIDS"):
+ uids = [uid.strip() for uid in push_config.get("WXPUSHER_UIDS").split(";") if uid.strip()]
+
+ # topic_ids uids 至少有一个
+ if not topic_ids and not uids:
+ print("wxpusher 服务的 WXPUSHER_TOPIC_IDS 和 WXPUSHER_UIDS 至少设置一个!!\n取消推送")
+ return
+
+ print("wxpusher 服务启动")
+
+ data = {
+ "appToken": push_config.get("WXPUSHER_APP_TOKEN"),
+ "content": f"{title}
{content}
",
+ "summary": title,
+ "contentType": 2,
+ "topicIds": topic_ids,
+ "uids": uids,
+ "verifyPayType": 0
+ }
+
+ headers = {"Content-Type": "application/json"}
+ response = requests.post(url=url, json=data, headers=headers).json()
+
+ if response.get("code") == 1000:
+ print("wxpusher 推送成功!")
+ else:
+ print(f"wxpusher 推送失败!错误信息:{response.get('msg')}")
+
+
def parse_headers(headers):
if not headers:
return {}
@@ -997,6 +1052,8 @@ def add_notify_function():
notify_function.append(custom_notify)
if push_config.get("NTFY_TOPIC"):
notify_function.append(ntfy)
+ if push_config.get("WXPUSHER_APP_TOKEN") and (push_config.get("WXPUSHER_TOPIC_IDS") or push_config.get("WXPUSHER_UIDS")):
+ notify_function.append(wxpusher_bot)
if not notify_function:
print(f"无推送渠道,请检查通知变量是否正确")
return notify_function
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index cb9951b0..19b7c78e 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -395,6 +395,9 @@
"自建的PushMeServer消息接口地址,例如:http://127.0.0.1:3010,不填则使用官方消息接口": "The self built PushMeServer message interface address, for example: http://127.0.0.1:3010 If left blank, use the official message interface",
"ntfy的url地址,例如 https://ntfy.sh'": "The URL address of ntfy, for example, https://ntfy.sh.",
"ntfy的消息应用topic": "The topic for ntfy's messaging application.",
+ "wxPusherBot的appToken": "wxPusherBot's appToken, obtain according to docs https://wxpusher.zjiecode.com/docs/",
+ "wxPusherBot的topicIds": "wxPusherBot's topicIds, at least one of topicIds or uids must be configured",
+ "wxPusherBot的uids": "wxPusherBot's uids, at least one of topicIds or uids must be configured",
"请求方法": "Request Method",
"请求头Content-Type": "Request Header Content-Type",
"请求链接以http或者https开头。url或者body中必须包含$title,$content可选,对应api内容的位置": "Request URL should start with http or https. URL or body must contain $title, $content is optional and corresponds to the API content position.",
diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json
index 1ca52233..c3ac7226 100644
--- a/src/locales/zh-CN.json
+++ b/src/locales/zh-CN.json
@@ -395,6 +395,9 @@
"自建的PushMeServer消息接口地址,例如:http://127.0.0.1:3010,不填则使用官方消息接口": "自建的PushMeServer消息接口地址,例如:http://127.0.0.1:3010,不填则使用官方消息接口",
"ntfy的url地址,例如 https://ntfy.sh": "ntfy的url地址,例如 https://ntfy.sh",
"ntfy的消息应用topic": "ntfy的消息应用topic",
+ "wxPusherBot的appToken": "wxPusherBot的appToken, 按照文档获取 https://wxpusher.zjiecode.com/docs/",
+ "wxPusherBot的topicIds": "wxPusherBot的topicIds, topicIds 和 uids 至少配置一个才行",
+ "wxPusherBot的uids": "wxPusherBot的uids, topicIds 和 uids 至少配置一个才行",
"请求方法": "请求方法",
"请求头Content-Type": "请求头Content-Type",
"请求链接以http或者https开头。url或者body中必须包含$title,$content可选,对应api内容的位置": "请求链接以http或者https开头。url或者body中必须包含$title,$content可选,对应api内容的位置",
diff --git a/src/utils/config.ts b/src/utils/config.ts
index a5ca36f5..35ce3bae 100644
--- a/src/utils/config.ts
+++ b/src/utils/config.ts
@@ -97,6 +97,7 @@ export default {
{ value: 'iGot', label: 'IGot' },
{ value: 'pushPlus', label: 'PushPlus' },
{ value: 'wePlusBot', label: intl.get('微加机器人') },
+ { value: 'wxPusherBot', label: 'wxPusher' },
{ value: 'chat', label: intl.get('群晖chat') },
{ value: 'email', label: intl.get('邮箱') },
{ value: 'lark', label: intl.get('飞书机器人') },
@@ -378,6 +379,23 @@ export default {
),
},
],
+ wxPusherBot: [
+ {
+ label: 'wxPusherBotAppToken',
+ tip: intl.get('wxPusherBot的appToken'),
+ required: true,
+ },
+ {
+ label: 'wxPusherBotTopicIds',
+ tip: intl.get('wxPusherBot的topicIds'),
+ required: false,
+ },
+ {
+ label: 'wxPusherBotUids',
+ tip: intl.get('wxPusherBot的uids'),
+ required: false,
+ },
+ ],
lark: [
{
label: 'larkKey',