fix telegram

This commit is contained in:
Claude Agent
2026-02-23 15:12:33 +00:00
parent 6c78fec8a7
commit 8bc567a9c5
426 changed files with 112478 additions and 1 deletions

View File

@@ -0,0 +1,141 @@
"""
Async SMTP Email Service with retry logic and proper error handling
"""
import aiosmtplib
from email.message import EmailMessage
import os
import logging
from typing import Optional
import asyncio
logger = logging.getLogger(__name__)
class EmailService:
"""Async SMTP client for sending authentication codes"""
def __init__(self):
self.smtp_host = os.getenv("SMTP_HOST", "mail.romfast.ro")
self.smtp_port = int(os.getenv("SMTP_PORT", "587"))
self.smtp_user = os.getenv("SMTP_USER")
self.smtp_password = os.getenv("SMTP_PASSWORD")
self.from_email = os.getenv("SMTP_FROM_EMAIL")
self.from_name = os.getenv("SMTP_FROM_NAME", "ROA2WEB")
self.use_tls = os.getenv("SMTP_USE_TLS", "true").lower() == "true"
# Retry configuration
self.max_retries = int(os.getenv("EMAIL_MAX_RETRIES", "3"))
self.retry_delay = float(os.getenv("EMAIL_RETRY_DELAY", "2.0")) # seconds
# Validate required config
if not all([self.smtp_user, self.smtp_password, self.from_email]):
raise ValueError("SMTP configuration incomplete. Check .env file.")
async def send_auth_code(
self,
to_email: str,
code: str,
username: str
) -> bool:
"""
Send authentication code via email with retry logic
Args:
to_email: Recipient email address
code: 6-digit authentication code
username: Oracle username for personalization
Returns:
True if email sent successfully (after retries if needed)
Raises:
No exceptions - returns False on all failures
"""
subject = "Autentificare ROA2WEB"
text_body = self._create_email_template(code, username)
for attempt in range(1, self.max_retries + 1):
try:
await self._send_email(to_email, subject, text_body)
logger.info(
f"[EMAIL] ✅ Sent auth code to {to_email} "
f"(attempt {attempt}/{self.max_retries}) via {self.smtp_host}:{self.smtp_port}"
)
return True
except aiosmtplib.SMTPException as e:
logger.error(
f"[EMAIL] ❌ Attempt {attempt}/{self.max_retries} failed for {to_email}: "
f"{type(e).__name__}: {e}"
)
if attempt < self.max_retries:
# Exponential backoff: 2s, 4s, 8s
delay = self.retry_delay * (2 ** (attempt - 1))
logger.info(f"[EMAIL] Retrying in {delay}s...")
await asyncio.sleep(delay)
else:
logger.error(f"[EMAIL] ❌ All {self.max_retries} attempts failed for {to_email}")
except Exception as e:
logger.error(f"[EMAIL] ❌ Unexpected error on attempt {attempt}/{self.max_retries} for {to_email}: {type(e).__name__}: {e}", exc_info=True)
return False
return False
async def _send_email(
self,
to_email: str,
subject: str,
text_body: str
) -> None:
"""
Internal async SMTP sender (plain text to avoid spam filters)
Raises:
aiosmtplib.SMTPException: On SMTP errors
"""
message = EmailMessage()
message["From"] = f"{self.from_name} <{self.from_email}>"
message["To"] = to_email
message["Subject"] = subject
message.set_content(text_body)
smtp = aiosmtplib.SMTP(
hostname=self.smtp_host,
port=self.smtp_port,
start_tls=self.use_tls,
timeout=30
)
try:
await smtp.connect()
await smtp.login(self.smtp_user, self.smtp_password)
await smtp.send_message(message)
finally:
try:
await smtp.quit()
except:
pass
def _create_email_template(self, code: str, username: str) -> str:
"""Generate plain text email body (HTML blocked by spam filters)"""
return (
f"Codul tau de autentificare ROA2WEB:\n\n"
f" {code}\n\n"
f"Introdu acest cod in Telegram. Expira in 5 minute.\n\n"
f"---\n"
f"Solicitat pentru: {username}\n"
f"Daca nu ai initiat aceasta autentificare, ignora acest email."
)
# Singleton instance
_email_service: Optional[EmailService] = None
def get_email_service() -> EmailService:
"""Get or create singleton email service instance"""
global _email_service
if _email_service is None:
_email_service = EmailService()
return _email_service