feat(notification): 优化用户通知服务

This commit is contained in:
2025-05-19 01:10:20 +08:00
parent 3787c25a77
commit bc5b15cec2

View File

@@ -25,18 +25,20 @@ v4.3
作者DLmaster_361
"""
from PySide6.QtWidgets import QWidget
from PySide6.QtCore import Signal
import requests
import time
from loguru import logger
from plyer import notification
import re
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import time
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formataddr
import requests
from PySide6.QtCore import Signal
from PySide6.QtWidgets import QWidget
from loguru import logger
from plyer import notification
from app.core import Config
from app.services.security import Crypto
@@ -320,43 +322,49 @@ class UserNotification:
self.config = user_config
def send_notification(self, title: str, content: str) -> bool:
"""发送用户通知
"""发送用户通知"""
logger.info(f"单独通知-准备发送用户通知,标题: {title}")
Args:
title: 通知标题
content: 通知内容
Returns:
bool: 是否发送成功
"""
if not self.config.get(self.config.Notify_Enable):
logger.warning("单独通知-用户通知功能未启用,跳过发送")
return False
success = False
# 发送邮件通知
# 邮件通知
if self._check_smtp_config():
try:
self._send_email(title, content)
success = True
except Exception as e:
logger.error(f"发送邮件通知失败: {str(e)}")
logger.error(f"单独通知-发送邮件通知失败: {str(e)}")
# 发送ServerChan通知
if self.config.get(self.config.Notify_IfServerChan) and self._check_serverchan_config():
# Server通知
if (
self.config.get(self.config.Notify_IfServerChan)
and self._check_serverchan_config()
):
try:
self._send_serverchan(title, content)
success = True
except Exception as e:
logger.error(f"发送ServerChan通知失败: {str(e)}")
logger.error(f"单独通知-发送 Server通知失败: {str(e)}")
# 发送企业微信机器人通知
if self.config.get(self.config.Notify_IfCompanyWebHookBot) and self._check_webhook_config():
# 企业微信机器人
if (
self.config.get(self.config.Notify_IfCompanyWebHookBot)
and self._check_webhook_config()
):
try:
self._send_webhook(title, content)
success = True
except Exception as e:
logger.error(f"发送企业微信机器人通知失败: {str(e)}")
logger.error(f"单独通知-发送企业微信机器人通知失败: {str(e)}")
if success:
logger.info("单独通知-用户通知发送完成")
else:
logger.warning("单独通知-所有通知方式均发送失败")
return success
@@ -380,6 +388,7 @@ class UserNotification:
def _send_email(self, title: str, content: str):
"""发送邮件通知"""
logger.debug("单独通知-开始发送邮件通知")
import smtplib
from email.mime.text import MIMEText
from email.header import Header
@@ -396,31 +405,76 @@ class UserNotification:
)
server.send_message(msg)
server.quit()
logger.success("单独通知-邮件通知发送成功")
def _send_serverchan(self, title: str, content: str):
"""发送ServerChan通知"""
"""发送 ServerChan 通知,支持 SCT、SC3、自定义域名等"""
logger.debug("单独通知-开始发送 ServerChan 通知")
import requests
import re
key = self.config.get(self.config.Notify_ServerChanKey)
channel = self.config.get(self.config.Notify_ServerChanChannel)
tag = self.config.get(self.config.Notify_ServerChanTag)
channel = self.config.get(self.config.Notify_ServerChanChannel)
url = f"https://sctapi.ftqq.com/{key}.send"
data = {
"title": title,
"desp": content,
"channel": channel if channel else 9, # 默认使用企业微信通道
"tag": tag if tag else ""
}
if not key:
raise Exception("ServerChan SendKey 未设置")
response = requests.post(url, data=data)
if response.status_code != 200:
raise Exception(f"ServerChan API返回错误: {response.text}")
# 1. 构造 URL支持 sctpN 和 sct 开头的)
if key.startswith("sctp"):
match = re.match(r"^sctp(\d+)t", key)
if match:
url = f"https://{match.group(1)}.push.ft07.com/send/{key}.send"
else:
raise ValueError("SendKey 格式错误sctp 开头但不符合规范")
else:
url = f"https://sctapi.ftqq.com/{key}.send"
logger.debug(f"单独通知-Server酱推送URL: {url}")
# 2. 校验 tag 和 channel 格式
def is_valid(s):
return s == "" or (
s == "|".join(s.split("|")) and (s.count("|") == 0 or all(s.split("|")))
)
tags = "|".join([_.strip() for _ in tag.split("|")]) if tag else ""
channels = "|".join([_.strip() for _ in channel.split("|")]) if channel else ""
options = {}
if is_valid(tags):
options["tags"] = tags
else:
logger.warning("单独通知-ServerChan Tag 格式不正确,已忽略")
if is_valid(channels):
options["channel"] = channels
else:
logger.warning("单独通知-ServerChan Channel 格式不正确,已忽略")
# 3. 构造 payload
payload = {"title": title, "desp": content, **options}
headers = {"Content-Type": "application/json;charset=utf-8"}
logger.info(f"单独通知-发送 Server酱通知: {payload}")
try:
response = requests.post(url, json=payload, headers=headers, timeout=10)
result = response.json()
if result.get("code") == 0:
logger.success("Server酱通知推送成功")
else:
raise Exception(
f"推送失败,响应码:{result.get('code')}, 信息:{result}"
)
except Exception as e:
raise Exception(f"Server酱推送失败: {e}")
def _send_webhook(self, title: str, content: str):
"""发送企业微信机器人通知"""
logger.debug("单独通知-开始发送企业微信机器人通知")
import requests
import json
url = self.config.get(self.config.Notify_CompanyWebHookBotUrl)
data = {
@@ -433,6 +487,7 @@ class UserNotification:
response = requests.post(url, json=data)
if response.status_code != 200:
raise Exception(f"企业微信机器人API返回错误: {response.text}")
logger.success("单独通知-企业微信机器人通知发送成功")
Notify = Notification()