From 57939391b9a7f276edeedf3d6248741df6724853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=86=B6=E5=A4=A3?= <56494145+liheji@users.noreply.github.com> Date: Sat, 7 Jun 2025 00:26:27 +0800 Subject: [PATCH] =?UTF-8?q?ntfy=20=E5=A2=9E=E5=8A=A0=E5=8F=AF=E9=80=89?= =?UTF-8?q?=E7=9A=84=E8=AE=A4=E8=AF=81=E4=B8=8E=E7=94=A8=E6=88=B7=E5=8A=A8?= =?UTF-8?q?=E4=BD=9C=20(#2741)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat:ntfy增加可选的认证 * feat:ntfy增加可选的用户动作 * fix:ntfy动作包含中文报错 --- back/data/notify.ts | 4 ++++ back/services/notify.ts | 18 +++++++++++++++--- sample/config.sample.sh | 8 ++++++++ sample/notify.js | 16 +++++++++++++++- sample/notify.py | 13 ++++++++++++- src/locales/en-US.json | 6 +++++- src/locales/zh-CN.json | 7 +++++-- src/utils/config.ts | 6 +++++- 8 files changed, 69 insertions(+), 9 deletions(-) diff --git a/back/data/notify.ts b/back/data/notify.ts index 547a8446..ef45d730 100644 --- a/back/data/notify.ts +++ b/back/data/notify.ts @@ -150,6 +150,10 @@ export class NtfyNotification extends NotificationBaseInfo { public ntfyUrl = ''; public ntfyTopic = ''; public ntfyPriority = ''; + public ntfyToken = ''; + public ntfyUsername = ''; + public ntfyPassword = ''; + public ntfyActions = ''; } export class WxPusherBotNotification extends NotificationBaseInfo { diff --git a/back/services/notify.ts b/back/services/notify.ts index 9aebe5e6..9bb11a50 100644 --- a/back/services/notify.ts +++ b/back/services/notify.ts @@ -623,20 +623,32 @@ export default class NotificationService { } private async ntfy() { - const { ntfyUrl, ntfyTopic, ntfyPriority } = this.params; + const { ntfyUrl, ntfyTopic, ntfyPriority, ntfyToken, ntfyUsername, ntfyPassword, ntfyActions } = this.params; // 编码函数 const encodeRfc2047 = (text: string, charset: string = 'UTF-8'): string => { const encodedText = Buffer.from(text).toString('base64'); return `=?${charset}?B?${encodedText}?=`; }; try { - const encodedTitle = encodeRfc2047(this.title); + const headers: Record = { + Title: encodeRfc2047(this.title), + Priority: `${ntfyPriority || '3'}`, + Icon: 'https://qn.whyour.cn/logo.png', + }; + if (ntfyToken) { + headers['Authorization'] = `Bearer ${ntfyToken}`; + } else if (ntfyUsername && ntfyPassword) { + headers['Authorization'] = `Basic ${Buffer.from(`${ntfyUsername}:${ntfyPassword}`).toString('base64')}`; + } + if (ntfyActions) { + headers['Actions'] = encodeRfc2047(ntfyActions); + } const res = await httpClient.request( `${ntfyUrl || 'https://ntfy.sh'}/${ntfyTopic}`, { ...this.gotOption, body: `${this.content}`, - headers: { Title: encodedTitle, Priority: `${ntfyPriority || '3'}` }, + headers: headers, method: 'POST', }, ); diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 1249ae6f..734f4ae5 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -226,9 +226,17 @@ export QMSG_TYPE="" ## ntfy_url 填写ntfy地址,如https://ntfy.sh ## ntfy_topic 填写ntfy的消息应用topic ## ntfy_priority 填写推送消息优先级,默认为3 +## ntfy_token 填写推送token,可选 +## ntfy_username 填写推送用户名称,可选 +## ntfy_password 填写推送用户密码,可选 +## ntfy_actions 填写推送用户动作,可选 export NTFY_URL="" export NTFY_TOPIC="" export NTFY_PRIORITY="3" +export NTFY_TOKEN="" +export NTFY_USERNAME="" +export NTFY_PASSWORD="" +export NTFY_ACTIONS="" ## 21. wxPusher ## 官方文档: https://wxpusher.zjiecode.com/docs/ diff --git a/sample/notify.js b/sample/notify.js index 5e870598..8dfe8851 100644 --- a/sample/notify.js +++ b/sample/notify.js @@ -140,6 +140,10 @@ const push_config = { NTFY_URL: '', // ntfy地址,如https://ntfy.sh,默认为https://ntfy.sh NTFY_TOPIC: '', // ntfy的消息应用topic NTFY_PRIORITY: '3', // 推送消息优先级,默认为3 + NTFY_TOKEN: '', // 推送token,可选 + NTFY_USERNAME: '', // 推送用户名称,可选 + NTFY_PASSWORD: '', // 推送用户密码,可选 + NTFY_ACTIONS: '', // 推送用户动作,可选 // 官方文档: https://wxpusher.zjiecode.com/docs/ // 管理后台: https://wxpusher.zjiecode.com/admin/ @@ -1258,7 +1262,7 @@ function ntfyNotify(text, desp) { } return new Promise((resolve) => { - const { NTFY_URL, NTFY_TOPIC, NTFY_PRIORITY } = push_config; + const { NTFY_URL, NTFY_TOPIC, NTFY_PRIORITY, NTFY_TOKEN, NTFY_USERNAME, NTFY_PASSWORD, NTFY_ACTIONS } = push_config; if (NTFY_TOPIC) { const options = { url: `${NTFY_URL || 'https://ntfy.sh'}/${NTFY_TOPIC}`, @@ -1266,9 +1270,19 @@ function ntfyNotify(text, desp) { headers: { Title: `${encodeRFC2047(text)}`, Priority: NTFY_PRIORITY || '3', + Icon: 'https://qn.whyour.cn/logo.png', }, timeout, }; + if (NTFY_TOKEN) { + options.headers['Authorization'] = `Bearer ${NTFY_TOKEN}`; + } else if (NTFY_USERNAME && NTFY_PASSWORD) { + options.headers['Authorization'] = `Basic ${Buffer.from(`${NTFY_USERNAME}:${NTFY_PASSWORD}`).toString('base64')}`; + } + if (NTFY_ACTIONS) { + options.headers['Actions'] = encodeRFC2047(NTFY_ACTIONS); + } + $.post(options, (err, resp, data) => { try { if (err) { diff --git a/sample/notify.py b/sample/notify.py index e62d4218..032bb97e 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 + 'NTFY_TOKEN': '', # 推送token,可选 + 'NTFY_USERNAME': '', # 推送用户名称,可选 + 'NTFY_PASSWORD': '', # 推送用户密码,可选 + 'NTFY_ACTIONS': '', # 推送用户动作,可选 'WXPUSHER_APP_TOKEN': '', # wxpusher 的 appToken 官方文档: https://wxpusher.zjiecode.com/docs/ 管理后台: https://wxpusher.zjiecode.com/admin/ 'WXPUSHER_TOPIC_IDS': '', # wxpusher 的 主题ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行 @@ -806,7 +810,14 @@ def ntfy(title: str, content: str) -> None: encoded_title = encode_rfc2047(title) data = content.encode(encoding="utf-8") - headers = {"Title": encoded_title, "Priority": priority} # 使用编码后的 title + headers = {"Title": encoded_title, "Priority": priority, "Icon": "https://qn.whyour.cn/logo.png"} # 使用编码后的 title + if push_config.get("NTFY_TOKEN"): + headers['Authorization'] = "Bearer " + push_config.get("NTFY_TOKEN") + elif push_config.get("NTFY_USERNAME") and push_config.get("NTFY_PASSWORD"): + authStr = push_config.get("NTFY_USERNAME") + ":" + push_config.get("NTFY_PASSWORD") + headers['Authorization'] = "Basic " + base64.b64encode(authStr.encode('utf-8')).decode('utf-8') + if push_config.get("NTFY_ACTIONS"): + headers['Actions'] = encode_rfc2047(push_config.get("NTFY_ACTIONS")) url = push_config.get("NTFY_URL") + "/" + push_config.get("NTFY_TOPIC") response = requests.post(url, data=data, headers=headers) diff --git a/src/locales/en-US.json b/src/locales/en-US.json index 353b0df9..9d2968bc 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -395,7 +395,11 @@ "PushMe的Key,https://push.i-i.me/": "PushMe key, https://push.i-i.me/", "自建的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.", + "ntfy应用topic": "The topic for ntfy's application.", + "ntfy应用token": "The token for ntfy's application, see https://docs.ntfy.sh/config/#access-tokens", + "ntfy应用用户名": "The username for ntfy's application, see https://docs.ntfy.sh/config/#users-and-roles", + "ntfy应用密码": "The password for ntfy's application, see https://docs.ntfy.sh/config/#users-and-roles", + "ntfy用户动作": "The user actions for ntfy's application, up to three actions, see https://docs.ntfy.sh/publish/?h=actions#action-buttons", "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", diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json index 0a178572..5baff0a1 100644 --- a/src/locales/zh-CN.json +++ b/src/locales/zh-CN.json @@ -395,7 +395,11 @@ "PushMe的Key,https://push.i-i.me/": "PushMe的Key,https://push.i-i.me/", "自建的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", + "ntfy应用topic": "ntfy应用topic", + "ntfy应用token": "ntfy应用token,参考 https://docs.ntfy.sh/config/#access-tokens", + "ntfy应用用户名": "ntfy应用用户名,参考 https://docs.ntfy.sh/config/#users-and-roles", + "ntfy应用密码": "ntfy应用密码,参考 https://docs.ntfy.sh/config/#users-and-roles", + "ntfy用户动作": "ntfy用户动作,最多三个动作,参考 https://docs.ntfy.sh/publish/?h=actions#action-buttons", "wxPusherBot的appToken": "wxPusherBot的appToken, 按照文档获取 https://wxpusher.zjiecode.com/docs/", "wxPusherBot的topicIds": "wxPusherBot的topicIds, topicIds 和 uids 至少配置一个才行", "wxPusherBot的uids": "wxPusherBot的uids, topicIds 和 uids 至少配置一个才行", @@ -508,4 +512,3 @@ "当前文件未保存,确认离开吗": "当前文件未保存,确认离开吗", "收件邮箱地址,多个分号分隔,默认发送给发件邮箱地址": "收件邮箱地址,多个分号分隔,默认发送给发件邮箱地址" } - \ No newline at end of file diff --git a/src/utils/config.ts b/src/utils/config.ts index 179710a2..49eab36b 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -128,10 +128,14 @@ export default { }, { label: 'ntfyTopic', - tip: intl.get('ntfy的消息应用topic'), + tip: intl.get('ntfy应用topic'), required: true, }, { label: 'ntfyPriority', tip: intl.get('推送消息的优先级') }, + { label: 'ntfyToken', tip: intl.get('ntfy应用token') }, + { label: 'ntfyUsername', tip: intl.get('ntfy应用用户名') }, + { label: 'ntfyPassword', tip: intl.get('ntfy应用密码') }, + { label: 'ntfyActions', tip: intl.get('ntfy用户动作') }, ], chat: [ {