From 225d720e8a26e690a34db2a8da18555720c06823 Mon Sep 17 00:00:00 2001 From: "yves.gugger" Date: Mon, 8 Dec 2025 15:41:05 +0100 Subject: [PATCH] feat: Configure all email services to use Zoho Mail Email Service (email_service.py): - Updated SMTP defaults for Zoho (smtp.zoho.eu:465) - Added SSL support (use_ssl parameter) for port 465 - Updated send_email() to handle both SSL (port 465) and STARTTLS (port 587) - Changed default sender from noreply@pounce.ch to hello@pounce.ch - Updated contact email to hello@pounce.ch Configuration Files: - env.example: Complete Zoho configuration with SSL - env.example.txt: Updated with Zoho defaults - README.md: Updated email setup documentation with Zoho instructions Zoho Configuration: - Host: smtp.zoho.eu - Port: 465 (SSL) - SSL: true, TLS: false - Sender: hello@pounce.ch Supported Email Types: - Domain availability alerts - Price change notifications - Subscription confirmations - Password reset - Email verification - Contact form (send + confirmation) - Newsletter welcome - Weekly digests --- README.md | 37 ++++++++++++++++------- backend/app/services/email_service.py | 42 ++++++++++++++++++--------- backend/env.example | 42 +++++++++++++-------------- backend/env.example.txt | 22 ++++++++------ 4 files changed, 88 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 5a93079..0d4b112 100644 --- a/README.md +++ b/README.md @@ -407,13 +407,15 @@ This ensures identical prices on: | `SITE_URL` | Frontend URL (for email links) | `http://localhost:3000` | | `REQUIRE_EMAIL_VERIFICATION` | Require email verification | `false` | | `SCHEDULER_CHECK_INTERVAL_HOURS` | Domain check interval | `24` | -| **SMTP Settings** | | | -| `SMTP_HOST` | Email server host | Optional | -| `SMTP_PORT` | Email server port | `587` | -| `SMTP_USER` | Email username | Optional | -| `SMTP_PASSWORD` | Email password | Optional | -| `SMTP_FROM_EMAIL` | Sender email | `noreply@pounce.ch` | -| `CONTACT_EMAIL` | Contact form recipient | `support@pounce.ch` | +| **SMTP Settings (Zoho)** | | | +| `SMTP_HOST` | Email server host | `smtp.zoho.eu` | +| `SMTP_PORT` | Email server port | `465` | +| `SMTP_USER` | Email username | `hello@pounce.ch` | +| `SMTP_PASSWORD` | Email password | **Required** | +| `SMTP_FROM_EMAIL` | Sender email | `hello@pounce.ch` | +| `SMTP_USE_SSL` | Use SSL (port 465) | `true` | +| `SMTP_USE_TLS` | Use STARTTLS (port 587) | `false` | +| `CONTACT_EMAIL` | Contact form recipient | `hello@pounce.ch` | | **Stripe Settings** | | | | `STRIPE_SECRET_KEY` | Stripe API secret key | Optional | | `STRIPE_WEBHOOK_SECRET` | Stripe webhook secret | Optional | @@ -570,15 +572,30 @@ The scraper architecture supports multiple sources: pounce supports automated email notifications for domain availability and price changes. -### Setup +### Setup (Zoho Mail) Configure SMTP settings in your `.env`: ```env +# Zoho Mail Configuration (Recommended) +SMTP_HOST=smtp.zoho.eu +SMTP_PORT=465 +SMTP_USER=hello@pounce.ch +SMTP_PASSWORD=your-zoho-app-password +SMTP_FROM_EMAIL=hello@pounce.ch +SMTP_FROM_NAME=pounce +SMTP_USE_TLS=false +SMTP_USE_SSL=true +CONTACT_EMAIL=hello@pounce.ch +``` + +Alternative providers: +```env +# Gmail (port 587, STARTTLS) SMTP_HOST=smtp.gmail.com SMTP_PORT=587 -SMTP_USER=your-email@gmail.com -SMTP_PASSWORD=your-app-password +SMTP_USE_SSL=false +SMTP_USE_TLS=true ``` ### Notification Types diff --git a/backend/app/services/email_service.py b/backend/app/services/email_service.py index 3fe12c6..20e6e25 100644 --- a/backend/app/services/email_service.py +++ b/backend/app/services/email_service.py @@ -32,19 +32,20 @@ from jinja2 import Template logger = logging.getLogger(__name__) -# SMTP Configuration from environment +# SMTP Configuration from environment (Zoho defaults) SMTP_CONFIG = { - "host": os.getenv("SMTP_HOST"), - "port": int(os.getenv("SMTP_PORT", "587")), - "username": os.getenv("SMTP_USER"), + "host": os.getenv("SMTP_HOST", "smtp.zoho.eu"), + "port": int(os.getenv("SMTP_PORT", "465")), + "username": os.getenv("SMTP_USER", "hello@pounce.ch"), "password": os.getenv("SMTP_PASSWORD"), - "from_email": os.getenv("SMTP_FROM_EMAIL", "noreply@pounce.ch"), + "from_email": os.getenv("SMTP_FROM_EMAIL", "hello@pounce.ch"), "from_name": os.getenv("SMTP_FROM_NAME", "pounce"), - "use_tls": os.getenv("SMTP_USE_TLS", "true").lower() == "true", + "use_tls": os.getenv("SMTP_USE_TLS", "false").lower() == "true", + "use_ssl": os.getenv("SMTP_USE_SSL", "true").lower() == "true", } # Contact email - where contact form submissions are sent -CONTACT_EMAIL = os.getenv("CONTACT_EMAIL", "support@pounce.ch") +CONTACT_EMAIL = os.getenv("CONTACT_EMAIL", "hello@pounce.ch") # Base email wrapper template @@ -388,13 +389,26 @@ class EmailService: msg.attach(MIMEText(html_content, "html")) # Send via SMTP - async with aiosmtplib.SMTP( - hostname=SMTP_CONFIG["host"], - port=SMTP_CONFIG["port"], - use_tls=SMTP_CONFIG["use_tls"], - ) as smtp: - await smtp.login(SMTP_CONFIG["username"], SMTP_CONFIG["password"]) - await smtp.send_message(msg) + # Zoho uses SSL on port 465 (not STARTTLS on 587) + if SMTP_CONFIG["use_ssl"]: + # SSL connection (port 465) + async with aiosmtplib.SMTP( + hostname=SMTP_CONFIG["host"], + port=SMTP_CONFIG["port"], + use_tls=True, # Start with TLS/SSL + start_tls=False, # Don't upgrade, already encrypted + ) as smtp: + await smtp.login(SMTP_CONFIG["username"], SMTP_CONFIG["password"]) + await smtp.send_message(msg) + else: + # STARTTLS connection (port 587) + async with aiosmtplib.SMTP( + hostname=SMTP_CONFIG["host"], + port=SMTP_CONFIG["port"], + start_tls=SMTP_CONFIG["use_tls"], + ) as smtp: + await smtp.login(SMTP_CONFIG["username"], SMTP_CONFIG["password"]) + await smtp.send_message(msg) logger.info(f"Email sent to {to_email}: {subject}") return True diff --git a/backend/env.example b/backend/env.example index 5d54e27..d41371f 100644 --- a/backend/env.example +++ b/backend/env.example @@ -41,36 +41,34 @@ STRIPE_PRICE_TRADER=price_xxxxxxxxxxxxxx STRIPE_PRICE_TYCOON=price_xxxxxxxxxxxxxx # ================================= -# SMTP Email Configuration +# SMTP Email Configuration (Zoho) # ================================= -# Gmail Example: +# Zoho Mail (recommended): +# SMTP_HOST=smtp.zoho.eu +# SMTP_PORT=465 +# SMTP_USE_SSL=true +# SMTP_USE_TLS=false +# +# Gmail Example (port 587, STARTTLS): # SMTP_HOST=smtp.gmail.com # SMTP_PORT=587 +# SMTP_USE_SSL=false +# SMTP_USE_TLS=true # SMTP_USER=your-email@gmail.com -# SMTP_PASSWORD=your-app-password (not your Gmail password!) -# -# Mailgun Example: -# SMTP_HOST=smtp.mailgun.org -# SMTP_PORT=587 -# SMTP_USER=postmaster@your-domain.com -# SMTP_PASSWORD=your-mailgun-smtp-password -# -# AWS SES Example: -# SMTP_HOST=email-smtp.eu-central-1.amazonaws.com -# SMTP_PORT=587 -# SMTP_USER=your-ses-smtp-user -# SMTP_PASSWORD=your-ses-smtp-password +# SMTP_PASSWORD=your-app-password -SMTP_HOST=smtp.gmail.com -SMTP_PORT=587 -SMTP_USER=your-email@gmail.com -SMTP_PASSWORD=your-app-password -SMTP_FROM_EMAIL=noreply@pounce.ch +# Zoho Configuration (Default) +SMTP_HOST=smtp.zoho.eu +SMTP_PORT=465 +SMTP_USER=hello@pounce.ch +SMTP_PASSWORD=your-zoho-app-password +SMTP_FROM_EMAIL=hello@pounce.ch SMTP_FROM_NAME=pounce -SMTP_USE_TLS=true +SMTP_USE_TLS=false +SMTP_USE_SSL=true # Email for contact form submissions -CONTACT_EMAIL=support@pounce.ch +CONTACT_EMAIL=hello@pounce.ch # ================================= # Scheduler Settings diff --git a/backend/env.example.txt b/backend/env.example.txt index 622f2c3..15d6e55 100644 --- a/backend/env.example.txt +++ b/backend/env.example.txt @@ -1,23 +1,27 @@ # Database DATABASE_URL=sqlite+aiosqlite:///./domainwatch.db # For PostgreSQL in production: -# DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/domainwatch +# DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/pounce # JWT Settings SECRET_KEY=your-super-secret-key-change-in-production ALGORITHM=HS256 -ACCESS_TOKEN_EXPIRE_MINUTES=1440 +ACCESS_TOKEN_EXPIRE_MINUTES=10080 # App Settings -APP_NAME=DomainWatch +APP_NAME=pounce DEBUG=True -# Email Settings (optional) -SMTP_HOST=smtp.example.com -SMTP_PORT=587 -SMTP_USER=your-email@example.com -SMTP_PASSWORD=your-password -EMAIL_FROM=noreply@domainwatch.com +# Email Settings (Zoho) +SMTP_HOST=smtp.zoho.eu +SMTP_PORT=465 +SMTP_USER=hello@pounce.ch +SMTP_PASSWORD=your-zoho-password +SMTP_FROM_EMAIL=hello@pounce.ch +SMTP_FROM_NAME=pounce +SMTP_USE_TLS=false +SMTP_USE_SSL=true +CONTACT_EMAIL=hello@pounce.ch # Scheduler Settings CHECK_HOUR=6