ics

iCal (ics) file generator

  • ics

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
ics
686263.7.25 months ago10 years agoMinified + gzip package size for ics in KB

Readme

ics
The iCalendar generator
npm version TravisCI build status Downloads

Install

npm install -S ics

Example Usage

In node / CommonJS

1) Create an iCalendar event:
const ics = require('ics')
// or, in ESM: import * as ics from '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)
})
// BEGIN:VCALENDAR
// VERSION:2.0
// CALSCALE:GREGORIAN
// PRODID:adamgibbons/ics
// METHOD:PUBLISH
// X-PUBLISHED-TTL:PT1H
// BEGIN:VEVENT
// UID:S8h0Vj7mTB74p9vt5pQzJ
// SUMMARY:Bolder Boulder
// DTSTAMP:20181017T204900Z
// DTSTART:20180530T043000Z
// DESCRIPTION:Annual 10-kilometer run in Boulder\, Colorado
// X-MICROSOFT-CDO-BUSYSTATUS:BUSY
// URL:http://www.bolderboulder.com/
// GEO:40.0095;105.2669
// LOCATION:Folsom Field, University of Colorado (finish line)
// STATUS:CONFIRMED
// CATEGORIES:10k races,Memorial Day Weekend,Boulder CO
// ORGANIZER;CN=Admin:mailto:Race@BolderBOULDER.com
// ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Adam Gibbons:mailto:adam@example.com
// ATTENDEE;RSVP=FALSE;ROLE=OPT-PARTICIPANT;DIR=https://linkedin.com/in/brittanyseaton;CN=Brittany
//   Seaton:mailto:brittany@example2.org
// DURATION:PT6H30M
// END:VEVENT
// END:VCALENDAR

2) Write an iCalendar file:
const { writeFileSync } = require('fs')
const ics = require('ics')

ics.createEvent({
  title: 'Dinner',
  description: 'Nightly thing I do',
  busyStatus: 'FREE',
  start: [2018, 1, 15, 6, 30],
  duration: { minutes: 50 }
}, (error, value) => {
  if (error) {
    console.log(error)
  }

  writeFileSync(`${__dirname}/event.ics`, value)
})

3) Create multiple iCalendar events:
const ics = require('./dist')

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)
// BEGIN:VCALENDAR
// VERSION:2.0
// CALSCALE:GREGORIAN
// PRODID:adamgibbons/ics
// METHOD:PUBLISH
// X-PUBLISHED-TTL:PT1H
// BEGIN:VEVENT
// UID:pP83XzQPo5RlvjDCMIINs
// SUMMARY:Lunch
// DTSTAMP:20230917T142209Z
// DTSTART:20180115T121500Z
// DURATION:PT45M
// END:VEVENT
// BEGIN:VEVENT
// UID:gy5vfUVv6wjyBeNkkFmBX
// SUMMARY:Dinner
// DTSTAMP:20230917T142209Z
// DTSTART:20180115T121500Z
// DURATION:PT1H30M
// END:VEVENT
// END:VCALENDAR

4) Create iCalendar events with Audio (Mac):
let ics = require("ics")
let moment = require("moment")
let events = []
let alarms = []

let start = moment().format('YYYY-M-D-H-m').split("-").map((a) => parseInt(a))
let end = moment().add({'hours':2, "minutes":30}).format("YYYY-M-D-H-m").split("-").map((a) => parseInt(a))

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: start,
  end: end,
  title: "test here",
  alarms: alarms
}
events.push(event)
console.log(ics.createEvents(events).value)

// BEGIN:VCALENDAR
// VERSION:2.0
// CALSCALE:GREGORIAN
// PRODID:myCalendarId
// METHOD:PUBLISH
// X-PUBLISHED-TTL:PT1H
// BEGIN:VEVENT
// UID:123@ics.com
// SUMMARY:test here
// DTSTAMP:20230917T142621Z
// DTSTART:20230917T152600
// DTEND:20230917T175600
// BEGIN:VALARM
// ACTION:AUDIO
// REPEAT:2
// DESCRIPTION:Reminder
// ATTACH;VALUE=URI:Glass
// TRIGGER:-PT2H30M\nEND:VALARM
// END:VEVENT
// END:VCALENDAR

Using ESModules & in the browser

import { createEvent} from 'ics';

const event = {
  ...
}

async function handleDownload() {
  const filename = 'ExampleEvent.ics'
  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);

  // trying to assign the file URL to a window could cause cross-site
  // issues so this is a workaround using HTML5
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = filename;

  document.body.appendChild(anchor);
  anchor.click();
  document.body.removeChild(anchor);

  URL.revokeObjectURL(url);
}

API

createEvent(attributes[, callback])

Generates an iCal-compliant VCALENDAR string with one VEVENT. If a callback is not provided, returns an object having the form { error, value }, where value contains an iCal-compliant string if there are no errors. If a callback is provided, returns a Node-style callback.

attributes

Object literal containing event information. Only the start property is required.
Note all date/time fields can be the array form, or a number representing the unix timestamp in milliseconds (e.g. getTime() on a Date).
The following properties are accepted:
| Property | Description | Example | | ------------- | ------------- | ---------- | start | Required. Date and time at which the event begins. | [2000, 1, 5, 10, 0] (January 5, 2000) or a number | startInputType | Type of the date/time data in start:
local (default): passed data is in local time.
utc: passed data is UTC | | startOutputType | Format of the start date/time in the output:
utc (default): the start date will be sent in UTC format.
local: the start date will be sent as "floating" (form #1 in RFC 5545) | | end | Time at which event ends. Either end or duration is required, but not both. | [2000, 1, 5, 13, 5] (January 5, 2000 at 1pm) or a number | endInputType | Type of the date/time data in end:
local: passed data is in local time.
utc: passed data is UTC.
The default is the value of startInputType | | endOutputType | Format of the start date/time in the output:
utc: the start date will be sent in UTC format.
local: the start date will be sent as "floating" (form #1 in RFC 5545).
The default is the value of startOutputType | | duration | How long the event lasts. Object literal having form { weeks, days, hours, minutes, seconds } Either end or duration is required, but not both. | { hours: 1, minutes: 45 } (1 hour and 45 minutes) | title | Title of event. | 'Code review' | description | Description of event. | 'A constructive roasting of those seeking to merge into master branch' | location | Intended venue | Mountain Sun Pub and Brewery | geo | Geographic coordinates (lat/lon) | { lat: 38.9072, lon: 77.0369 } | url | URL associated with event | 'http://www.mountainsunpub.com/' | status | Three statuses are allowed: TENTATIVE, CONFIRMED, CANCELLED | CONFIRMED | organizer | Person organizing the event | { name: 'Adam Gibbons', email: 'adam@example.com', dir: 'https://linkedin.com/in/adamgibbons', sentBy: 'test@example.com' } | attendees | Persons invited to the event | [{ name: 'Mo', email: 'mo@foo.com', rsvp: true }, { name: 'Bo', email: 'bo@bar.biz', dir: 'https://twitter.com/bo1234', partstat: 'ACCEPTED', role: 'REQ-PARTICIPANT' }] | categories | Categories associated with the event | ['hacknight', 'stout month'] | alarms | Alerts that can be set to trigger before, during, or after the event. The following attach properties work on Mac OS: Basso, Blow, Bottle, Frog, Funk, Glass, Hero, Morse, Ping, Pop, Purr, Sousumi, Submarine, Tink | { action: 'display', description: 'Reminder', trigger: [2000, 1, 4, 18, 30] } OR { action: 'display', description: 'Reminder', trigger: { hours: 2, minutes: 30, before: true } } OR { action: 'display', description: 'Reminder', trigger: { hours: 2, minutes: 30, before: false } OR { action: 'audio', description: 'Reminder', trigger: { hours: 2, minutes: 30, before: true }, repeat: 2, attachType: 'VALUE=URI', attach: 'Glass' } | productId | Product which created ics, PRODID field | 'adamgibbons/ics' | uid | Universal unique id for event, produced by default with nanoid. Warning: This value must be globally unique. It is recommended that it follow the RFC 822 addr-spec (i.e. localpart@domain). Including the @domain half is a good way to ensure uniqueness. | 'LZfXLFzPPR4NNrgjlWDxn' | method | This property defines the iCalendar object method associated with the calendar object. When used in a MIME message entity, the value of this property MUST be the same as the Content-Type "method" parameter value. If either the "METHOD" property or the Content-Type "method" parameter is specified, then the other MUST also be specified. | PUBLISH | recurrenceRule | A recurrence rule, commonly referred to as an RRULE, defines the repeat pattern or rule for to-dos, journal entries and events. If specified, RRULE can be used to compute the recurrence set (the complete set of recurrence instances in a calendar component). You can use a generator like this one. | FREQ=DAILY | exclusionDates | Array of date-time exceptions for recurring events, to-dos, journal entries, or time zone definitions. | [[2000, 1, 5, 10, 0], [2000, 2, 5, 10, 0]] OR [1694941727477, 1694945327477] | sequence | For sending an update for an event (with the same uid), defines the revision sequence number. | 2 | busyStatus | Used to specify busy status for Microsoft applications, like Outlook. See Microsoft spec. | 'BUSY' OR 'FREE' OR 'TENTATIVE' OR 'OOF' | transp | Used to specify event transparency (does event consume actual time of an individual). Used by Google Calendar to determine if event should change attendees availability to 'Busy' or not. | 'TRANSPARENT' OR 'OPAQUE' | classification | This property defines the access classification for a calendar component. See iCalender spec. | 'PUBLIC' OR 'PRIVATE' OR 'CONFIDENTIAL' OR any non-standard string | created | Date-time representing event's creation date. Provide a date-time in local time | [2000, 1, 5, 10, 0] or a number | lastModified | Date-time representing date when event was last modified. Provide a date-time in local time | 2000, 1, 5, 10, 0 or a number | calName | Specifies the calendar (not event) name. Used by Apple iCal and Microsoft Outlook; see Open Specification | 'Example Calendar' | | htmlContent | Used to include HTML markup in an event's description. Standard DESCRIPTION tag should contain non-HTML version. | <!DOCTYPE html><html><body><p>This is<br>test<br>html code.</p></body></html> |
To create an all-day event, pass only three values (year, month, and date) to the start and end properties. The date of the end property should be the day after your all-day event. For example, in order to create an all-day event occuring on October 15, 2018:
const eventAttributes = {
  start: [2018, 10, 15],
  end: [2018, 10, 16],
  /* rest of attributes */
}

callback

Optional. Node-style callback.
function (err, value) {
  if (err) {
    // if iCal generation fails, err is an object containing the reason
    // if iCal generation succeeds, err is null
  }

  console.log(value) // iCal-compliant text string
}

createEvents(events[, headerParams, callback])

Generates an iCal-compliant VCALENDAR string with multiple VEVENTS.
headerParams may be omitted, and in this case they will be read from the first event.
If a callback is not provided, returns an object having the form { error, value }, where value is an iCal-compliant text string if error is null.
If a callback is provided, returns a Node-style callback.

events

Array of attributes objects (as described in createEvent).

callback

Optional. Node-style callback.
function (err, value) {
  if (err) {
    // if iCal generation fails, err is an object containing the reason
    // if iCal generation succeeds, err is null
  }

  console.log(value) // iCal-compliant text string
}

Develop

Run mocha tests and watch for changes:
npm start

Run tests once and exit:
npm test

Build the project, compiling all ES6 files within the src directory into vanilla JavaScript in the dist directory.
npm run build

References