Bot commit: Добавлен файл email_task.py
This commit is contained in:
parent
dc9d3d48ce
commit
623d452d7d
114
email_task.py
Normal file
114
email_task.py
Normal file
@ -0,0 +1,114 @@
|
||||
import smtplib
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from celery import Celery
|
||||
from config import *
|
||||
from templates import templates
|
||||
import logging
|
||||
from typing import Optional
|
||||
import asyncio
|
||||
from email.utils import formatdate, make_msgid
|
||||
|
||||
|
||||
def build_unsubscribe_url(email: str, token: str, base_url: str) -> str:
|
||||
return f"{base_url}/api/v1/email/unsubscribe?token={token}&email={email}"
|
||||
|
||||
|
||||
async def create_email_message(
|
||||
to_email: str,
|
||||
subject: str,
|
||||
html_content: str,
|
||||
user_id: int = None,
|
||||
):
|
||||
msg = MIMEMultipart("alternative")
|
||||
|
||||
msg['From'] = f"{FROM_NAME} <{FROM_EMAIL}>"
|
||||
msg['To'] = to_email
|
||||
msg['Subject'] = subject
|
||||
msg['Message-ID'] = make_msgid(domain=FROM_EMAIL.split('@')[1])
|
||||
msg['Date'] = formatdate(localtime=True)
|
||||
msg['X-Priority'] = "3"
|
||||
msg['Importance'] = "normal"
|
||||
msg['X-Auto-Response-Suppress'] = "All"
|
||||
|
||||
# token = await create_unsubscribe_token(to_email, user_id)
|
||||
unsubscribe_url = build_unsubscribe_url(to_email, None, FULL_DOMAIN)
|
||||
if to_email != FROM_EMAIL:
|
||||
msg['List-Unsubscribe'] = f"<{unsubscribe_url}>"
|
||||
msg['List-Unsubscribe-Post'] = "List-Unsubscribe=One-Click"
|
||||
|
||||
msg.attach(MIMEText(html_content, 'html'))
|
||||
|
||||
return msg
|
||||
|
||||
def connect(email_server, email_port):
|
||||
server = smtplib.SMTP(email_server, email_port)
|
||||
server.starttls(context=ctx)
|
||||
return server
|
||||
|
||||
|
||||
|
||||
def send_email(
|
||||
to_email: str,
|
||||
html_content: str,
|
||||
subject: str,
|
||||
user_id: Optional[str] = None,
|
||||
) -> bool:
|
||||
msg =asyncio.run(create_email_message(
|
||||
to_email=to_email,
|
||||
subject=subject,
|
||||
html_content=html_content,
|
||||
user_id=user_id,
|
||||
))
|
||||
|
||||
|
||||
try:
|
||||
with connect(EMAIL_SMTP_SERVER, EMAIL_SMTP_PORT) as server:
|
||||
server.login(FROM_EMAIL, EMAIL_PASS)
|
||||
server.send_message(msg)
|
||||
# server.close()
|
||||
|
||||
logging.info(f"Email sent successfully to: {to_email} | Subject: {subject}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logging.error(
|
||||
f"Error sending email to: {to_email}, "
|
||||
f"Subject: {subject}, Error: {str(e)}"
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
celery_app_email = Celery('emails', broker=f'amqps://admin:{RABBITMQ_PASS}@{RABBITMQ_HOST}/email', backend=f'redis://{REDIS_HOST}:{6379 if PROD else 30003}/0', task_track_started=True )
|
||||
|
||||
|
||||
@celery_app_email.task(
|
||||
bind=True,
|
||||
rate_limit='30/m',
|
||||
name='email_task.send_email',
|
||||
retry_backoff=True,
|
||||
retry_backoff_max=600,
|
||||
retry_jitter=True,
|
||||
max_retries=3,
|
||||
soft_time_limit=30,
|
||||
time_limit=45,
|
||||
)
|
||||
def notify(self, to_email: str, data: dict, subject: str = EMAIL_SUBJECT, template: str = 'main.html'):
|
||||
logging.info(f"Отправка email на {to_email} (попытка {self.request.retries + 1})")
|
||||
try:
|
||||
html_content = templates.get_template(f"email/{template}").render({
|
||||
"subject": subject,
|
||||
"data": data
|
||||
})
|
||||
|
||||
ok = send_email(to_email, html_content, subject=subject)
|
||||
if ok:
|
||||
return ok
|
||||
else:
|
||||
raise self.retry(exc=exc)
|
||||
|
||||
except Exception as exc:
|
||||
logging.warning(
|
||||
f"Ошибка при отправке email на {to_email} (попытка {self.request.retries + 1}): {exc}"
|
||||
)
|
||||
raise self.retry(exc=exc)
|
||||
Loading…
Reference in New Issue
Block a user