- email_client: log IMAP connection, login, UNSEEN count, each email details (subject/sender/body size), mark-as-seen progress - ai_client: log AI request params, timing, token usage, response size - smtp_client: log SMTP connect, login, send details - tg_bot: log all callback actions with subject context, message states - main: periodic queue depth report (email_queue/tg_queue/pending_uids)
40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
import smtplib
|
|
import logging
|
|
from email.mime.text import MIMEText
|
|
from email.mime.multipart import MIMEMultipart
|
|
from src.config import EmailAccount
|
|
from src.retry import retry
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@retry()
|
|
def send_reply(account: EmailAccount, to_addr: str, subject: str, body: str):
|
|
if not account.smtp:
|
|
raise RuntimeError(f"账号 {account.username} 未配置 SMTP")
|
|
|
|
s = account.smtp
|
|
logger.info("SMTP 连接: %s:%d (ssl=%s)", s.server, s.port, s.use_ssl)
|
|
if s.use_ssl:
|
|
conn = smtplib.SMTP_SSL(s.server, s.port, timeout=15)
|
|
else:
|
|
conn = smtplib.SMTP(s.server, s.port, timeout=15)
|
|
if s.use_starttls:
|
|
conn.starttls()
|
|
|
|
conn.login(account.username, account.password)
|
|
logger.info("SMTP 登录成功")
|
|
|
|
reply_subject = subject if subject.lower().startswith("re:") else f"Re: {subject}"
|
|
logger.info("SMTP 发送: to=%s subject=%s body=%d 字符", to_addr, reply_subject, len(body))
|
|
|
|
msg = MIMEMultipart("alternative")
|
|
msg["From"] = account.username
|
|
msg["To"] = to_addr
|
|
msg["Subject"] = reply_subject
|
|
msg.attach(MIMEText(body, "plain", "utf-8"))
|
|
|
|
conn.sendmail(account.username, [to_addr], msg.as_string())
|
|
conn.quit()
|
|
logger.info("SMTP 发送完成")
|