Overview
The Automated Email Reminders feature sends scheduled notifications to employees who have not checked in by 8:00 AM each workday. Using APScheduler’s cron-based scheduling, the system automatically identifies absent employees and sends reminder emails via SMTP, helping ensure accountability and timely attendance.Reminders are sent only to employees who have not checked in on the current date. Admin users are excluded from notifications.
How It Works
Scheduler Triggers at 8:00 AM
APScheduler’s background cron job activates daily at exactly 8:00 AM server time
System Checks Today's Attendance
The system queries all check-ins from the current date and creates a list of employees who have logged in
Identify Missing Employees
Compares the user database against today’s check-ins to find employees without attendance records
Technical Implementation
Scheduler Configuration
The system uses APScheduler’s BackgroundScheduler with cron triggers inapp.py:87-91:
Email Logic
The core reminder function inapp.py:65-85 handles all notification logic:
Email Configuration
SMTP Setup
The system uses Gmail’s SMTP server configured inapp.py:15-21:
Gmail App Password Setup
Enable 2-Factor Authentication
Go to Google Account settings and enable 2FA on the sender Gmail account
Who Gets Notified?
Recipient Selection Logic
The system applies three filtering rules:Rule 1: Exclude Admin
Admin users (
username == 'admin') never receive reminder emailsRule 2: Check Today's Date
Only checks registrations with
fecha == today to determine attendanceRule 3: No Duplicate Emails
Employees who already checked in today are excluded from recipients list
Example Scenario
User Database:- ✅ empleado1: Already checked in → No email
- ❌ empleado2: No check-in → Receives reminder
- ❌ empleado3: No check-in → Receives reminder
- ⛔ admin: Excluded by rule → No email
Email Content
Message Template
- Subject Line
- Email Body
- Sender Address
- Emoji draws attention in inbox
- Clear action required: “Inicia tu Turno”
- “Automático” indicates system-generated
Manual Override
Admin-Triggered Reminders
Administrators can manually send reminders outside the 8:00 AM schedule:Scheduling Details
Cron Expression Breakdown
Trigger Type
'cron' - Use cron-style scheduling (not interval or date-based)Hour
hour=8 - Execute at 8 AM (24-hour format, server timezone)Minute
minute=0 - Execute at exactly :00 (top of the hour)Frequency
Runs every day at 08:00:00 (implicit daily recurrence)
Timezone Considerations
To specify an explicit timezone:Monitoring & Logs
Console Output
The system prints detailed logs to stdout:Error Handling
SMTP Connection Failures
SMTP Connection Failures
Common causes:Solution: Verify credentials, regenerate app password, check network connectivity
- Invalid Gmail credentials
- 2FA not enabled or app password not generated
- SMTP port 587 blocked by firewall
- Gmail rate limiting (too many emails)
No Recipients Found
No Recipients Found
If all employees have checked in,
destinatarios will be empty and no emails are sent.Expected behavior: Silent success (no error thrown)Log output: Function executes but mail.send() is skipped due to if destinatarios: checkTesting the System
Development Testing
Wait for Trigger
Wait until the scheduled time and check:
- Console logs for confirmation message
- Test email inbox for reminder
Best Practices
Production Recommendations
Environment Variables
Email Service Provider
Consider SendGrid, Mailgun, or AWS SES for better deliverability and higher limits
Rate Limiting
Implement delays between bulk sends to avoid Gmail spam filters
Logging System
Replace
print() statements with proper logging framework (e.g., Python logging module)Integration with Other Features
The reminder system works seamlessly with:- Employee Tracking: Checks GPS check-in timestamps to determine attendance
- Admin Dashboard: Provides manual trigger button for on-demand reminders
- PDF Reports: Email logs can be referenced when reviewing attendance patterns
Troubleshooting
Scheduler not triggering
Scheduler not triggering
Symptoms: No logs appear at 8:00 AMPossible causes:
- Flask app crashed or restarted before trigger time
scheduler.start()not calleduse_reloader=Truecausing duplicate schedulers
- Check app uptime with process monitoring
- Verify
scheduler.start()in code - Set
use_reloader=Falseinapp.run()
Emails not arriving
Emails not arriving
Symptoms: Logs show success but no emails receivedPossible causes:
- Emails in spam/junk folder
- Invalid recipient email addresses
- Gmail blocked delivery (suspicious activity)
- Check spam folders
- Verify email addresses in
usuarios.json - Review Gmail account security notifications
- Test with
mail.send()directly in Python shell
Customization Options
- Change Trigger Time
- Custom Email Template
- HTML Emails
- Multiple Reminders
Modify
hour and minute parameters: