Create Subscription Calendar on Node.js

Subscription Calendar is typically a URL pointing to an .ics file hosted online. Calendar applications fetch updates from this URL at regular intervals. So, if the content of the online .ics file changes (because new events are added or existing events are modified), subscribers will see these changes in their calendar applications after the next refresh.

Here is a sample .ics to display bid opening dates

BEGIN:VCALENDAR VERSION:2.0 PRODID:-//SanJoseCA//Calendar 1.0//EN CALSCALE:GREGORIAN BEGIN:VEVENT UID:project-10334@sanjoseca.gov SUMMARY:SJC New Belly Freight Facility and Receiving Center DESCRIPTION:Project Manager: De Guzman, Chris DTSTART:20231109T110000 END:VEVENT BEGIN:VEVENT UID:project-10232@sanjoseca.gov SUMMARY:SJC Terminal A Baggage Claim Escalators Replacement DESCRIPTION:Project Manager: Ancheta, Lorimer DTSTART:20230622T110000 END:VEVENT BEGIN:VEVENT UID:project-10223@sanjoseca.gov SUMMARY:BUILDING: Emergency Interim Shelter Rue Ferrari Expansion DESCRIPTION:Project Manager: Castellanos, Francisco DTSTART:20231020T110000 END:VEVENT BEGIN:VEVENT UID:project-10131@sanjoseca.gov SUMMARY:SJC Admin Parking Lot Safety Upgrades DESCRIPTION:Project Manager: Ancheta, Lorimer DTSTART:20230810T110000 END:VEVENT BEGIN:VEVENT UID:project-10128@sanjoseca.gov SUMMARY:PARK: BUNDLE - 9500 Hamann Tot Lot & 10121 Starbird Park Renovations DESCRIPTION:Project Manager: Castellanos, Sarah DTSTART:20230713T110000 END:VEVENT BEGIN:VEVENT UID:project-10073@sanjoseca.gov SUMMARY:Sanitary Sewer Condition Assessment FY 2022-2023 Package II DESCRIPTION:Project Manager: Nguyen, Donie DTSTART:20231109T110000 END:VEVENT BEGIN:VEVENT UID:project-10071@sanjoseca.gov SUMMARY:Sanitary Sewer Condition Assessment FY 2022-2023 Package I DESCRIPTION:Project Manager: Franso, Linda DTSTART:20231012T110000 END:VEVENT BEGIN:VEVENT UID:project-10068@sanjoseca.gov SUMMARY:TRAIL: Coyote Creek (I-280 Undercrossing Lighting) DESCRIPTION:Project Manager: Correa, Leila DTSTART:20230928T110000 END:VEVENT BEGIN:VEVENT UID:project-10027@sanjoseca.gov SUMMARY:En Movimiento Bicycle Boulevards- STPL-5005(167) DESCRIPTION:Project Manager: Leon, Diego DTSTART:20231109T110000 END:VEVENT BEGIN:VEVENT UID:project-9998@sanjoseca.gov SUMMARY:Rule 20B Underground District - Delmas/West San Fernando DESCRIPTION:Project Manager: Simonis, David DTSTART:20230810T110000 END:VEVENT END:VCALENDAR

Use Node.js to create a dynamic iCalendar:

function formatDate(dateString) { let [month, day, year] = dateString.split('/'); return `${year}${month}${day}T110000`; // The time is hardcoded to 11:00:00 } app.get('/calendar-feed', (req, res) => { // Sample data - replace with database data let projects = [ { id: 10334, name: "SJC New Belly Freight Facility and Receiving Center", manager: "De Guzman, Chris", date: "11/09/2023" }, // ... other projects ]; let icsContent = `BEGIN:VCALENDAR VERSION:2.0 PRODID:-//SanJoseCA//Calendar 1.0//EN CALSCALE:GREGORIAN `; projects.forEach(project => { // Outputs something like "20231109T110000" let startDate = formatDate(project.date); icsContent += `BEGIN:VEVENT UID:project-${project.id}@sanjoseca.gov SUMMARY:${project.name} DESCRIPTION:Project Manager: ${project.manager} DTSTART:${startDate} END:VEVENT `; }); icsContent += "END:VCALENDAR"; icsContent = icsContent.replace(/\n +/g, '\n'); // Remove spaces after \n res.setHeader('Content-Type', 'text/calendar'); res.setHeader('Content-Disposition', 'inline; filename=calendar.ics'); res.send(icsContent); // Send dynamic calendar back });

Common iCalendar fields

Field

Type

Description

Field

Type

Description

BEGIN/END

Required

Denote the beginning and end of an entity (e.g., VCALENDAR, VEVENT).

VERSION

Required

Specifies the version of the iCalendar specification.

PRODID

Required

Identifier for the product that created the iCalendar object.

UID

Required

A unique identifier for the event.

DTSTAMP

Required

Represents the date and time the iCalendar object was created.

SUMMARY

Optional

A brief description or title of the event.

DESCRIPTION

Optional

Detailed description of the event.

DTSTART

Optional

The start date/time of the event.

DTEND

Optional

The end date/time of the event.

LOCATION

Optional

Intended venue for the event.

RRULE

Optional

Recurrence rules for recurring events.

ATTENDEE

Optional

Specifies an attendee, often with an email address.

ORGANIZER

Optional

Specifies the organizer of the event, often with an email address.

URL

Optional

A URL associated with the event.

STATUS

Optional

Overall status or confirmation for the calendar entity (e.g., CONFIRMED, TENTATIVE).

CATEGORIES

Optional

Categories or subtypes of the calendar entity.

PRIORITY

Optional

Relative priority of a calendar entity (0 to 9).

TRANSP

Optional

Defines if the event shows as "busy" or "free". Common values: TRANSPARENT, OPAQUE.

ALARMS

Optional

Defines a reminder or an alarm for the event.

This table provides a high-level overview of some common iCalendar fields. For more detailed information, you would want to consult the official iCalendar specification (RFC 5545).

To gain a deeper understanding of these fields, consider exporting an .ics file from Outlook. By examining its contents, you can familiarize yourself with the various iCalendar fields in a practical context.