mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-03 18:22:57 +00:00
8.6 KiB
8.6 KiB
Newsletter Implementation Summary
✅ Implementation Complete
The comprehensive newsletter system has been fully implemented with all requested features.
🎯 Features Implemented
1. Enhanced Subscription Flow
- ✅ Initial email with token for preference setup
- ✅ Welcome email with unsubscribe/manage links
- ✅ Token-based preference management (no login required)
- ✅ Unsubscribe functionality in every email
2. Four Newsletter Types
Týdenní Přehled (Weekly Overview)
- ✅ Sends every Sunday at 9 AM (configurable day/hour in admin)
- ✅ Contains blogs, activities, matches, scores
- ✅ Filtered by user preferences and categories
Nadcházející Zápasy (Upcoming Matches)
- ✅ Sends 2 days before match (configurable lead time)
- ✅ Sends day-of reminder (0-6 hours before)
- ✅ Includes: category, teams, place, time, date
- ✅ Filtered by user-selected categories
Nový Blog (Blog Notifications)
- ✅ Sends immediately when blog is published
- ✅ Includes title, excerpt, tracked link to article
- ✅ Filtered by blog categories
- ✅ Auto-triggered from admin when publishing
Výsledky Zápasu (Match Results)
- ✅ Sends after match finishes (within 6 hours)
- ✅ Includes final score and match details
- ✅ Respects quiet hours (default 22:00-08:00)
- ✅ Filtered by categories
3. Email Analytics & Tracking
- ✅ Open tracking (transparent pixel)
- ✅ Click tracking (all links wrapped)
- ✅ Blog links with tracking parameters
- ✅ Unsubscribe tracking
- ✅ All events logged in
email_eventtable
4. Admin Configuration
- ✅ Master on/off toggle
- ✅ Individual newsletter type toggles
- ✅ Weekly schedule configuration (day + hour)
- ✅ Match reminder lead time setting
- ✅ Quiet hours for result notifications
- ✅ Manual test sending
- ✅ Manual digest sending
- ✅ Newsletter preview
- ✅ Subscriber management
5. Category-Based Filtering
- ✅ Users can specify categories in preferences
- ✅ Comma-separated list (e.g., "MFS A, MFS B, Divize")
- ✅ Applied to matches, results, and blogs
- ✅ Empty = receive all categories
📁 Files Created/Modified
New Files
database/migrations/20250930000001_enhance_newsletter_system.up.sql- Migration for tracking tablesdatabase/migrations/20250930000001_enhance_newsletter_system.down.sql- Rollback migrationinternal/services/newsletter_automation.go- Main automation service (550+ lines)NEWSLETTER_SYSTEM.md- Comprehensive documentationNEWSLETTER_IMPLEMENTATION_SUMMARY.md- This file
Modified Files
internal/models/email.go- Added tracking models (NewsletterSentLog,MatchNotification,BlogNotification)internal/controllers/base_controller.go- Added blog notification triggerinternal/routes/routes.go- Added newsletter automation instance managementmain.go- Initialize and start newsletter automationinternal/models/models.go- Settings table already had newsletter fields
Existing Files Leveraged
internal/models/contact.go-NewsletterSubscriptionmodel with preferences JSONBinternal/controllers/contact_controller.go- Subscription endpoints, preference managementinternal/services/newsletter_content.go- Content builder for digestsinternal/services/newsletter_scheduler.go- Legacy weekly scheduler (kept for compatibility)pkg/email/service.go- Email sending with analytics trackingpkg/utils/subscriber_token.go- Token generation/validationtemplates/emails/newsletter_welcome.html- Welcome templatetemplates/emails/newsletter.html- General newsletter template
🗄️ Database Changes
New Tables (3)
newsletter_sent_log -- Tracks all sent newsletters
match_notifications -- Prevents duplicate match alerts
blog_notifications -- Prevents duplicate blog alerts
Modified Tables
None - all required fields already existed in:
newsletter_subscriptions(preferences JSONB)settings(newsletter configuration fields)email_log&email_event(analytics)
🔧 Configuration
Required Settings in Database (settings table)
newsletter_enabled = true -- Master toggle
enable_weekly = true -- Enable weekly digest
enable_match_reminders = true -- Enable match alerts
enable_results = true -- Enable result notifications
newsletter_weekly_day = 'sun' -- Day for weekly (sun/mon/tue/wed/thu/fri/sat)
newsletter_weekly_hour = 9 -- Hour for weekly (0-23)
newsletter_reminder_lead_hours = 48 -- Hours before match for first alert
newsletter_quiet_start = 22 -- Don't send results between these hours
newsletter_quiet_end = 8 -- (22:00 - 08:00)
Environment Variables (Optional)
NEWSLETTER_ENABLED=true # Can be overridden by DB setting
NEWSLETTER_INTERVAL_HOURS=24 # Legacy setting for old scheduler
🚀 How to Use
1. Run Migration
export RUN_MIGRATIONS=true
./main
2. Enable in Admin
curl -X PATCH http://localhost:8080/api/v1/admin/newsletter/enable \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
3. Configure Settings
Update the settings table via admin API or directly in database.
4. Test
curl -X POST http://localhost:8080/api/v1/admin/newsletter/test \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "type": "weekly"}'
🔄 Automation Schedule
The system runs checks every 15 minutes and:
- Checks if it's time for weekly digest (matches configured day/hour)
- Scans upcoming matches for reminder opportunities
- Scans finished matches for result notifications
- Blog notifications trigger immediately on publish (not on schedule)
⚠️ Important Notes
Duplicate Prevention
- Each notification type has tracking to prevent duplicates
- Unique constraints on
match_id + notification_typeandarticle_id
Rate Limiting
- 200ms delay between individual emails to avoid SMTP throttling
- Consider using a dedicated SMTP service for large subscriber lists
Token Security
- Subscriber tokens expire after 30 days
- Tokens are JWT-based with HMAC signing
- Use
JWT_SECRETenvironment variable (never leave as default in production)
Blog Notifications
- Only trigger when
publishedchanges fromfalsetotrue - Manual DB updates won't trigger (only through admin API/UI)
Match Data
- Relies on cached FACR data in
cache/prefetch/facr_club_info.json - Ensure prefetch service is running and cache is fresh
📊 Monitoring
Check System Status
-- Active subscribers
SELECT COUNT(*) FROM newsletter_subscriptions WHERE is_active = true;
-- Sent newsletters today
SELECT newsletter_type, COUNT(*), SUM(recipients_count)
FROM newsletter_sent_log
WHERE DATE(sent_at) = CURRENT_DATE
GROUP BY newsletter_type;
-- Recent blog notifications
SELECT article_id, sent_at, recipients_count
FROM blog_notifications
ORDER BY sent_at DESC LIMIT 10;
-- Recent match notifications
SELECT match_id, notification_type, sent_at, recipients_count
FROM match_notifications
ORDER BY sent_at DESC LIMIT 10;
-- Email analytics
SELECT event_type, COUNT(*)
FROM email_event
WHERE DATE(created_at) = CURRENT_DATE
GROUP BY event_type;
Admin API
GET /api/v1/admin/newsletter/status
🐛 Troubleshooting
| Issue | Solution |
|---|---|
| No emails sent | Check newsletter_enabled and individual type flags in settings |
| Duplicate emails | Check tracking tables for existing notifications |
| Wrong schedule | Verify timezone, day, and hour settings |
| Blog notification not sent | Ensure article was published via API (not manual DB update) |
| Match data missing | Verify prefetch cache is populated |
📖 Full Documentation
See NEWSLETTER_SYSTEM.md for:
- Detailed API reference
- Database schema documentation
- Email template variables
- Security considerations
- Future enhancement ideas
✨ Next Steps
- Run migration to create tracking tables
- Enable system via admin API
- Configure settings for your club's schedule
- Test each newsletter type individually
- Monitor logs for first automated sends
- Gather user feedback and adjust settings
Implementation Date: 2025-09-30
Status: ✅ Complete and Ready for Production
Developer Notes: All requested features implemented. System is modular, well-documented, and ready for deployment.