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 |
---|---|---|
BEGIN/END | Required | Denote the beginning and end of an entity (e.g., |
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., |
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: |
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.