Files
sasa-membership/backend/app/services/email_service.py
James Pattinson 93aeda8e83 Basic frontend
2025-11-10 14:51:15 +00:00

251 lines
9.3 KiB
Python

import httpx
from typing import List, Optional
from ..core.config import settings
class EmailService:
"""Email service using SMTP2GO API"""
def __init__(self):
self.api_key = settings.SMTP2GO_API_KEY
self.api_url = settings.SMTP2GO_API_URL
self.from_email = settings.EMAIL_FROM
self.from_name = settings.EMAIL_FROM_NAME
async def send_email(
self,
to_email: str,
subject: str,
html_body: str,
text_body: Optional[str] = None
) -> dict:
"""
Send an email using SMTP2GO API
Args:
to_email: Recipient email address
subject: Email subject
html_body: HTML content of the email
text_body: Plain text content (optional)
Returns:
dict: API response
"""
payload = {
"to": [to_email],
"sender": f"{self.from_name} <{self.from_email}>",
"subject": subject,
"html_body": html_body,
}
if text_body:
payload["text_body"] = text_body
headers = {
"Content-Type": "application/json",
"X-Smtp2go-Api-Key": self.api_key
}
async with httpx.AsyncClient() as client:
response = await client.post(self.api_url, json=payload, headers=headers)
return response.json()
async def send_welcome_email(self, to_email: str, first_name: str) -> dict:
"""Send welcome email to new user"""
subject = f"Welcome to {settings.APP_NAME}!"
html_body = f"""
<html>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<h2 style="color: #0066cc;">Welcome to {settings.APP_NAME}!</h2>
<p>Hello {first_name},</p>
<p>Thank you for registering with us. Your account has been successfully created.</p>
<p>You can now:</p>
<ul>
<li>Browse membership tiers and select one that suits you</li>
<li>View upcoming events and meetings</li>
<li>Access your membership portal</li>
</ul>
<p>If you have any questions, please don't hesitate to contact us.</p>
<p>Best regards,<br>
<strong>{settings.APP_NAME}</strong></p>
</body>
</html>
"""
text_body = f"""
Welcome to {settings.APP_NAME}!
Hello {first_name},
Thank you for registering with us. Your account has been successfully created.
You can now:
- Browse membership tiers and select one that suits you
- View upcoming events and meetings
- Access your membership portal
If you have any questions, please don't hesitate to contact us.
Best regards,
{settings.APP_NAME}
"""
return await self.send_email(to_email, subject, html_body, text_body)
async def send_payment_confirmation(
self,
to_email: str,
first_name: str,
amount: float,
payment_method: str,
membership_tier: str
) -> dict:
"""Send payment confirmation email"""
subject = "Payment Confirmation"
html_body = f"""
<html>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<h2 style="color: #0066cc;">Payment Confirmed!</h2>
<p>Hello {first_name},</p>
<p>We have received your payment. Thank you!</p>
<div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; margin: 20px 0;">
<p style="margin: 5px 0;"><strong>Amount:</strong> £{amount:.2f}</p>
<p style="margin: 5px 0;"><strong>Payment Method:</strong> {payment_method}</p>
<p style="margin: 5px 0;"><strong>Membership Tier:</strong> {membership_tier}</p>
</div>
<p>Your membership is now active. You can access all the benefits associated with your tier.</p>
<p>Best regards,<br>
<strong>{settings.APP_NAME}</strong></p>
</body>
</html>
"""
text_body = f"""
Payment Confirmed!
Hello {first_name},
We have received your payment. Thank you!
Amount: £{amount:.2f}
Payment Method: {payment_method}
Membership Tier: {membership_tier}
Your membership is now active. You can access all the benefits associated with your tier.
Best regards,
{settings.APP_NAME}
"""
return await self.send_email(to_email, subject, html_body, text_body)
async def send_membership_renewal_reminder(
self,
to_email: str,
first_name: str,
expiry_date: str,
membership_tier: str,
annual_fee: float
) -> dict:
"""Send membership renewal reminder"""
subject = "Membership Renewal Reminder"
html_body = f"""
<html>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<h2 style="color: #0066cc;">Membership Renewal Reminder</h2>
<p>Hello {first_name},</p>
<p>This is a friendly reminder that your <strong>{membership_tier}</strong> membership will expire on <strong>{expiry_date}</strong>.</p>
<p>To continue enjoying your membership benefits, please renew your membership.</p>
<div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; margin: 20px 0;">
<p style="margin: 5px 0;"><strong>Membership Tier:</strong> {membership_tier}</p>
<p style="margin: 5px 0;"><strong>Annual Fee:</strong> £{annual_fee:.2f}</p>
<p style="margin: 5px 0;"><strong>Expires:</strong> {expiry_date}</p>
</div>
<p>Please log in to your account to renew your membership.</p>
<p>Best regards,<br>
<strong>{settings.APP_NAME}</strong></p>
</body>
</html>
"""
text_body = f"""
Membership Renewal Reminder
Hello {first_name},
This is a friendly reminder that your {membership_tier} membership will expire on {expiry_date}.
To continue enjoying your membership benefits, please renew your membership.
Membership Tier: {membership_tier}
Annual Fee: £{annual_fee:.2f}
Expires: {expiry_date}
Please log in to your account to renew your membership.
Best regards,
{settings.APP_NAME}
"""
return await self.send_email(to_email, subject, html_body, text_body)
async def send_password_reset_email(
self,
to_email: str,
first_name: str,
reset_token: str
) -> dict:
"""Send password reset email with reset link"""
subject = f"Password Reset - {settings.APP_NAME}"
reset_url = f"{settings.FRONTEND_URL}/reset-password?token={reset_token}"
html_body = f"""
<html>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<h2 style="color: #0066cc;">Password Reset Request</h2>
<p>Hello {first_name},</p>
<p>You have requested to reset your password for your {settings.APP_NAME} account.</p>
<p>Please click the button below to reset your password:</p>
<div style="text-align: center; margin: 30px 0;">
<a href="{reset_url}" style="background-color: #0066cc; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;">Reset Password</a>
</div>
<p>If the button doesn't work, you can copy and paste this link into your browser:</p>
<p style="word-break: break-all; background-color: #f5f5f5; padding: 10px; border-radius: 3px;">{reset_url}</p>
<p><strong>This link will expire in 1 hour.</strong></p>
<p>If you didn't request this password reset, please ignore this email. Your password will remain unchanged.</p>
<p>For security reasons, please don't share this email with anyone.</p>
<p>Best regards,<br>
<strong>{settings.APP_NAME}</strong></p>
</body>
</html>
"""
text_body = f"""
Password Reset Request
Hello {first_name},
You have requested to reset your password for your {settings.APP_NAME} account.
Please use this link to reset your password: {reset_url}
This link will expire in 1 hour.
If you didn't request this password reset, please ignore this email. Your password will remain unchanged.
For security reasons, please don't share this email with anyone.
Best regards,
{settings.APP_NAME}
"""
return await self.send_email(to_email, subject, html_body, text_body)
# Create a singleton instance
email_service = EmailService()