Automated Action ef749e4878 Implement WhatsApp Message Analytics Service
- 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
2025-05-22 13:29:12 +00:00

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