jira-ai-fixer/app/services/email.py

95 lines
4.1 KiB
Python

"""Email service using Resend."""
import httpx
from typing import Optional, List
from app.core.config import settings
class EmailService:
RESEND_API = "https://api.resend.com/emails"
@classmethod
async def send(
cls,
to: List[str],
subject: str,
html: str,
text: Optional[str] = None
) -> bool:
if not settings.RESEND_API_KEY:
return False
async with httpx.AsyncClient() as client:
try:
response = await client.post(
cls.RESEND_API,
headers={
"Authorization": f"Bearer {settings.RESEND_API_KEY}",
"Content-Type": "application/json"
},
json={
"from": settings.EMAIL_FROM,
"to": to,
"subject": subject,
"html": html,
"text": text
}
)
return response.status_code == 200
except Exception:
return False
@classmethod
async def send_welcome(cls, email: str, name: str, org_name: str):
html = f"""
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<h1 style="color: #4F46E5;">Welcome to JIRA AI Fixer! 🤖</h1>
<p>Hi {name},</p>
<p>You've been added to <strong>{org_name}</strong>.</p>
<p>JIRA AI Fixer automatically analyzes support issues and suggests code fixes using AI.</p>
<div style="margin: 30px 0;">
<a href="https://jira-fixer.startdata.com.br"
style="background: #4F46E5; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px;">
Get Started
</a>
</div>
<p style="color: #666;">— The JIRA AI Fixer Team</p>
</div>
"""
await cls.send([email], f"Welcome to {org_name} on JIRA AI Fixer", html)
@classmethod
async def send_analysis_complete(cls, email: str, issue_key: str, confidence: float, pr_url: Optional[str]):
html = f"""
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<h1 style="color: #10B981;">Analysis Complete ✅</h1>
<p>Issue <strong>{issue_key}</strong> has been analyzed.</p>
<div style="background: #F3F4F6; padding: 20px; border-radius: 8px; margin: 20px 0;">
<p><strong>Confidence:</strong> {confidence:.0%}</p>
{f'<p><strong>Pull Request:</strong> <a href="{pr_url}">{pr_url}</a></p>' if pr_url else ''}
</div>
<a href="https://jira-fixer.startdata.com.br"
style="background: #4F46E5; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px;">
View Details
</a>
</div>
"""
await cls.send([email], f"Analysis Complete: {issue_key}", html)
@classmethod
async def send_weekly_digest(cls, email: str, org_name: str, stats: dict):
html = f"""
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<h1 style="color: #4F46E5;">Weekly Digest 📊</h1>
<p>Here's what happened in <strong>{org_name}</strong> this week:</p>
<div style="background: #F3F4F6; padding: 20px; border-radius: 8px; margin: 20px 0;">
<p><strong>Issues Analyzed:</strong> {stats.get('analyzed', 0)}</p>
<p><strong>PRs Created:</strong> {stats.get('prs', 0)}</p>
<p><strong>Avg Confidence:</strong> {stats.get('confidence', 0):.0%}</p>
</div>
<a href="https://jira-fixer.startdata.com.br/reports"
style="background: #4F46E5; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px;">
View Full Report
</a>
</div>
"""
await cls.send([email], f"Weekly Digest: {org_name}", html)