ics

repository·master·Indexed 21 days ago

https://github.com/adamgibbons/ics

An iCalendar (.ics) file generator for Node.js and the browser. It provides functionality to programmatically create single or multiple events using createEvent(), createEvents(), and createEventsAsync(). The library supports event attributes such as attendees, organizers, alarms, recurrence rules, and geographic coordinates, and includes an asynchronous method optimized for large batches of events to prevent blocking the main thread.

Tokens
5.7K
Snippets
17
Records
20
Agent score
74%

What's inside ics

  1. How to format Date-Time values for iCalendar

    master

    When working with iCalendar (RFC5545) properties like DTSTART or DTEND, time values can be expressed in three distinct forms. Choosing the correct form depends on whether you are using local time, UTC, or a specific time zone reference.

    1. Local Time: Use this for 'floating' time where no specific time zone is attached.
    2. UTC Time: Append a Z to the end of the timestamp to indicate UTC.
    3. Local Time with Time Zone Reference: Use the TZID parameter to specify a time zone (e.g., America/New_York).

    Note: The TZID parameter MUST NOT be applied to DATE properties or properties already specified in UTC.

    // FORM #1: DATE WITH LOCAL TIME
    19980118T230000
    
    // FORM #2: DATE WITH UTC TIME
    19980119T070000Z
    
    // FORM #3: DATE WITH LOCAL TIME AND TIME ZONE REFERENCE
    TZID=America/New_York:19980119T020000
  2. Download an iCalendar file in the browser

    master

    When using ics in a frontend environment (like React), you cannot use the fs module. Instead, generate the iCalendar string and use a Blob and a temporary anchor element to trigger a download.

    If using a library like file-saver, you can use saveAs(blob, filename).

    import { createEvent } from 'ics';
    
    async function handleDownload() {
      const filename = 'ExampleEvent.ics';
      const event = {
        title: 'Example',
        start: [2023, 1, 1, 12, 0],
        duration: { minutes: 30 }
      };
    
      const file = await new Promise((resolve, reject) => {
        createEvent(event, (error, value) => {
          if (error) {
            reject(error);
          }
          resolve(new File([value], filename, { type: 'text/calendar' }));
        });
      });
    
      const url = URL.createObjectURL(file);
      const anchor = document.createElement('a');
      anchor.href = url;
      anchor.download = filename;
    
      document.body.appendChild(anchor);
      anchor.click();
      document.body.removeChild(anchor);
    
      URL.revokeObjectURL(url);
    }
  3. Develop the ics project

    master

    If you are contributing to the ics repository, use the following commands:

    Run tests and watch for changes:

    npm start

    Run tests once:

    npm test

    Build the project: Compiles ES6 files from src/ into vanilla JavaScript in dist/.

    npm run build
  4. Add alarms to iCalendar events

    master

    You can add alarms to events by including an alarms array in the event object. Each alarm object can specify an action (e.g., 'audio'), a description, a trigger (using hours, minutes, and before), and repeat counts. For audio alarms on Mac, you can use attachType: 'VALUE=URI' and an attach property.

    let ics = require("ics")
    let alarms = []
    
    // Example alarm configuration
    alarms.push({
      action: 'audio',
      description: 'Reminder',
      trigger: {hours:2,minutes:30,before:true},
      repeat: 2,
      attachType:'VALUE=URI',
      attach: 'Glass'
    })
    
    let event = {
      productId:"myCalendarId",
      uid: "123" + "@ics.com",
      startOutputType:"local",
      start: [2023, 9, 17, 15, 26],
      end: [2023, 9, 17, 17, 56],
      title: "test here",
      alarms: alarms
    }
    
    console.log(ics.createEvents([event]).value)
  5. Create a single iCalendar event with createEvent()

    master

    Use createEvent(attributes, callback) to generate an iCalendar string for a single event. The attributes object can include details like start, duration, title, description, location, url, geo, categories, status, busyStatus, organizer, and attendees.

    Note: The start attribute expects an array in the format [year, month, day, hour, minute].

    const ics = require('ics')
    
    const event = {
      start: [2018, 5, 30, 6, 30],
      duration: { hours: 6, minutes: 30 },
      title: 'Bolder Boulder',
      description: 'Annual 10-kilometer run in Boulder, Colorado',
      location: 'Folsom Field, University of Colorado (finish line)',
      url: 'http://www.bolderboulder.com/',
      geo: { lat: 40.0095, lon: 105.2669 },
      categories: ['10k races', 'Memorial Day Weekend', 'Boulder CO'],
      status: 'CONFIRMED',
      busyStatus: 'BUSY',
      organizer: { name: 'Admin', email: 'Race@BolderBOULDER.com' },
      attendees: [
        { name: 'Adam Gibbons', email: 'adam@example.com', rsvp: true, partstat: 'ACCEPTED', role: 'REQ-PARTICIPANT' },
        { name: 'Brittany Seaton', email: 'brittany@example2.org', dir: 'https://linkedin.com/in/brittanyseaton', role: 'OPT-PARTICIPANT' }
      ]
    }
    
    ics.createEvent(event, (error, value) => {
      if (error) {
        console.log(error)
        return
      }
    
      console.log(value)
    })
  6. Create multiple iCalendar events with createEvents()

    master

    Use createEvents(events, headerParams, callback) to generate a single iCalendar file containing multiple events.

    • events: An array of event attribute objects.
    • headerParams: (Optional) An object containing calendar header parameters, such as calName.
    const ics = require('ics')
    
    const { error, value } = ics.createEvents([
      {
        title: 'Lunch',
        start: [2018, 1, 15, 12, 15],
        duration: { minutes: 45 }
      },
      {
        title: 'Dinner',
        start: [2018, 1, 15, 12, 15],
        duration: { hours: 1, minutes: 30 }
      }
    ])
    
    if (error) {
      console.log(error)
      return
    }
    
    console.log(value)
  7. Generate multiple iCal events asynchronously with `createEventsAsync()`

    master

    createEventsAsync(events[, headerAttributes]) is the async variant of createEvents. It returns a Promise that resolves to an object { error, value }.

    Performance Note: This method is optimized for large batches. It yields to the event loop during iteration to prevent freezing the process and builds the output in parts to reduce string concatenation overhead.

    • events: An array of attribute objects.
    • headerAttributes (optional): An object merged with the first event (if events is not empty) to build the calendar header. If events is empty, headerAttributes is used alone to build the header.
    const { createEventsAsync } = require('ics');
    
    const events = [
      { start: [2000, 1, 5, 10, 0], duration: { hours: 1 }, title: 'Event 1' }
    ];
    
    async function run() {
      const { error, value } = await createEventsAsync(events);
      if (!error) console.log(value);
    }
  8. Create multiple events asynchronously with createEventsAsync()

    master

    For large batches of events, use createEventsAsync(events, headerAttributes). This method returns a Promise that resolves to { error, value }.

    Unlike the synchronous version, createEventsAsync periodically yields to the event loop, preventing the generation process from blocking the Node.js or browser main thread for extended periods.

    const { createEventsAsync } = require('ics')
    
    async function run () {
      const { error, value } = await createEventsAsync([
        {
          title: 'Lunch',
          start: [2018, 1, 15, 12, 15],
          duration: { minutes: 45 }
        },
        {
          title: 'Dinner',
          start: [2018, 1, 15, 12, 15],
          duration: { hours: 1, minutes: 30 }
        }
      ])
    
      if (error) {
        console.log(error)
        return
      }
    
      console.log(value)
    }
    
    run()
  9. Generate multiple iCal events with `createEvents()`

    master

    Use createEvents(events[, headerParams, callback]) to generate an iCal-compliant VCALENDAR string containing multiple VEVENTs.

    • events: An array of attribute objects (the same shape used in createEvent).
    • headerParams (optional): Parameters for the calendar header. If omitted, they are read from the first event in the array.

    If no callback is provided, it returns { error, value }. If a callback is provided, it uses the Node-style function(err, value) pattern.

    const { createEvents } = require('ics');
    
    const events = [
      { start: [2000, 1, 5, 10, 0], duration: { hours: 1 }, title: 'Event 1' },
      { start: [2000, 1, 6, 10, 0], duration: { hours: 1 }, title: 'Event 2' }
    ];
    
    const { error, value } = createEvents(events);
    if (!error) console.log(value);
  10. Create a single iCal event with `createEvent()`

    master

    Use createEvent(attributes[, callback]) to generate an iCal-compliant VCALENDAR string containing a single VEVENT.

    If no callback is provided, the function returns an object: { error, value }. If a callback is provided, it follows the Node-style function(err, value) pattern.

    Key requirements for attributes:

    • start is required. It can be an array [year, month, day, hour, minute] or a Unix timestamp in milliseconds.
    • Either end or duration must be provided, but not both.
    • To create an all-day event, pass only [year, month, day] to start and end. The end date must be the day after the event.

    Example of an all-day event on October 15, 2018:

    const eventAttributes = {
      start: [2018, 10, 15],
      end: [2018, 10, 16],
      /* rest of attributes */
    }
    const { createEvent } = require('ics');
    
    // Using the return object pattern
    const { error, value } = createEvent({
      start: [2000, 1, 5, 10, 0],
      duration: { hours: 1 }
    });
    
    if (error) {
      console.error(error);
    } else {
      console.log(value);
    }
  11. Reference: `createEvent` attribute properties

    master

    The following properties are accepted in the attributes object for createEvent:

    PropertyDescriptionExample
    startRequired. Date/time event begins. Array [Y, M, D, H, M] or number (ms).[2000, 1, 5, 10, 0]
    startInputTypeType of start data: local (default) or utc.'utc'
    startOutputTypeFormat of output: utc (default) or local (floating).'local'
    endTime event ends. Either end or duration required.[2000, 1, 5, 13, 5]
    endInputTypeType of end data: local, utc, or defaults to startInputType.'utc'
    endOutputTypeFormat of output: utc, local, or defaults to startOutputType.'local'
    durationObject { weeks, days, hours, minutes, seconds }.{ hours: 1, minutes: 45 }
    titleTitle of event.'Code review'
    descriptionDescription of event.'A constructive roasting...'
    locationIntended venue.'Mountain Sun Pub'
    geoGeographic coordinates.{ lat: 38.9072, lon: 77.0369 }
    urlURL associated with event.'http://example.com/'
    statusTENTATIVE, CONFIRMED, or CANCELLED.'CONFIRMED'
    organizerPerson organizing.{ name: 'Adam', email: 'a@ex.com' }
    attendeesArray of persons invited.[{ name: 'Mo', email: 'm@f.com', rsvp: true }]
    categoriesArray of categories.['hacknight']
    alarmsAlerts. Supports action (display, audio), description, trigger (array, object, or timestamp), and attach (Mac OS specific).{ action: 'display', description: 'Remind', trigger: { hours: 2 } }
    productIdPRODID field.'adamgibbons/ics'
    uidGlobally unique ID. Recommended format: localpart@domain.'LZfXLFzPPR4NNrgjlWDxn'
    methodiCalendar object method (e.g., PUBLISH).'PUBLISH'
    recurrenceRuleRRULE string (e.g., FREQ=DAILY).'FREQ=DAILY'
    recurrenceIdDate-time for recurring event instances.[2000, 1, 5, 10, 0]
    exclusionDatesArray of date-time exceptions.[[2000, 1, 5, 10, 0]]
    sequenceRevision sequence number for updates.2
    busyStatusFor Microsoft apps: BUSY, FREE, TENTATIVE, OOF.'BUSY'
    transpTransparency: TRANSPARENT or OPAQUE.'TRANSPARENT'
    classificationPUBLIC, PRIVATE, CONFIDENTIAL, etc.'PUBLIC'
    createdEvent creation date (local time).[2000, 1, 5, 10, 0]
    lastModifiedLast modification date (local time).[2000, 1, 5, 10, 0]
    calNameCalendar name (for Apple/Outlook).'Example Calendar'
    htmlContentHTML markup for description.'<html>...</html>'