import os import tempfile from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication from dotenv import load_dotenv from markdown_it import MarkdownIt from datetime import datetime import weasyprint import base64 from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import ( Mail, Attachment, FileContent, FileName, FileType, Disposition) # Tải biến môi trường load_dotenv() # Thông tin email từ biến môi trường SENDER_EMAIL = os.getenv("SENDER_EMAIL") SENDER_APP_PASSWORD = os.getenv("SENDER_APP_PASSWORD") def _markdown_to_html(markdown_string): """Convert Markdown to HTML""" md = MarkdownIt() html_content = md.render(markdown_string) # Format current date current_date = datetime.now().strftime("%d/%m/%Y") # Create complete HTML with CSS for nice formatting full_html = f""" Daily Market Report - {current_date}
Date: {current_date}

Daily Market Report

AI Financial Dashboard

{html_content}
""" return full_html def _generate_pdf_from_markdown(markdown_string): """Generate PDF from Markdown using WeasyPrint""" # Convert markdown to HTML html_content = _markdown_to_html(markdown_string) # Create temporary HTML file with tempfile.NamedTemporaryFile(suffix='.html', delete=False) as temp_html: temp_html_path = temp_html.name temp_html.write(html_content.encode('utf-8')) # Create PDF from HTML try: # Create temporary PDF filename with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as temp_pdf: temp_pdf_path = temp_pdf.name # Generate PDF weasyprint.HTML(filename=temp_html_path).write_pdf(temp_pdf_path) # Read PDF content with open(temp_pdf_path, 'rb') as f: pdf_data = f.read() # Delete temporary files os.unlink(temp_html_path) os.unlink(temp_pdf_path) return pdf_data except Exception as e: # Handle errors and ensure temporary files are deleted if os.path.exists(temp_html_path): os.unlink(temp_html_path) raise e def send_report_via_email(report_markdown: str, recipient_email: str): """ Tạo báo cáo PDF từ markdown và gửi qua email bằng API của SendGrid. """ sendgrid_api_key = os.getenv("SENDGRID_API_KEY") sender_email = os.getenv("SENDER_EMAIL") if not sendgrid_api_key or not sender_email: raise ValueError("Thiếu thông tin SENDGRID_API_KEY hoặc SENDER_EMAIL trong biến môi trường.") # Tạo đối tượng Mail của SendGrid message = Mail( from_email=sender_email, to_emails=recipient_email, subject=f"Bản tin Thị trường Tài chính ngày {datetime.now().strftime('%d-%m-%Y')}", html_content="

Xin chào,

Đây là bản tin thị trường được tạo tự động bởi AI Financial Dashboard.

Vui lòng xem chi tiết trong file PDF đính kèm.

Trân trọng,

" ) try: # Tạo file PDF trong bộ nhớ pdf_data = _generate_pdf_from_markdown(report_markdown) # Mã hóa base64 cho file đính kèm encoded_file = base64.b64encode(pdf_data).decode() # Tạo đối tượng Attachment attached_file = Attachment( FileContent(encoded_file), FileName(f'Ban_tin_Thi_truong_{datetime.now().strftime("%Y%m%d")}.pdf'), FileType('application/pdf'), Disposition('attachment') ) message.attachment = attached_file # Gửi email qua API sg = SendGridAPIClient(sendgrid_api_key) response = sg.send(message) # Kiểm tra response từ SendGrid if 200 <= response.status_code < 300: print(f"Email đã được gửi thành công đến {recipient_email} qua SendGrid.") return True, "Email đã được gửi thành công!" else: print(f"Lỗi khi gửi email qua SendGrid: {response.body}") return False, f"Không thể gửi email. Mã lỗi: {response.status_code}" except Exception as e: import traceback traceback.print_exc() print(f"Lỗi khi gửi email: {e}") return False, f"Đã xảy ra lỗi: {e}"