Files
stock_cursor_v0/backend/notifier.py

85 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""推送通知:邮件(SMTP) + Server酱 + 企业微信机器人 + PushPlus。
任意渠道配置了凭证即启用notify() 会向所有已配置渠道发送,返回各渠道结果。
"""
from __future__ import annotations
import smtplib
import ssl
from email.mime.text import MIMEText
from email.header import Header
import requests
import config
def channels_status():
return {
"email": bool(config.SMTP_HOST and config.SMTP_USER and config.SMTP_TO),
"serverchan": bool(config.SERVERCHAN_KEY),
"wecom": bool(config.WECOM_WEBHOOK),
"pushplus": bool(config.PUSHPLUS_TOKEN),
}
def any_enabled():
return any(channels_status().values())
def _send_email(title, content):
msg = MIMEText(content, "plain", "utf-8")
msg["Subject"] = Header(title, "utf-8")
msg["From"] = config.SMTP_USER
tos = [x.strip() for x in config.SMTP_TO.split(",") if x.strip()]
msg["To"] = ",".join(tos)
ctx = ssl.create_default_context()
if config.SMTP_PORT == 465:
with smtplib.SMTP_SSL(config.SMTP_HOST, config.SMTP_PORT, context=ctx, timeout=15) as srv:
srv.login(config.SMTP_USER, config.SMTP_PASSWORD)
srv.sendmail(config.SMTP_USER, tos, msg.as_string())
else:
with smtplib.SMTP(config.SMTP_HOST, config.SMTP_PORT, timeout=15) as srv:
srv.starttls(context=ctx)
srv.login(config.SMTP_USER, config.SMTP_PASSWORD)
srv.sendmail(config.SMTP_USER, tos, msg.as_string())
return True
def _send_serverchan(title, content):
url = f"https://sctapi.ftqq.com/{config.SERVERCHAN_KEY}.send"
r = requests.post(url, data={"title": title, "desp": content}, timeout=12)
r.raise_for_status()
return r.json().get("code", 0) == 0
def _send_wecom(title, content):
r = requests.post(config.WECOM_WEBHOOK,
json={"msgtype": "text", "text": {"content": f"{title}\n{content}"}}, timeout=12)
r.raise_for_status()
return r.json().get("errcode", -1) == 0
def _send_pushplus(title, content):
r = requests.post("https://www.pushplus.plus/send",
json={"token": config.PUSHPLUS_TOKEN, "title": title, "content": content}, timeout=12)
r.raise_for_status()
return r.json().get("code", 0) == 200
def notify(title, content):
"""向所有已配置渠道推送,返回 {渠道: 'ok'|错误信息}。"""
st = channels_status()
senders = {"email": _send_email, "serverchan": _send_serverchan,
"wecom": _send_wecom, "pushplus": _send_pushplus}
result = {}
for ch, on in st.items():
if not on:
continue
try:
senders[ch](title, content)
result[ch] = "ok"
except Exception as e:
result[ch] = repr(e)[:120]
return result