133 lines
4.5 KiB
Python
133 lines
4.5 KiB
Python
import smtplib
|
||
from email.mime.text import MIMEText
|
||
from email.mime.multipart import MIMEMultipart
|
||
from email.mime.base import MIMEBase
|
||
from email import encoders
|
||
import os
|
||
import time
|
||
|
||
|
||
class EmailSender:
|
||
def __init__(self, smtp_server, smtp_port, sender_email, sender_password):
|
||
"""初始化邮件发送工具类
|
||
|
||
Args:
|
||
smtp_server (str): SMTP 服务器地址
|
||
smtp_port (int): SMTP 服务器端口
|
||
sender_email (str): 发件人邮箱地址
|
||
sender_password (str): 发件人邮箱密码或授权码
|
||
"""
|
||
self.smtp_server = smtp_server
|
||
self.smtp_port = smtp_port
|
||
self.sender_email = sender_email
|
||
self.sender_password = sender_password
|
||
|
||
def send_email(self, recipient, subject, body, is_html=False, attachments=None):
|
||
"""发送电子邮件
|
||
|
||
Args:
|
||
recipient (str or list): 收件人邮箱地址,单个地址或地址列表
|
||
subject (str): 邮件主题
|
||
body (str): 邮件正文内容
|
||
is_html (bool): 是否为 HTML 格式内容
|
||
attachments (list): 附件文件路径列表
|
||
|
||
Returns:
|
||
bool: 发送成功返回 True,失败返回 False
|
||
"""
|
||
try:
|
||
# 创建邮件对象
|
||
msg = MIMEMultipart()
|
||
msg['From'] = self.sender_email
|
||
msg['Subject'] = subject
|
||
|
||
# 处理收件人
|
||
if isinstance(recipient, str):
|
||
msg['To'] = recipient
|
||
else:
|
||
msg['To'] = ", ".join(recipient)
|
||
|
||
# 添加邮件正文
|
||
if is_html:
|
||
msg.attach(MIMEText(body, 'html', 'utf-8'))
|
||
else:
|
||
msg.attach(MIMEText(body, 'plain', 'utf-8'))
|
||
|
||
# 处理附件
|
||
if attachments:
|
||
for file_path in attachments:
|
||
if os.path.isfile(file_path):
|
||
with open(file_path, 'rb') as f:
|
||
part = MIMEBase('application', 'octet-stream')
|
||
part.set_payload(f.read())
|
||
|
||
# 编码附件
|
||
encoders.encode_base64(part)
|
||
|
||
# 添加附件头信息
|
||
part.add_header(
|
||
'Content-Disposition',
|
||
f'attachment; filename= {os.path.basename(file_path)}'
|
||
)
|
||
msg.attach(part)
|
||
|
||
# 连接 SMTP 服务器并发送
|
||
with smtplib.SMTP_SSL(self.smtp_server, self.smtp_port) as server:
|
||
server.login(self.sender_email, self.sender_password)
|
||
server.send_message(msg)
|
||
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"发送邮件失败: {str(e)}")
|
||
return False
|
||
|
||
def send_wechat_alert(self, recipient, error_msg, wxid, nickname, attachments=None):
|
||
"""发送微信机器人异常通知邮件
|
||
|
||
Args:
|
||
recipient (str or list): 收件人邮箱地址
|
||
error_msg (str): 错误信息
|
||
wxid (str): 微信ID
|
||
nickname (str): 微信昵称
|
||
attachments (list): 附件文件路径列表
|
||
|
||
Returns:
|
||
bool: 发送成功返回 True,失败返回 False
|
||
"""
|
||
subject = "微信机器人异常通知:用户可能退出"
|
||
content = f"""
|
||
<html>
|
||
<body>
|
||
<h2>微信机器人异常通知</h2>
|
||
<p>检测到微信机器人出现"用户可能退出"异常</p>
|
||
<p>错误信息: {error_msg}</p>
|
||
<p>时间: {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}</p>
|
||
<p>机器人信息:</p>
|
||
<ul>
|
||
<li>微信ID: {wxid}</li>
|
||
<li>昵称: {nickname}</li>
|
||
</ul>
|
||
</body>
|
||
</html>
|
||
"""
|
||
return self.send_email(recipient, subject, content, is_html=True, attachments=attachments)
|
||
|
||
|
||
# 使用示例
|
||
if __name__ == "__main__":
|
||
# 配置示例(请替换为实际的 SMTP 服务器信息)
|
||
email_sender = EmailSender(
|
||
smtp_server="smtp.163.com",
|
||
smtp_port=465,
|
||
sender_email="bovine_liu@163.com",
|
||
sender_password="LTS9BhmX9XhS36QS"
|
||
)
|
||
# 发送微信机器人异常通知
|
||
email_sender.send_wechat_alert(
|
||
recipient="bovine_liu@163.com",
|
||
error_msg="用户未响应,可能是未登录或退出",
|
||
wxid="wxid_123456789",
|
||
nickname="TestBot",
|
||
attachments=["error_log.txt"]
|
||
) |