import os
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage # Added for embedding images
from dotenv import load_dotenv
import asyncio
from utils.url_utils import get_frontend_url
from utils.config_loader import get_setting
load_dotenv()
# GMAIL_USER and GMAIL_PASS are now fetched dynamically inside functions
# --- Base Email Template with Beautiful Design ---
EMAIL_BASE_TEMPLATE = """
"""
# --- Account Verification Email ---
ACCOUNT_VERIFICATION_EMAIL_SUBJECT = "Verify your account - MediSync"
ACCOUNT_VERIFICATION_EMAIL_CONTENT = """
Welcome, {full_name}! ๐
Thank you for registering with MediSync, your AI-Powered Medicine Dispenser System.
To get started and access all the amazing features, please verify your email address by clicking the button below:
If the button doesn't work, copy and paste this link into your browser:
{verification_link}
If you didn't create this account, you can safely ignore this email.
๐ Security Tip
Never share your verification link with anyone. MediSync will never ask for your password via email.
"""
# --- Medicine Added Email ---
MEDICINE_ADDED_EMAIL_SUBJECT = "โ Medicine Added to Your Schedule"
MEDICINE_ADDED_EMAIL_CONTENT = """
Hello, {full_name}! ๐
Great news! Your medicine has been successfully added to your schedule.
๐ Medicine Details
๐ Medicine: {medicine_name}
๐ Dosage: {dosage}
โฐ Scheduled Time: {time}
You will receive reminders before each scheduled dose. Stay on track with your health goals! ๐ฏ
"""
# --- Medicine Reminder Email ---
MEDICINE_REMINDER_EMAIL_SUBJECT = "โฐ Medicine Reminder - Time to Take Your Dose"
MEDICINE_REMINDER_EMAIL_CONTENT = """
Reminder for {full_name} โฐ
It's time to take your medicine! Don't forget your health routine.
๐ Dose Information
๐ Medicine: {medicine_name}
๐ Dosage: {dosage}
โฐ Time: {time}
Please take your medicine as prescribed. Your health is our priority! ๐
๐ก Tip: Set up your dispenser for automatic dispensing to never miss a dose!
"""
# --- Medicine Missed Email ---
MEDICINE_MISSED_EMAIL_SUBJECT = "โ ๏ธ ALERT: Missed Medicine Notification"
MEDICINE_MISSED_EMAIL_CONTENT = """
Important Alert, {full_name} โ ๏ธ
โ ๏ธ Missed Dose Alert
You missed your scheduled medicine dose. Please take it as soon as possible.
๐ Medicine: {medicine_name}
๐ Dosage: {dosage}
โฐ Scheduled Time: {time}
If you have any concerns or questions about your medication schedule, please contact your healthcare provider immediately.
๐ Need Help?
Contact your doctor or our support team if you need assistance with your medication schedule.
"""
# --- Medicine Updated Email ---
MEDICINE_UPDATED_EMAIL_SUBJECT = "๐ Medicine Schedule Updated"
MEDICINE_UPDATED_EMAIL_CONTENT = """
Update Notification, {full_name} ๐
Your medicine schedule has been updated successfully.
๐ Updated Medicine Details
๐ Medicine: {medicine_name}
๐ Dosage: {dosage}
โฐ New Time: {time}
If you didn't request this change, please contact our support team immediately for assistance.
๐ Security Notice
If this update was unauthorized, please contact support immediately at support@MediSync.com
"""
# --- Password Reset Email ---
PASSWORD_RESET_EMAIL_SUBJECT = "๐ Reset Your Password - MediSync"
PASSWORD_RESET_EMAIL_CONTENT = """
Password Reset Request, {full_name} ๐
We received a request to reset your password for your MediSync account.
Click the button below to set a new password:
If you didn't request a password reset, you can safely ignore this email. Your password will remain unchanged.
โฑ๏ธ Link Expires Soon
This password reset link will expire in 1 hour for security reasons.
"""
# --- Pre-order Confirmation Email ---
PREORDER_CONFIRMATION_EMAIL_SUBJECT = "๐ Pre-order Confirmed - MediSync"
PREORDER_CONFIRMATION_EMAIL_CONTENT = """
Thank You, {full_name}! ๐
We've received your pre-order request for the MediSync AI-Powered Medicine Dispenser!
โ What Happens Next?
Our team will review your request and contact you within 24-48 hours with next steps.
You're one step closer to revolutionizing your medication management! ๐
๐ฆ Product Features
โ Automated dispensing with smart scheduling
โ AI health assistant for medication questions
โ Multi-slot system for up to 8 medications
โ Smart reminders via SMS & Email
Have questions? Feel free to reply to this email anytime!
"""
# --- Pre-order Notification to Owner ---
PREORDER_NOTIFICATION_OWNER_SUBJECT = "๐ New Pre-order Received"
PREORDER_NOTIFICATION_OWNER_CONTENT = """
New Pre-order Alert! ๐ฏ
A new customer has submitted a pre-order request for MediSync.
๐ค Customer Information
๐ค Name: {name}
๐ Phone: {phone}
๐ง Email: {gmail}
๐ฌ Message: {message}
Please follow up with the customer within 24-48 hours.
"""
# --- Contact Form Confirmation Email ---
CONTACT_CONFIRMATION_EMAIL_SUBJECT = "โ We've Received Your Message - MediSync"
CONTACT_CONFIRMATION_EMAIL_CONTENT = """
Thank You, {name}! ๐ฌ
We've received your message and appreciate you reaching out to MediSync.
๐ Message Details
๐ง Subject: {subject}
๐ฌ Your Message: {message}
Our team will review your inquiry and get back to you within 24-48 hours.
โฑ๏ธ Response Time
We typically respond to all inquiries within 1-2 business days.
If you have any urgent matters, please call us at +1 (234) 567-8900.
"""
# --- Contact Form Notification to Owner ---
CONTACT_NOTIFICATION_OWNER_SUBJECT = "๐ฌ New Contact Form Submission"
CONTACT_NOTIFICATION_OWNER_CONTENT = """
New Contact Form Submission! ๐ฌ
A visitor has submitted a contact form on the MediSync website.
๐ค Contact Information
๐ค Name: {name}
๐ง Email: {email}
๐ Subject: {subject}
๐ฌ Message: {message}
Please respond to this inquiry within 24-48 hours.
"""
def _send_email(to_email: str, subject: str, html: str):
GMAIL_USER = get_setting("GMAIL_USER")
GMAIL_PASS = get_setting("GMAIL_PASS")
if not GMAIL_USER or not GMAIL_PASS:
print("Gmail credentials not set.")
# We don't raise exception to avoid crashing the app if credentials are missing,
# but normally we should. However, since this is async background task usually, printing is safe.
# But let's log and return.
return
# Create the root message and fill in the from, to, and subject headers
msg = MIMEMultipart("related") # Changed to 'related' to embed images
msg["Subject"] = subject
msg["From"] = GMAIL_USER
msg["To"] = to_email
# Attach the HTML part
msg.attach(MIMEText(html, "html"))
# Attach the image
image_path = "mediflow-logo-trans.png"
try:
with open(image_path, "rb") as img_file:
img_data = img_file.read()
img = MIMEImage(img_data, name=os.path.basename(image_path))
img.add_header("Content-ID", "") # Content-ID for referencing in HTML
msg.attach(img)
except FileNotFoundError:
print(f"Warning: Logo image not found at {image_path}. Email will be sent without logo.")
except Exception as e:
print(f"Error embedding logo image: {e}")
try:
with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
server.login(GMAIL_USER, GMAIL_PASS)
server.sendmail(GMAIL_USER, to_email, msg.as_string())
except Exception as e:
print(f"Failed to send email: {e}")
raise
async def send_verification_email(to_email: str, full_name: str, verification_link: str):
content = ACCOUNT_VERIFICATION_EMAIL_CONTENT.format(
full_name=full_name,
verification_link=verification_link
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, ACCOUNT_VERIFICATION_EMAIL_SUBJECT, html)
async def send_password_reset_email(to_email: str, full_name: str, reset_link: str):
content = PASSWORD_RESET_EMAIL_CONTENT.format(
full_name=full_name,
reset_link=reset_link
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, PASSWORD_RESET_EMAIL_SUBJECT, html)
async def send_preorder_confirmation_email(to_email: str, full_name: str):
content = PREORDER_CONFIRMATION_EMAIL_CONTENT.format(full_name=full_name)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, PREORDER_CONFIRMATION_EMAIL_SUBJECT, html)
async def send_preorder_notification_to_owner(name: str, phone: str, gmail: str, message: str):
frontend_url = get_frontend_url()
content = PREORDER_NOTIFICATION_OWNER_CONTENT.format(
name=name,
phone=phone,
gmail=gmail,
message=message or "No message provided",
frontend_url=frontend_url
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(
None,
_send_email,
"birdskeener@gmail.com",
PREORDER_NOTIFICATION_OWNER_SUBJECT,
html
)
async def send_medicine_added_email(to_email: str, full_name: str, medicine_name: str, dosage: str, time: str):
frontend_url = get_frontend_url()
content = MEDICINE_ADDED_EMAIL_CONTENT.format(
full_name=full_name,
medicine_name=medicine_name,
dosage=dosage,
time=time,
frontend_url=frontend_url
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, MEDICINE_ADDED_EMAIL_SUBJECT, html)
async def send_medicine_reminder_email(to_email: str, full_name: str, medicine_name: str, dosage: str, time: str):
frontend_url = get_frontend_url()
content = MEDICINE_REMINDER_EMAIL_CONTENT.format(
full_name=full_name,
medicine_name=medicine_name,
dosage=dosage,
time=time,
frontend_url=frontend_url
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, MEDICINE_REMINDER_EMAIL_SUBJECT, html)
async def send_medicine_missed_email(to_email: str, full_name: str, medicine_name: str, dosage: str, time: str):
frontend_url = get_frontend_url()
content = MEDICINE_MISSED_EMAIL_CONTENT.format(
full_name=full_name,
medicine_name=medicine_name,
dosage=dosage,
time=time,
frontend_url=frontend_url
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, MEDICINE_MISSED_EMAIL_SUBJECT, html)
async def send_medicine_updated_email(to_email: str, full_name: str, medicine_name: str, dosage: str, time: str):
frontend_url = get_frontend_url()
content = MEDICINE_UPDATED_EMAIL_CONTENT.format(
full_name=full_name,
medicine_name=medicine_name,
dosage=dosage,
time=time,
frontend_url=frontend_url
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, MEDICINE_UPDATED_EMAIL_SUBJECT, html)
async def send_contact_confirmation_email(to_email: str, name: str, subject: str, message: str):
content = CONTACT_CONFIRMATION_EMAIL_CONTENT.format(
name=name,
subject=subject,
message=message
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, CONTACT_CONFIRMATION_EMAIL_SUBJECT, html)
async def send_contact_notification_to_owner(name: str, email: str, subject: str, message: str):
frontend_url = get_frontend_url()
content = CONTACT_NOTIFICATION_OWNER_CONTENT.format(
name=name,
email=email,
subject=subject,
message=message,
frontend_url=frontend_url
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(
None,
_send_email,
"birdskeener@gmail.com",
CONTACT_NOTIFICATION_OWNER_SUBJECT,
html
)
# --- Subscription Approval Email ---
SUBSCRIPTION_APPROVAL_EMAIL_SUBJECT = "๐ Subscription Approved - MediSync"
SUBSCRIPTION_APPROVAL_EMAIL_CONTENT = """
Congratulations, {full_name}! ๐
Your subscription to MediSync has been approved successfully!
โ Subscription Details
๐
Plan: {plan}
โณ Valid Until: {end_date}
โ
Status: Active
You now have full access to all premium features. Thank you for choosing MediSync!
"""
async def send_subscription_approval_email(to_email: str, full_name: str, plan: str, end_date: str):
frontend_url = get_frontend_url()
content = SUBSCRIPTION_APPROVAL_EMAIL_CONTENT.format(
full_name=full_name,
plan=plan.capitalize(),
end_date=end_date,
frontend_url=frontend_url
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, SUBSCRIPTION_APPROVAL_EMAIL_SUBJECT, html)
# --- Payment Success Email ---
PAYMENT_SUCCESS_EMAIL_SUBJECT = "โ
Payment Successful - MediSync"
PAYMENT_SUCCESS_EMAIL_CONTENT = """
Payment Received, {full_name}! โ
Thank you for your payment. Your transaction was successful and your subscription is now active!
๐งพ Transaction Receipt
๐ณ Transaction ID: {transaction_id}
๐
Plan: {plan_name}
๐ฐ Amount: {amount}
๐๏ธ Date: {date}
You can now enjoy all the benefits of your {plan_name}.
A copy of this receipt has been saved to your account.
"""
async def send_payment_success_email(to_email: str, full_name: str, transaction_id: str, plan_name: str, amount: str, date: str):
frontend_url = get_frontend_url()
content = PAYMENT_SUCCESS_EMAIL_CONTENT.format(
full_name=full_name,
transaction_id=transaction_id,
plan_name=plan_name,
amount=amount,
date=date,
frontend_url=frontend_url
)
html = EMAIL_BASE_TEMPLATE.format(content=content)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, _send_email, to_email, PAYMENT_SUCCESS_EMAIL_SUBJECT, html)