AutoSendReminder
Overview
AutoSendReminderTask resends previously sent patient letters that have not been viewed after configured resend intervals. It evaluates all auto-sent letters against AutoSendLetterConfig reminder criteria, identifies letters needing follow-up, and resends them via email or SMS while tracking reminder attempt counts.
Use this task when: You need to automatically follow up with patients who haven't viewed their cost estimate letters, ensuring critical payment information reaches patients through repeated delivery attempts.
Don't use this task when:
- Initial letter sending (use
AutoSendLettersTaskorAutoSendLettersForFutureVisitsTaskinstead) - Manually resending a single letter (use the UI letter management features)
- Testing letter delivery (reminder logic requires existing send events and proper time intervals)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| None | - | - | - | This task has no configurable parameters. All reminder behavior is configured via AutoSendLetterConfig entities (ResendInterval, MaxResendAttempts, AttemptResend properties). |
Execution Flow
flowchart TD
A[Start AutoSendReminder] --> B[Load all AutoSendLetterConfigs with reminders enabled]
B --> C{Any configs with AttemptResend=true?}
C -->|No| Z[End - No reminders configured]
C -->|Yes| D[For each AutoSendLetterConfig]
D --> E[Calculate intervalOffset = Today - ResendInterval days]
E --> F[Query PatientLetters needing resend]
F --> G{Query filters}
G --> H[AutoSent = true]
H --> I[ViewedDate IS NULL]
I --> J[AutoResendAttempts < MaxResendAttempts]
J --> K[Last send event >= intervalOffset]
K --> L[Most recent letter per visit/invoice]
L --> M{Any letters found?}
M -->|No| D
M -->|Yes| N[Load related Visits, Patients, Facilities]
N --> O[For each PatientLetter]
O --> P[Create PatientLetterSendEvent with current date]
P --> Q[Send letter via email/SMS using LetterHandler]
Q --> R[Log API response]
R --> S[Increment letter.AutoResendAttempts]
S --> T{More letters for this config?}
T -->|Yes| O
T -->|No| U[Save all PatientLetterSendEvents in bulk]
U --> V[Save all updated PatientLetters in bulk]
V --> W{More configs?}
W -->|Yes| D
W -->|No| Z[End]
style F fill:#e1f5ff
style Q fill:#fff4e1
style U fill:#e1f5ff
style V fill:#e1f5ff
Processing Algorithm
The task uses date-based interval logic to determine which letters need reminders:
Reminder Selection Algorithm
Load Eligible Configs: Select all AutoSendLetterConfig records where:
AttemptResend = trueResendIntervalis not nullMaxResendAttempts != 0
For Each Config: Calculate which letters need reminders using:
intervalOffset = CurrentDate - config.ResendInterval (in days)Filter PatientLetters by the following cumulative criteria:
AutoGenerated = true(generated by auto-send system)AutoSent = true(successfully sent initially)ViewedDate IS NULL(patient hasn't viewed the letter)AutoResendAttempts < config.MaxResendAttempts(haven't exhausted attempts)- Associated with the AutoSendLetterConfig via PatientLetterSendEvent
- Most recent PatientLetterSendEvent.CreatedOn date >= intervalOffset
- Most recent letter per Visit/Invoice combination (no duplicates)
Send Reminders: For each qualifying letter:
- Create new PatientLetterSendEvent with current timestamp
- Resend letter using existing LetterHandler (same logic as initial send)
- Increment
AutoResendAttemptscounter on the letter - Log email/SMS API response
Bulk Save: Save all send events and updated letters in two bulk operations
Example Execution
Scenario: AutoSendLetterConfig with ResendInterval=3 days, MaxResendAttempts=2
Config: AutoSendLetterConfig-01
ResendInterval: 3 days
MaxResendAttempts: 2
AttemptResend: true
PatientLetter: PL-1 (for Visit V-1)
AutoSent: true
ViewedDate: null (not viewed)
AutoResendAttempts: 0
Send Events:
- Event 1: Created 2024-01-01 (initial send)
Current Date: 2024-01-04 (3 days later)
intervalOffset: 2024-01-04 - 3 = 2024-01-01
Evaluation:
✓ AutoSent = true
✓ ViewedDate IS NULL
✓ AutoResendAttempts (0) < MaxResendAttempts (2)
✓ Last event (2024-01-01) >= intervalOffset (2024-01-01)
Result: SEND REMINDER
- Create Event 2 with CreatedOn = 2024-01-04
- Resend letter via email/SMS
- Increment AutoResendAttempts to 1
Next Reminder: 2024-01-07 (3 days later, attempt 2/2)
Final Attempt: After 2024-01-07, no more reminders (MaxResendAttempts reached)
Letter Viewed During Reminder Period
PatientLetter: PL-2
AutoResendAttempts: 1
ViewedDate: 2024-01-03 (patient viewed letter)
Evaluation:
✓ AutoSent = true
✗ ViewedDate IS NOT NULL
Result: NO REMINDER (patient already viewed)
Usage Examples
Example 1: Scheduled daily execution
// Run daily at 9:00 AM to send reminders for unviewed letters
var task = new AutoSendReminderTask();
// No parameters - all configuration is in AutoSendLetterConfig entities
// The task automatically processes all configs with AttemptResend=true
Example 2: Part of patient engagement pipeline
// Step 1: Initial letter send for upcoming visits
var initialSendTask = new AutoSendLettersForFutureVisitsTask();
// Step 2 (3 days later): Follow up with patients who haven't viewed
var reminderTask = new AutoSendReminderTask();
// Automatically identifies and resends letters based on ResendInterval
Example 3: Configuration-driven reminder strategy
// AutoSendLetterConfig configured in UI with:
// - ResendInterval: 2 days
// - MaxResendAttempts: 3
// - AttemptResend: true
//
// Timeline:
// Day 0: Initial letter sent (AutoSendLettersTask)
// Day 2: First reminder (AutoSendReminderTask, attempt 1/3)
// Day 4: Second reminder (AutoSendReminderTask, attempt 2/3)
// Day 6: Final reminder (AutoSendReminderTask, attempt 3/3)
// Day 8+: No more reminders (MaxResendAttempts reached)
var task = new AutoSendReminderTask();
Related Tasks Comparison
| Task | Scope | Letter Source | Reminder Logic | Use Case |
|---|---|---|---|---|
| AutoSendReminder | Unviewed auto-sent letters | Existing PatientLetter records | ResendInterval + MaxResendAttempts | Following up on letters patients haven't viewed |
AutoSendLettersTask |
Batch table visits | Generates new letters | N/A (initial send) | Initial letter generation and sending for batch visits |
AutoSendLettersForFutureVisitsTask |
Future scheduled visits | Generates new letters | N/A (initial send) | Initial letter generation for upcoming appointments |
Key Differentiators:
- AutoSendReminder only resends existing letters; it never creates new letters
- AutoSendReminder requires prior execution of AutoSendLettersTask or AutoSendLettersForFutureVisitsTask
- AutoSendLetters* tasks create PatientLetter and initial PatientLetterSendEvent records
- AutoSendReminder creates additional PatientLetterSendEvent records and increments AutoResendAttempts
- All three tasks use the same
LetterHandlerfor actual email/SMS delivery
Typical Pipeline:
AutoSendLettersTask → (wait ResendInterval days) → AutoSendReminderTask → (repeat until MaxResendAttempts)
Performance Considerations
Database Impact
- Tables Read:
AutoSendLetterConfig: Single query for all configs with reminders enabledPatientLetter: Filtered query per config using resend criteria (indexed by AutoSent, ViewedDate)PatientLetterSendEvent: Used to determine last send date and identify letters needing remindersVisit: Loaded for all letters needing remindersPatient: Loaded for all letters needing remindersFacility: Loaded for visits needing reminders
- Tables Written:
PatientLetterSendEvent: Bulk insert of new send events (one per reminder)PatientLetter: Bulk update of AutoResendAttempts counterMessageAPILog: Per-reminder logging of email/SMS API responses
- Query Patterns:
- Single query to load reminder-enabled configs
- Per-config query for letters needing resend (optimized with indexes)
- Batch loading of related entities (visits, patients, facilities)
- Dictionary lookups for entity relationships (no N+1 queries)
- External API Calls:
- One email or SMS API call per letter reminder
- API rate limits may affect throughput for high-volume reminders
Optimization Tips
| Scenario | Recommendation | Rationale |
|---|---|---|
| High unviewed letter count | Stagger reminder configs across different times of day | Avoid overwhelming email/SMS APIs with thousands of simultaneous sends |
| Many configs with reminders | Use longer ResendInterval to reduce frequency | 3-7 day intervals balance persistence with patient annoyance |
| Low patient engagement | Review letter content and MaxResendAttempts | 2-3 attempts is optimal; more may be counterproductive |
| API rate limiting | Run during off-peak hours (early morning) | Reduces conflicts with real-time letter sending |
| Large reminder batches | Monitor MessageAPILog for failures | Failed sends don't increment AutoResendAttempts; letter will be retried |