import logging import smtplib from email.message import EmailMessage from app.core.config import settings logger = logging.getLogger(__name__) def _send_email(to_email: str, subject: str, body: str) -> bool: if not settings.smtp_host or not settings.smtp_from_email: logger.warning("SMTP is not configured. Cannot send email to %s", to_email) return False message = EmailMessage() message["Subject"] = subject message["From"] = f"{settings.smtp_from_name} <{settings.smtp_from_email}>" message["To"] = to_email message.set_content(body) try: with smtplib.SMTP(settings.smtp_host, settings.smtp_port, timeout=15) as server: server.ehlo() if settings.smtp_use_tls: server.starttls() server.ehlo() if settings.smtp_username and settings.smtp_password: server.login(settings.smtp_username, settings.smtp_password) server.send_message(message) return True except Exception: logger.exception("Failed to send email to %s", to_email) return False def send_password_reset_email(to_email: str, reset_url: str) -> bool: subject = "[Run The Shape] 비밀번호 재설정 안내" body = ( "비밀번호 재설정을 요청하셨습니다.\n\n" "아래 링크를 눌러 새 비밀번호를 설정해주세요.\n" f"{reset_url}\n\n" "요청하지 않으셨다면 이 메일을 무시하셔도 됩니다." ) return _send_email(to_email, subject, body) def send_email_verification_code(to_email: str, code: str) -> bool: subject = "[Run The Shape] 회원가입 이메일 인증번호" body = ( "Run The Shape 회원가입 인증번호 안내입니다.\n\n" f"인증번호: {code}\n\n" "인증번호는 10분 동안 유효합니다.\n" "요청하지 않으셨다면 이 메일을 무시하셔도 됩니다." ) return _send_email(to_email, subject, body)