Files
sasa-membership/backend/app/services/email_service.py
James Pattinson 43b13ef52d Adding more shit
2025-11-10 15:42:09 +00:00

329 lines
13 KiB
Python

import httpx
from typing import List, Optional
from datetime import datetime
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_activation_email(
self,
to_email: str,
first_name: str,
membership_tier: str,
annual_fee: float,
payment_amount: float,
payment_method: str,
renewal_date: str
) -> dict:
"""Send membership activation email with payment details and renewal date"""
subject = f"Your {settings.APP_NAME} Membership is Now Active!"
html_body = f"""
<html>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<h2 style="color: #28a745;">Welcome to {settings.APP_NAME}!</h2>
<p>Hello {first_name},</p>
<p>Great news! Your membership has been successfully activated. You now have full access to all the benefits of your membership tier.</p>
<div style="background-color: #f8f9fa; padding: 20px; border-radius: 8px; margin: 20px 0; border-left: 4px solid #28a745;">
<h3 style="margin-top: 0; color: #28a745;">Membership Details</h3>
<p style="margin: 8px 0;"><strong>Membership Tier:</strong> {membership_tier}</p>
<p style="margin: 8px 0;"><strong>Annual Fee:</strong> £{annual_fee:.2f}</p>
<p style="margin: 8px 0;"><strong>Next Renewal Date:</strong> {renewal_date}</p>
</div>
<div style="background-color: #e9ecef; padding: 20px; border-radius: 8px; margin: 20px 0;">
<h3 style="margin-top: 0; color: #495057;">Payment Information</h3>
<p style="margin: 8px 0;"><strong>Amount Paid:</strong> £{payment_amount:.2f}</p>
<p style="margin: 8px 0;"><strong>Payment Method:</strong> {payment_method}</p>
<p style="margin: 8px 0;"><strong>Payment Date:</strong> {datetime.now().strftime('%d %B %Y')}</p>
</div>
<p>Your membership will automatically renew on <strong>{renewal_date}</strong> unless you choose to cancel it. You can manage your membership settings in your account dashboard.</p>
<p>If you have any questions about your membership or need assistance, please don't hesitate to contact us.</p>
<p>Welcome to the {settings.APP_NAME} community!</p>
<p>Best regards,<br>
<strong>{settings.APP_NAME} Team</strong></p>
</body>
</html>
"""
text_body = f"""
Welcome to {settings.APP_NAME}!
Hello {first_name},
Great news! Your membership has been successfully activated. You now have full access to all the benefits of your membership tier.
MEMBERSHIP DETAILS
------------------
Membership Tier: {membership_tier}
Annual Fee: £{annual_fee:.2f}
Next Renewal Date: {renewal_date}
PAYMENT INFORMATION
-------------------
Amount Paid: £{payment_amount:.2f}
Payment Method: {payment_method}
Payment Date: {datetime.now().strftime('%d %B %Y')}
Your membership will automatically renew on {renewal_date} unless you choose to cancel it. You can manage your membership settings in your account dashboard.
If you have any questions about your membership or need assistance, please don't hesitate to contact us.
Welcome to the {settings.APP_NAME} community!
Best regards,
{settings.APP_NAME} Team
"""
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()