Hi there,
{{ inviter_name }} has invited you to join {{ org_name }} on the Accessible Video Platform.
Or copy this link: {{ accept_url }}
This invitation expires on {{ expires_at }}.
from datetime import datetime from jinja2 import Template from ..core.config import settings from ..core.logging import get_logger logger = get_logger(__name__) class EmailService: """Sends email via Mailgun REST API (httpx, async-safe).""" @property def _configured(self) -> bool: return bool(settings.mailgun_api_key and settings.mailgun_domain) async def _send(self, to_email: str, subject: str, html: str) -> bool: if not self._configured: logger.warning("Mailgun not configured — email skipped") return False try: import httpx url = f"https://api.mailgun.net/v3/{settings.mailgun_domain}/messages" async with httpx.AsyncClient(timeout=15) as client: response = await client.post( url, auth=("api", settings.mailgun_api_key), data={ "from": f"Accessible Video Platform <{settings.mailgun_from}>", "to": to_email, "subject": subject, "html": html, }, ) if response.status_code in (200, 202): logger.info(f"Email sent to {to_email}: {subject}") return True logger.error(f"Mailgun error {response.status_code}: {response.text}") return False except Exception as e: logger.error(f"Email sending failed: {e}") return False async def send_invitation_email( self, to_email: str, inviter_name: str, org_name: str, accept_url: str, expires_at: datetime, ) -> bool: html = Template("""
Hi there,
{{ inviter_name }} has invited you to join {{ org_name }} on the Accessible Video Platform.
Or copy this link: {{ accept_url }}
This invitation expires on {{ expires_at }}.
Hi {{ full_name }},
Your account has been set up and you now have access to {{ org_name }} on the Accessible Video Platform.
If you have any questions, reach out to your organization admin.
Hi {{ full_name }},
Click below to reset your password. This link is valid for 1 hour.
If you didn't request this, you can ignore this email.
Great news! Your video accessibility assets have been processed and are ready for download.
{% for language, files in download_links.items() %}Important: These download links will expire in 24 hours for security purposes.
If you need assistance or have questions about your accessible video assets, please don't hesitate to contact our support team.