Email Notifications
How automatic emails work and how to configure them
OptiLearn sends automatic transactional emails at key learning events. These are delivered via Resend and run in the background so they don't slow down the app.
What Triggers an Email
| Event | Recipient | Template |
|---|---|---|
| Student enrolls in a course | Student | Enrollment Confirmed |
| Student completes a quiz | Student | Quiz Result (pass or fail) |
| Student completes all lessons in a course | Student | Course Completed |
| Certificate is auto-issued | Student | Certificate Earned |
| Assignment deadline approaching | Student | Assignment Due Reminder |
All emails are fire-and-forget. If sending fails, the main action (enrollment, quiz submission, etc.) still succeeds. Failures are logged but not surfaced to users.
Email Templates
Each template is a self-contained HTML file with inline styles (for email client compatibility). They share a common layout:
- Header with OptiLearn logo
- Main content card
- Optional call-to-action button
- Footer with links
Templates live in src/lib/email/templates.ts. If you need to customize them, edit that file and redeploy.
Available Templates
Enrollment Confirmed
- Sent when a student enrolls (self or admin)
- Includes course name, optional instructor name
- CTA: "Start Learning" → direct link to the course
Quiz Result
- Sent after every quiz submission
- Color-coded by pass/fail (green / red)
- Shows percentage score prominently
- CTA: "Go to Course" to retake if failed or continue if passed
Course Completed
- Sent when student finishes all lessons
- Shows final score (if available)
- Tells them a certificate is coming
Certificate Earned
- Sent separately from course completion
- Includes certificate number
- CTA: "View Certificate" → public verification page (shareable with employers)
Assignment Due Reminder
- Designed for cron-based scheduling (not yet wired up)
- Shows hours remaining before deadline
- CTA: "Open Assignment"
Configuration
Resend API Key
Set in Coolify environment variables:
RESEND_API_KEY=re_xxxxxxxx
EMAIL_FROM="OptiLearn <learn@opticrm.app>"
Without RESEND_API_KEY, OptiLearn falls back to SMTP (if configured) or silently skips sending.
SMTP Fallback
If you prefer SMTP over Resend, set:
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-username
SMTP_PASS=your-password
SMTP_SECURE=false
EMAIL_FROM="OptiLearn <learn@opticrm.app>"
OptiLearn tries Resend first, then falls back to SMTP if Resend isn't configured.
Disabling Emails
To disable all notification emails:
- Go to Coolify → OptiLearn → Environment Variables
- Remove
RESEND_API_KEY(or set it to an empty string) - Redeploy
The app will still work — emails just won't send.
Testing Email Delivery
In production, enroll a test student in a course. Check their inbox (and spam folder) for the enrollment email.
If nothing arrives:
- Check Resend dashboard for delivery logs
- Verify
RESEND_API_KEYis set correctly in Coolify - Make sure the
fromaddress domain is verified in Resend - Check server logs for "Failed to send email" messages
Rate Limits
Resend free tier allows 100 emails/day. For higher volumes, upgrade your Resend plan. OptiLearn doesn't throttle email sending — every event sends one email immediately.
What's NOT Yet Implemented
These require future work:
- In-app preferences — Currently every student gets all emails. A future version will let students opt out per category.
- Digest emails — Currently each event sends a separate email. A future version will bundle daily/weekly digests.
- Scheduled assignment reminders — The template exists but no cron job triggers them yet. Needs a BullMQ worker.
- Custom per-institution templates — Currently all tenants share the same templates. A future version will let institutions customize.