Files
ProxyAuto/services/email_service.py

198 lines
6.2 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.
"""邮件发送服务"""
from __future__ import annotations
import logging
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from typing import Optional
logger = logging.getLogger(__name__)
def send_email(
smtp_host: str,
smtp_port: int,
smtp_user: str,
smtp_password: str,
use_tls: bool,
to_email: str,
subject: str,
body: str,
html_body: Optional[str] = None,
) -> dict:
"""
发送邮件
Args:
smtp_host: SMTP 服务器地址
smtp_port: SMTP 端口
smtp_user: SMTP 用户名
smtp_password: SMTP 密码
use_tls: 是否使用 TLS
to_email: 收件人邮箱
subject: 邮件主题
body: 纯文本内容
html_body: HTML 内容(可选)
Returns:
{"ok": True/False, "message": "..."}
"""
try:
# 创建邮件
msg = MIMEMultipart("alternative")
msg["Subject"] = subject
msg["From"] = smtp_user
msg["To"] = to_email
# 添加纯文本内容
part1 = MIMEText(body, "plain", "utf-8")
msg.attach(part1)
# 添加 HTML 内容
if html_body:
part2 = MIMEText(html_body, "html", "utf-8")
msg.attach(part2)
# 连接 SMTP 服务器
if use_tls:
server = smtplib.SMTP(smtp_host, smtp_port, timeout=30)
server.starttls()
else:
server = smtplib.SMTP_SSL(smtp_host, smtp_port, timeout=30)
server.login(smtp_user, smtp_password)
server.sendmail(smtp_user, [to_email], msg.as_string())
server.quit()
logger.info("Email sent successfully to %s: %s", to_email, subject)
return {"ok": True, "message": "邮件发送成功"}
except smtplib.SMTPAuthenticationError as e:
logger.error("SMTP authentication failed: %s", e)
return {"ok": False, "message": "SMTP 认证失败,请检查用户名和密码"}
except smtplib.SMTPConnectError as e:
logger.error("SMTP connection failed: %s", e)
return {"ok": False, "message": "无法连接到 SMTP 服务器"}
except Exception as e:
logger.exception("Failed to send email")
return {"ok": False, "message": str(e)}
def send_traffic_alert_email(
smtp_host: str,
smtp_port: int,
smtp_user: str,
smtp_password: str,
use_tls: bool,
to_email: str,
machine_name: str,
aws_service: str,
current_traffic_gb: float,
limit_gb: float,
traffic_type: str, # "total" or "upload"
) -> dict:
"""
发送流量预警邮件
Args:
machine_name: 机器名称
aws_service: 服务类型ec2/lightsail
current_traffic_gb: 当前流量GB
limit_gb: 限制流量GB
traffic_type: 流量类型total=总流量, upload=上传流量)
"""
if traffic_type == "total":
traffic_desc = "总流量(上传+下载)"
else:
traffic_desc = "上传流量"
subject = f"[ProxyAuto] 流量预警 - {machine_name}"
body = f"""
流量预警通知
机器名称: {machine_name}
服务类型: {aws_service.upper()}
预警类型: {traffic_desc}超限
当前{traffic_desc}: {current_traffic_gb:.2f} GB
设定限制: {limit_gb:.2f} GB
超出: {current_traffic_gb - limit_gb:.2f} GB
系统已自动暂停该机器的 IP 自动更换任务。
---
ProxyAuto Pro 自动通知
"""
html_body = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; line-height: 1.6; color: #333; }}
.container {{ max-width: 600px; margin: 0 auto; padding: 20px; }}
.header {{ background: linear-gradient(135deg, #1F6BFF, #3D8BFF); color: white; padding: 20px; border-radius: 8px 8px 0 0; }}
.content {{ background: #f9f9f9; padding: 20px; border: 1px solid #e0e0e0; border-top: none; border-radius: 0 0 8px 8px; }}
.alert {{ background: #FEE2E2; border-left: 4px solid #EF4444; padding: 15px; margin: 15px 0; border-radius: 4px; }}
.info-row {{ display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #e0e0e0; }}
.info-label {{ color: #666; }}
.info-value {{ font-weight: 600; }}
.footer {{ text-align: center; padding: 15px; color: #999; font-size: 12px; }}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h2 style="margin: 0;">流量预警通知</h2>
</div>
<div class="content">
<div class="alert">
<strong>警告:</strong>{traffic_desc}已超出设定限制!
</div>
<div class="info-row">
<span class="info-label">机器名称</span>
<span class="info-value">{machine_name}</span>
</div>
<div class="info-row">
<span class="info-label">服务类型</span>
<span class="info-value">{aws_service.upper()}</span>
</div>
<div class="info-row">
<span class="info-label">当前{traffic_desc}</span>
<span class="info-value" style="color: #EF4444;">{current_traffic_gb:.2f} GB</span>
</div>
<div class="info-row">
<span class="info-label">设定限制</span>
<span class="info-value">{limit_gb:.2f} GB</span>
</div>
<div class="info-row">
<span class="info-label">超出流量</span>
<span class="info-value" style="color: #EF4444;">{current_traffic_gb - limit_gb:.2f} GB</span>
</div>
<p style="margin-top: 20px; color: #666;">
系统已自动暂停该机器的 IP 自动更换任务。请登录控制台查看详情。
</p>
</div>
<div class="footer">
ProxyAuto Pro 自动通知
</div>
</div>
</body>
</html>
"""
return send_email(
smtp_host=smtp_host,
smtp_port=smtp_port,
smtp_user=smtp_user,
smtp_password=smtp_password,
use_tls=use_tls,
to_email=to_email,
subject=subject,
body=body,
html_body=html_body,
)