""" 邮件发送服务 """ import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from typing import List, Optional from loguru import logger from config import settings class EmailService: """邮件发送服务""" def __init__(self): self.smtp_server = settings.email_smtp_server self.smtp_port = settings.email_smtp_port self.username = settings.email_smtp_username self.password = settings.email_smtp_password self.from_email = settings.email_from_email def send_email(self, to_emails: List[str], subject: str, content: str) -> bool: """ 发送邮件 Args: to_emails: 收件人邮箱列表 subject: 邮件主题 content: 邮件内容 Returns: 发送成功返回True,失败返回False """ if not settings.email_enabled: logger.info("邮件发送功能已禁用") return True if not to_emails: logger.warning("收件人邮箱列表为空") return False try: # 创建邮件对象 msg = MIMEMultipart() msg["From"] = self.from_email msg["To"] = ", ".join(to_emails) msg["Subject"] = subject # 添加邮件内容 msg.attach(MIMEText(content, "plain", "utf-8")) # 连接SMTP服务器并发送邮件 server = None email_sent = False try: server = smtplib.SMTP(self.smtp_server, self.smtp_port) server.starttls() # 启用TLS加密 server.login(self.username, self.password) # 发送邮件 text = msg.as_string() server.sendmail(self.from_email, to_emails, text) email_sent = True logger.info(f"邮件发送成功: to={to_emails}, subject={subject}") finally: # 安全关闭连接,忽略关闭时的异常 if server: try: server.quit() except Exception: # 忽略关闭连接时的异常,因为邮件可能已经发送成功 pass return email_sent except smtplib.SMTPAuthenticationError as e: logger.error(f"邮件发送认证失败: error={str(e)}") return False except smtplib.SMTPException as e: logger.error(f"邮件发送SMTP错误: error={str(e)}") return False except Exception as e: logger.error(f"邮件发送异常: error={str(e)}") return False def send_notification(self, subject: str, content: str) -> bool: """ 发送通知邮件到配置的收件人列表 Args: subject: 邮件主题 content: 邮件内容 Returns: 发送成功返回True,失败返回False """ return self.send_email(settings.email_to_emails, subject, content) def test_connection(self) -> bool: """ 测试邮件服务器连接 Returns: 连接成功返回True,失败返回False """ if not settings.email_enabled: logger.info("邮件发送功能已禁用") return True try: server = None connection_success = False try: server = smtplib.SMTP(self.smtp_server, self.smtp_port) server.starttls() server.login(self.username, self.password) connection_success = True logger.info("邮件服务器连接测试成功") finally: # 安全关闭连接,忽略关闭时的异常 if server: try: server.quit() except Exception: # 忽略关闭连接时的异常 pass return connection_success except smtplib.SMTPAuthenticationError as e: logger.error(f"邮件服务器认证失败: error={str(e)}") return False except smtplib.SMTPException as e: logger.error(f"邮件服务器连接SMTP错误: error={str(e)}") return False except Exception as e: logger.error(f"邮件服务器连接异常: error={str(e)}") return False # 全局邮件服务实例 email_service = EmailService()