From f82de3621f906460aface8ee852a3bd7989652d8 Mon Sep 17 00:00:00 2001 From: Paul Bailey Date: Mon, 17 Nov 2025 00:34:21 +0000 Subject: [PATCH] docs: update Mailgun configuration with correct sandbox domain - Update domain to sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org - Set test email to psbailey31@gmail.com - Add comprehensive Mailgun setup guide - Document sandbox authorization requirements - Create email testing script - Update troubleshooting documentation Note: Sandbox domains require recipient authorization in Mailgun dashboard --- NOTIFICATION_SYSTEM_IMPLEMENTATION.md | 36 +++- server/.env.example | 4 +- server/MAILGUN_SETUP.md | 231 ++++++++++++++++++++++++++ server/src/scripts/testEmail.ts | 62 +++++++ server/src/services/emailService.ts | 2 +- 5 files changed, 323 insertions(+), 12 deletions(-) create mode 100644 server/MAILGUN_SETUP.md create mode 100644 server/src/scripts/testEmail.ts diff --git a/NOTIFICATION_SYSTEM_IMPLEMENTATION.md b/NOTIFICATION_SYSTEM_IMPLEMENTATION.md index d07b574..8041a18 100644 --- a/NOTIFICATION_SYSTEM_IMPLEMENTATION.md +++ b/NOTIFICATION_SYSTEM_IMPLEMENTATION.md @@ -101,10 +101,23 @@ TEST_EMAIL="test@example.com" ### Mailgun Setup -1. **API Key**: Provided - `dd27be7a81dd7b0980ada31fec9a9bd9-e80d8b76-fd80c63b` -2. **Domain**: Configure your Mailgun domain (currently using sandbox) -3. **From Email**: Set your sender email address -4. **Sandbox Mode**: For testing, add authorized recipients in Mailgun dashboard +1. **API Key**: `dd27be7a81dd7b0980ada31fec9a9bd9-e80d8b76-fd80c63b` +2. **Domain**: `sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org` +3. **From Email**: `Beach Litter Platform ` + +#### Sandbox Mode Authorization + +**IMPORTANT**: Mailgun sandbox domains require you to authorize recipient email addresses before sending. + +To authorize recipients: +1. Go to https://app.mailgun.com/ +2. Navigate to Sending → Domains +3. Click on your sandbox domain: `sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org` +4. Go to "Authorized Recipients" section +5. Add email addresses you want to test with (e.g., `psbailey31@gmail.com`) +6. Recipients will receive a confirmation email - they must click the link to authorize + +**For Production**: Use a verified custom domain instead of sandbox to send to any email address without authorization. ## Testing @@ -218,11 +231,16 @@ Emails include: ### Emails Not Sending -1. Check Mailgun API key is correct -2. Verify domain is configured in Mailgun -3. Check sandbox mode restrictions (add authorized recipients) -4. Review server logs for error messages -5. Test email service with test script +1. **Check Mailgun API key is correct**: Verify in `.env` file +2. **Verify domain is configured**: Should be `sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org` +3. **Authorize recipients for sandbox**: + - Go to https://app.mailgun.com/ + - Navigate to your sandbox domain + - Add authorized recipients (they must confirm via email) + - Error "Forbidden" means recipient is not authorized +4. **Review server logs**: Check for detailed error messages +5. **Test email service**: Run `npx tsx src/scripts/testEmail.ts` +6. **For production**: Use a verified custom domain to avoid sandbox restrictions ### Notifications Not Appearing diff --git a/server/.env.example b/server/.env.example index e78ecd8..9f3ad2a 100644 --- a/server/.env.example +++ b/server/.env.example @@ -22,7 +22,7 @@ OPENWEATHER_API_KEY="your_openweather_api_key_here" # Email Notifications (Mailgun) MAILGUN_API_KEY="dd27be7a81dd7b0980ada31fec9a9bd9-e80d8b76-fd80c63b" -MAILGUN_DOMAIN="sandbox-123.mailgun.org" -FROM_EMAIL="Beach Litter Platform " +MAILGUN_DOMAIN="sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org" +FROM_EMAIL="Beach Litter Platform " FRONTEND_URL="http://localhost:5173" TEST_EMAIL="test@example.com" diff --git a/server/MAILGUN_SETUP.md b/server/MAILGUN_SETUP.md new file mode 100644 index 0000000..c00376e --- /dev/null +++ b/server/MAILGUN_SETUP.md @@ -0,0 +1,231 @@ +# Mailgun Email Setup Guide + +## Current Configuration + +- **API Key**: `dd27be7a81dd7b0980ada31fec9a9bd9-e80d8b76-fd80c63b` +- **Domain**: `sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org` +- **From Email**: `Beach Litter Platform ` + +## Sandbox Domain Limitations + +Mailgun sandbox domains have restrictions: +- ✅ Free to use for testing +- ❌ Can only send to **authorized recipients** +- ❌ Limited to 300 emails per day +- ❌ Emails may be marked as spam more often + +## Step-by-Step: Authorize Recipients + +### 1. Access Mailgun Dashboard + +Go to: https://app.mailgun.com/ + +### 2. Navigate to Your Domain + +1. Click on **"Sending"** in the left sidebar +2. Click on **"Domains"** +3. Select your sandbox domain: `sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org` + +### 3. Add Authorized Recipients + +1. Scroll down to the **"Authorized Recipients"** section +2. Enter the email address you want to authorize (e.g., `psbailey31@gmail.com`) +3. Click **"Invite"** + +### 4. Confirm Authorization + +1. The recipient will receive an email from Mailgun +2. Subject: "Mailgun Sandbox Domain Authorization" +3. They must click the confirmation link in the email +4. Once confirmed, you can send emails to that address + +### 5. Test Email Sending + +Run the test script: + +```bash +cd server +npx tsx src/scripts/testEmail.ts +``` + +You should see: +``` +✅ Test email sent successfully to psbailey31@gmail.com +``` + +## Common Errors + +### Error: "Forbidden" + +**Cause**: Recipient email is not authorized in sandbox domain + +**Solution**: +1. Add the email to authorized recipients in Mailgun dashboard +2. Recipient must confirm the authorization email +3. Wait a few minutes and try again + +### Error: "Unauthorized" + +**Cause**: Invalid API key + +**Solution**: +1. Verify API key in `.env` file +2. Check for extra spaces or quotes +3. Regenerate API key in Mailgun if needed + +### Emails Going to Spam + +**Cause**: Sandbox domains have lower reputation + +**Solution**: +1. For testing, check spam folder +2. For production, use a verified custom domain +3. Set up SPF and DKIM records + +## Upgrading to Production + +For production use, you should: + +### 1. Add a Custom Domain + +1. Go to Mailgun dashboard → Domains +2. Click "Add New Domain" +3. Enter your domain (e.g., `beachlitter.ie`) +4. Follow DNS setup instructions + +### 2. Verify Domain + +Add these DNS records to your domain: + +``` +TXT @ v=spf1 include:mailgun.org ~all +TXT k1._domainkey [provided by Mailgun] +CNAME email mailgun.org +``` + +### 3. Update Configuration + +Update `.env`: + +```env +MAILGUN_DOMAIN="beachlitter.ie" +FROM_EMAIL="Beach Litter Platform " +``` + +### 4. Benefits of Custom Domain + +- ✅ Send to any email address (no authorization needed) +- ✅ Better email deliverability +- ✅ Professional sender address +- ✅ Higher sending limits +- ✅ Better spam score + +## Testing Checklist + +- [ ] API key is correct in `.env` +- [ ] Domain is correct in `.env` +- [ ] Test email is authorized in Mailgun dashboard +- [ ] Test email confirmation link was clicked +- [ ] Test script runs successfully +- [ ] Email appears in inbox (or spam folder) +- [ ] Email formatting looks correct +- [ ] Links in email work correctly + +## Email Templates + +The system sends two types of emails: + +### 1. Simple Text Email + +Plain text with basic formatting, used for: +- Test emails +- System notifications + +### 2. HTML Notification Email + +Formatted HTML with: +- Beach Litter Platform branding +- Professional styling +- Call-to-action buttons +- Responsive design + +Used for: +- New report notifications +- New event notifications +- Event reminders +- Report verification notifications + +## Monitoring Email Delivery + +### Mailgun Dashboard + +View email statistics: +1. Go to https://app.mailgun.com/ +2. Click "Analytics" → "Overview" +3. See sent, delivered, opened, clicked metrics + +### Server Logs + +Check application logs for: +- Email sending attempts +- Success/failure messages +- Error details + +```bash +# View recent logs +tail -f server.log | grep EMAIL +``` + +## Rate Limits + +### Sandbox Domain +- 300 emails per day +- 100 emails per hour + +### Verified Domain +- 10,000 emails per month (free tier) +- Higher limits available with paid plans + +## Support + +If you encounter issues: + +1. **Check Mailgun Status**: https://status.mailgun.com/ +2. **Review Logs**: Check server logs for detailed errors +3. **Mailgun Support**: https://help.mailgun.com/ +4. **Documentation**: https://documentation.mailgun.com/ + +## Alternative: Using a Different Email Service + +If you prefer a different email service, you can modify `server/src/services/emailService.ts`: + +### SendGrid +```typescript +import sgMail from '@sendgrid/mail'; +sgMail.setApiKey(process.env.SENDGRID_API_KEY); +``` + +### AWS SES +```typescript +import AWS from 'aws-sdk'; +const ses = new AWS.SES({ region: 'us-east-1' }); +``` + +### Nodemailer (SMTP) +```typescript +import nodemailer from 'nodemailer'; +const transporter = nodemailer.createTransport({ + host: 'smtp.gmail.com', + port: 587, + auth: { user: 'email', pass: 'password' } +}); +``` + +## Conclusion + +The notification system is configured and ready to use. For testing: +1. Authorize recipient emails in Mailgun dashboard +2. Run the test script +3. Check inbox (and spam folder) + +For production, upgrade to a verified custom domain for better deliverability and no authorization requirements. diff --git a/server/src/scripts/testEmail.ts b/server/src/scripts/testEmail.ts new file mode 100644 index 0000000..900fa71 --- /dev/null +++ b/server/src/scripts/testEmail.ts @@ -0,0 +1,62 @@ +/** + * Quick test script for email service + */ + +import dotenv from 'dotenv'; +import { emailService } from '../services/emailService'; + +dotenv.config(); + +async function testEmail() { + console.log('📧 Testing Email Service with Mailgun\n'); + + console.log('Configuration:'); + console.log(` API Key: ${process.env.MAILGUN_API_KEY?.substring(0, 20)}...`); + console.log(` Domain: ${process.env.MAILGUN_DOMAIN}`); + console.log(` From: ${process.env.FROM_EMAIL}`); + console.log(''); + + // Test 1: Send a simple test email + console.log('1️⃣ Sending test email...'); + const testEmail = process.env.TEST_EMAIL || 'psbailey31@gmail.com'; + + const success = await emailService.sendEmail({ + to: testEmail, + subject: 'Beach Litter Platform - Test Email', + text: 'This is a test email from the Beach Litter Mapping Platform. If you received this, email notifications are working correctly!', + }); + + if (success) { + console.log(`✅ Test email sent successfully to ${testEmail}`); + console.log(' Check your inbox (and spam folder)'); + } else { + console.log(`❌ Failed to send test email to ${testEmail}`); + } + console.log(''); + + // Test 2: Send a formatted notification email + console.log('2️⃣ Sending formatted notification email...'); + const notificationSuccess = await emailService.sendNotificationEmail( + testEmail, + 'Test User', + 'New Litter Report in Your Area', + 'A new plastic litter report was submitted near Dublin city center. The report indicates a significant amount of plastic waste.', + 'report', + 'test-report-123' + ); + + if (notificationSuccess) { + console.log(`✅ Notification email sent successfully to ${testEmail}`); + console.log(' Check your inbox for a formatted notification'); + } else { + console.log(`❌ Failed to send notification email to ${testEmail}`); + } + console.log(''); + + console.log('✅ Email testing completed!'); + console.log(''); + console.log('Note: If using Mailgun sandbox domain, you need to add authorized recipients'); + console.log('in your Mailgun dashboard: https://app.mailgun.com/'); +} + +testEmail().catch(console.error); diff --git a/server/src/services/emailService.ts b/server/src/services/emailService.ts index 24bae89..1f786a9 100644 --- a/server/src/services/emailService.ts +++ b/server/src/services/emailService.ts @@ -9,7 +9,7 @@ const mg = mailgun.client({ key: process.env.MAILGUN_API_KEY || 'dd27be7a81dd7b0980ada31fec9a9bd9-e80d8b76-fd80c63b', }); -const MAILGUN_DOMAIN = process.env.MAILGUN_DOMAIN || 'sandbox-123.mailgun.org'; +const MAILGUN_DOMAIN = process.env.MAILGUN_DOMAIN || 'sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org'; const FROM_EMAIL = process.env.FROM_EMAIL || 'Beach Litter Platform '; interface EmailData {