Skip to content

Conversation

@christenbc
Copy link

Google Calendar Reminder Sync Fix - Summary

Changes Made

Fixed the issue where task reminders were not being synced to Google Calendar events. The sync service was only using the global defaultReminderMinutes setting and ignoring task-specific reminders.

Implementation Details

1. Added ISO 8601 Duration Parser

Added parseISO8601Duration() method to parse reminder offset strings like -PT15M, -PT1H, -P1D into milliseconds.

2. Created Reminder Conversion Utility

Added convertTaskRemindersToGoogleFormat() method that:

  • Converts task reminders (both relative and absolute types) to Google Calendar API format
  • Handles relative reminders (e.g., "15 minutes before scheduled date")
  • Handles absolute reminders (e.g., "2026-01-24T09:00:00")
  • Filters out invalid reminders (e.g., reminders after the event, mismatched date anchors)
  • Caps reminders at Google Calendar's limit (40,320 minutes = 4 weeks)
  • Returns array of { method: 'popup', minutes: number } objects

3. Updated Event Builder

Modified taskToCalendarEvent() method to:

  • Determine which date field (due or scheduled) was used for the event
  • Convert task reminders using the new utility
  • Prioritize task-specific reminders over the default setting
  • Fall back to defaultReminderMinutes if no task reminders exist

How Reminders Are Converted

Relative Reminders

  • Format: { type: 'relative', relatedTo: 'due'|'scheduled', offset: '-PT15M' }
  • Only included if relatedTo matches the event's date source
  • Negative offset (e.g., -PT15M) = reminder before event
  • Positive offset = skipped (Google Calendar doesn't support reminders after events)
  • Converted to minutes before the event

Absolute Reminders

  • Format: { type: 'absolute', absoluteTime: '2026-01-24T09:00:00' }
  • Calculate difference between absolute time and event start
  • Converted to minutes before the event
  • Skipped if absolute time is after the event start

Testing Guide

Test Case 1: Task with Relative Reminder (Scheduled)

  1. Create a task with:
    • scheduled: 2026-01-25T10:00:00
    • reminders:
      • type: relative
      • relatedTo: scheduled
      • offset: -PT15M
  2. Sync to Google Calendar
  3. Expected: Event should have a reminder 15 minutes before 10:00 AM

Test Case 2: Task with Relative Reminder (Due)

  1. Create a task with:
    • due: 2026-01-25
    • reminders:
      • type: relative
      • relatedTo: due
      • offset: -PT1H
  2. Sync to Google Calendar
  3. Expected: Event should have a reminder 1 hour before the event

Test Case 3: Task with Absolute Reminder

  1. Create a task with:
    • scheduled: 2026-01-25T14:00:00
    • reminders:
      • type: absolute
      • absoluteTime: 2026-01-25T13:30:00
  2. Sync to Google Calendar
  3. Expected: Event should have a reminder 30 minutes before (at 1:30 PM)

Test Case 4: Task with Multiple Reminders

  1. Create a task with:
    • scheduled: 2026-01-25T15:00:00
    • reminders:
      • Reminder 1: { type: relative, relatedTo: scheduled, offset: -PT5M }
      • Reminder 2: { type: relative, relatedTo: scheduled, offset: -PT1H }
  2. Sync to Google Calendar
  3. Expected: Event should have two reminders (5 minutes and 1 hour before)

Test Case 5: Task with Mismatched Reminder (Should Ignore)

  1. Create a task with:
    • due: 2026-01-25 (event based on due date)
    • reminders:
      • type: relative
      • relatedTo: scheduled (but no scheduled date)
      • offset: -PT15M
  2. Sync to Google Calendar with syncTrigger: due
  3. Expected: Reminder should be ignored, falls back to defaultReminderMinutes

Test Case 6: Task with No Reminders (Fallback to Default)

  1. Create a task with:
    • scheduled: 2026-01-25
    • No reminders field
  2. Sync to Google Calendar
  3. Expected: Uses defaultReminderMinutes setting (if configured)

Verification in Google Calendar

After syncing, open the event in Google Calendar and check:

  1. Click on the event to open details
  2. Look for "Notifications" or "Reminders" section
  3. Verify the correct number of reminders exist
  4. Verify each reminder has the correct time offset

Edge Cases Handled

  1. Invalid duration format: Logged warning, reminder skipped
  2. Reminder after event: Logged warning, reminder skipped
  3. Absolute time after event start: Logged warning, reminder skipped
  4. Invalid timestamps: Logged warning, reminder skipped
  5. Reminders exceeding Google's limit: Capped at 40,320 minutes (4 weeks)
  6. Empty or null reminders array: Falls back to default setting

Files Modified

  • src/services/TaskCalendarSyncService.ts
    • Added parseISO8601Duration() method (lines ~336-362)
    • Added convertTaskRemindersToGoogleFormat() method (lines ~364-473)
    • Updated taskToCalendarEvent() reminder logic (lines ~544-571)

Build Status

✅ TypeScript compilation successful
✅ No linter errors
✅ Build completed successfully

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant