zioinfo-mail/backend/smtp_client.py

60 lines
1.9 KiB
Python

"""SMTP 발송: smtplib STARTTLS + Sent 폴더 자동 저장"""
import smtplib, ssl, asyncio
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from email.utils import formatdate
from typing import Optional
SMTP_HOST = "localhost"
SMTP_PORT = 587
async def send_mail(
username: str, password: str,
to: str, subject: str, body: str,
cc: Optional[str] = None, bcc: Optional[str] = None,
is_html: bool = False,
attachments: Optional[list] = None,
) -> bytes:
"""발송 성공 시 raw 메시지 바이트 반환 (Sent 폴더 저장용)"""
msg = MIMEMultipart("alternative" if is_html else "mixed")
msg["From"] = username
msg["To"] = to
msg["Subject"] = subject
msg["Date"] = formatdate(localtime=True)
if cc: msg["Cc"] = cc
msg.attach(MIMEText(body, "html" if is_html else "plain", "utf-8"))
if attachments:
for name, data, ctype in attachments:
part = MIMEBase(*ctype.split("/", 1))
part.set_payload(data)
encoders.encode_base64(part)
part.add_header("Content-Disposition", "attachment", filename=name)
msg.attach(part)
recipients = [r.strip() for r in to.split(",")]
if cc: recipients += [r.strip() for r in cc.split(",")]
if bcc: recipients += [r.strip() for r in bcc.split(",")]
raw_bytes = msg.as_bytes()
user_short = username.split("@")[0]
def _do():
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
s = smtplib.SMTP(SMTP_HOST, SMTP_PORT, timeout=15)
s.ehlo()
s.starttls(context=ctx)
s.ehlo()
s.login(user_short, password)
s.sendmail(username, recipients, raw_bytes)
s.quit()
await asyncio.get_event_loop().run_in_executor(None, _do)
return raw_bytes