Skip to content
Skip to main content

Schedule reminders from calendar events

Calendar apps send push notifications to the person who owns the event. That’s fine if you only need to remind yourself. The moment your application needs to reach other people — patients before an appointment, students before a tutoring session, prospects before a demo — built-in notifications fall short. You need branded, personalized email reminders sent on behalf of your users.

This recipe builds that. A scheduled job scans a calendar for events starting soon, filters out the noise, and sends a tailored HTML reminder to each attendee. A webhook listener catches reschedules and cancellations and pushes updates the same way. The whole thing runs across Google Calendar, Microsoft, and Exchange without provider-specific code.

cron (every 15min) ─▶ list events for next 24h ─▶ filter (skip all-day, internal, already-sent)
send reminder email
event.updated/deleted webhook ─▶ look up sent reminder ─▶ send update or cancellation

Two flows around one shared dedup store. The cron handles proactive sends; the webhook handles reactive updates.

Make sure you have the following before starting this tutorial:

  • A Nylas account with an active application
  • A valid API key from your Nylas Dashboard
  • At least one connected grant (an authenticated user account) for the provider you want to work with
  • Node.js 18+ or Python 3.8+ installed (depending on which code samples you follow)

You also need:

  • A connected grant with calendar read access and email send access for the account you want to send reminders from
  • A calendar ID for the calendar you want to scan (use the List Calendars endpoint to find it)
  • A persistent store for tracking which events have already received reminders (a database table, Redis set, or even a local JSON file for prototyping)

Query the Nylas Calendar API for events in a time window. The Events API accepts start and end query parameters as Unix timestamps, so you can request exactly the window you care about. A 24-hour lookahead works well for most reminder systems.

Not every event deserves a reminder. All-day events (like holidays or out-of-office blocks) rarely need one. Events where you are the only participant are just calendar holds. And you definitely do not want to send the same reminder twice.

The key design decisions: track by event ID for deduplication, filter by when.object to distinguish timed events ("timespan") from all-day events ("date" or "datespan"), and exclude the organizer’s email so they do not receive their own reminder.

For each qualifying event, build a personalized email and send it through the Nylas Email API. Include the meeting title, time, location or conferencing link, and any agenda from the event description.

Use the POST /v3/grants/<NYLAS_GRANT_ID>/messages/send endpoint to deliver the reminder to each attendee.

Reminders are only useful if they reflect the current state of the event. When someone reschedules or cancels a meeting after you already sent a reminder, you need to notify attendees.

Subscribe to event.updated and event.deleted webhooks:

Then handle updates and cancellations. Only act on events you have already sent reminders for:

Tie the pieces together with a scheduled job. Use node-cron in Node.js or schedule in Python to run the scan every 15 minutes.

A few practical details that will save you time in production:

  • Timezone handling is the hardest part. Events include start_timezone and end_timezone fields, but not all providers populate them consistently. Always fall back to UTC if the timezone is missing, and format times using the event’s timezone rather than your server’s local time. An attendee in Tokyo does not want to see a time formatted for Chicago.

  • All-day events use a different when object. Timed events have when.object set to "timespan" with Unix timestamps. All-day events use "date" (single day) or "datespan" (multi-day) with date strings like "2024-03-15". Check the when.object value rather than looking for missing timestamps.

  • Recurring events produce separate instances. When you query the Events API with a time range, each occurrence of a recurring series appears as its own event with its own ID. You do not need to expand recurrence rules yourself. Track reminders by the individual occurrence ID, not the master_event_id.

  • Rate limits apply to both APIs. Nylas enforces rate limits per grant. If you are sending reminders for a calendar with dozens of events, add a small delay between email sends. For high-volume use cases, queue your sends and process them with a rate-limited worker.

  • Deduplication prevents double reminders. Your scan runs on a schedule, so the same event appears in multiple scans. Without deduplication, an attendee could receive the same reminder every 15 minutes. In production, store the event ID alongside a hash of key fields (time, title, participants) so you can detect whether the event changed enough to warrant a new notification.

  • Some providers sync with a delay. Google Calendar events typically appear in Nylas within seconds. Microsoft and Exchange accounts may take slightly longer. If your reminder window is narrow (for example, 30 minutes before the event), factor in sync latency to avoid missing recently created events.

  • Do not hardcode calendar IDs. The primary calendar ID varies by provider. Google uses the user’s email address. Microsoft uses a long opaque string. Use the List Calendars endpoint to discover calendars dynamically.