
- Set up FastAPI application structure - Implement SQLite database with SQLAlchemy - Create WhatsApp webhook endpoints - Implement message storage and analysis - Integrate Gemini 2.5 Pro for message analysis - Add email delivery of insights - Configure APScheduler for weekend analysis - Add linting with Ruff
185 lines
5.0 KiB
Python
185 lines
5.0 KiB
Python
"""
|
|
Service for sending emails.
|
|
"""
|
|
import logging
|
|
import smtplib
|
|
from datetime import datetime
|
|
from email.mime.multipart import MIMEMultipart
|
|
from email.mime.text import MIMEText
|
|
|
|
from jinja2 import Template
|
|
|
|
from app.core.config import settings
|
|
|
|
# Configure logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Email template for analysis results
|
|
ANALYSIS_EMAIL_TEMPLATE = """
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>WhatsApp Message Analysis</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
line-height: 1.6;
|
|
color: #333;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
}
|
|
.header {
|
|
background-color: #25D366;
|
|
color: white;
|
|
padding: 15px;
|
|
border-radius: 5px;
|
|
margin-bottom: 20px;
|
|
text-align: center;
|
|
}
|
|
.content {
|
|
padding: 20px;
|
|
background-color: #f9f9f9;
|
|
border-radius: 5px;
|
|
}
|
|
.footer {
|
|
margin-top: 20px;
|
|
font-size: 12px;
|
|
color: #777;
|
|
text-align: center;
|
|
}
|
|
h1, h2, h3 {
|
|
color: #075E54;
|
|
}
|
|
.date-range {
|
|
color: #666;
|
|
font-style: italic;
|
|
margin-bottom: 20px;
|
|
}
|
|
pre {
|
|
white-space: pre-wrap;
|
|
background-color: #f0f0f0;
|
|
padding: 10px;
|
|
border-radius: 3px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<h1>WhatsApp Message Analysis</h1>
|
|
</div>
|
|
<div class="content">
|
|
<div class="date-range">
|
|
<p>Analysis for messages from {{ start_date.strftime('%Y-%m-%d') }} to {{ end_date.strftime('%Y-%m-%d') }}</p>
|
|
</div>
|
|
|
|
<div class="analysis">
|
|
{{ analysis_text | safe }}
|
|
</div>
|
|
</div>
|
|
<div class="footer">
|
|
<p>This is an automated analysis generated by WhatsApp Message Analytics Service.</p>
|
|
<p>© {{ current_year }} WhatsApp Message Analytics Service</p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
|
|
async def send_email(
|
|
recipients: list[str],
|
|
subject: str,
|
|
html_content: str,
|
|
from_email: str | None = None,
|
|
from_name: str | None = None,
|
|
) -> bool:
|
|
"""
|
|
Send an email.
|
|
|
|
Args:
|
|
recipients: List of email addresses to send to
|
|
subject: Email subject
|
|
html_content: HTML content of the email
|
|
from_email: Sender email address (defaults to settings.EMAILS_FROM_EMAIL)
|
|
from_name: Sender name (defaults to settings.EMAILS_FROM_NAME)
|
|
|
|
Returns:
|
|
True if the email was sent successfully, False otherwise
|
|
"""
|
|
try:
|
|
# Use default sender details if not provided
|
|
sender_email = from_email or settings.EMAILS_FROM_EMAIL
|
|
sender_name = from_name or settings.EMAILS_FROM_NAME
|
|
|
|
# Create message
|
|
message = MIMEMultipart()
|
|
message["From"] = f"{sender_name} <{sender_email}>"
|
|
message["To"] = ", ".join(recipients)
|
|
message["Subject"] = subject
|
|
|
|
# Attach HTML content
|
|
message.attach(MIMEText(html_content, "html"))
|
|
|
|
# Connect to SMTP server and send email
|
|
with smtplib.SMTP(settings.SMTP_HOST, settings.SMTP_PORT) as server:
|
|
if settings.SMTP_TLS:
|
|
server.starttls()
|
|
if settings.SMTP_USER and settings.SMTP_PASSWORD:
|
|
server.login(settings.SMTP_USER, settings.SMTP_PASSWORD)
|
|
server.send_message(message)
|
|
|
|
logger.info(f"Email sent successfully to {len(recipients)} recipients")
|
|
return True
|
|
|
|
except Exception as e:
|
|
logger.exception(f"Failed to send email: {str(e)}")
|
|
return False
|
|
|
|
|
|
async def send_analysis_email(
|
|
subject: str,
|
|
analysis_text: str,
|
|
start_date: datetime,
|
|
end_date: datetime,
|
|
) -> bool:
|
|
"""
|
|
Send an email with message analysis.
|
|
|
|
Args:
|
|
subject: Email subject
|
|
analysis_text: Text of the analysis
|
|
start_date: Start date of the analysis period
|
|
end_date: End date of the analysis period
|
|
|
|
Returns:
|
|
True if the email was sent successfully, False otherwise
|
|
"""
|
|
try:
|
|
# Get recipients from settings
|
|
recipients = settings.EMAIL_RECIPIENTS
|
|
if not recipients:
|
|
logger.error("No email recipients configured")
|
|
return False
|
|
|
|
# Format HTML content using template
|
|
template = Template(ANALYSIS_EMAIL_TEMPLATE)
|
|
html_content = template.render(
|
|
analysis_text=analysis_text,
|
|
start_date=start_date,
|
|
end_date=end_date,
|
|
current_year=datetime.now().year,
|
|
)
|
|
|
|
# Send email
|
|
return await send_email(
|
|
recipients=recipients,
|
|
subject=subject,
|
|
html_content=html_content,
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.exception(f"Error sending analysis email: {str(e)}")
|
|
return False
|