"""
Email sending utilities with support for Yandex SMTP
"""
import smtplib
import logging
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from typing import Optional
from config import settings
logger = logging.getLogger(__name__)
def generate_verification_email(code: str) -> str:
"""Generate HTML email with verification code"""
return f"""
Код подтверждения
Ваш код для регистрации в Nakama:
{code}
Код действителен в течение 15 минут.
"""
async def send_email_smtp(to: str, subject: str, html: str, text: Optional[str] = None):
"""Send email via SMTP (Yandex, Gmail, etc.)"""
try:
# Create message
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = settings.EMAIL_FROM
msg['To'] = to
# Add text and HTML parts
if text:
msg.attach(MIMEText(text, 'plain', 'utf-8'))
msg.attach(MIMEText(html, 'html', 'utf-8'))
# Connect and send
if settings.EMAIL_PROVIDER == 'yandex':
logger.info(f"[Email] Отправка через Yandex SMTP: {settings.YANDEX_SMTP_HOST}:{settings.YANDEX_SMTP_PORT}")
if not settings.YANDEX_SMTP_USER or not settings.YANDEX_SMTP_PASSWORD:
raise ValueError("YANDEX_SMTP_USER и YANDEX_SMTP_PASSWORD должны быть установлены в .env")
# Используем SMTP_SSL для порта 465
if settings.YANDEX_SMTP_PORT == 465:
server = smtplib.SMTP_SSL(settings.YANDEX_SMTP_HOST, settings.YANDEX_SMTP_PORT)
else:
server = smtplib.SMTP(settings.YANDEX_SMTP_HOST, settings.YANDEX_SMTP_PORT)
if settings.YANDEX_SMTP_SECURE:
server.starttls()
server.login(settings.YANDEX_SMTP_USER, settings.YANDEX_SMTP_PASSWORD)
server.send_message(msg)
server.quit()
logger.info(f"✅ Email отправлен на {to}")
return {"success": True, "to": to}
else:
raise ValueError(f"Email provider '{settings.EMAIL_PROVIDER}' не поддерживается. Используйте 'yandex'")
except Exception as e:
logger.error(f"❌ Ошибка отправки email: {e}")
# More informative error messages
if "Authentication" in str(e) or "credentials" in str(e).lower():
raise ValueError(
"Неверные учетные данные SMTP. Для Yandex используйте пароль приложения "
"(https://id.yandex.ru/security), а не основной пароль аккаунта."
)
elif "Connection" in str(e):
raise ValueError(
f"Не удалось подключиться к SMTP серверу {settings.YANDEX_SMTP_HOST}:{settings.YANDEX_SMTP_PORT}"
)
raise
async def send_verification_code(email: str, code: str):
"""Send verification code to email"""
subject = "Код подтверждения регистрации - Nakama"
html = generate_verification_email(code)
text = f"Ваш код подтверждения: {code}. Код действителен 15 минут."
return await send_email_smtp(email, subject, html, text)
async def send_admin_confirmation_code(code: str, action: str, user_info: dict):
"""Send admin confirmation code to owner email"""
action_text = "добавления админа" if action == "add" else "удаления админа"
subject = f"Код подтверждения {action_text} - Nakama Moderation"
html = f"""
Подтверждение {action_text}
Пользователь: @{user_info.get('username', 'не указан')} ({user_info.get('firstName', '')})
{f"
Номер админа: {user_info['adminNumber']}
" if 'adminNumber' in user_info else ''}
Код подтверждения:
{code}
Код действителен в течение 5 минут.
"""
text = f"""Код подтверждения {action_text}: {code}
Пользователь: @{user_info.get('username', 'не указан')}
Код действителен 5 минут."""
return await send_email_smtp(settings.OWNER_EMAIL, subject, html, text)