ics
v3.8.1
Published
iCal (ics) file generator
Downloads
627,313
Maintainers
Readme
ics
The iCalendar generator
Install
npm install -S ics
Example Usage
In node / CommonJS
- 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: '[email protected]' },
attendees: [
{ name: 'Adam Gibbons', email: '[email protected]', rsvp: true, partstat: 'ACCEPTED', role: 'REQ-PARTICIPANT' },
{ name: 'Brittany Seaton', email: '[email protected]', 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:[email protected]
// ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Adam Gibbons:mailto:[email protected]
// ATTENDEE;RSVP=FALSE;ROLE=OPT-PARTICIPANT;DIR=https://linkedin.com/in/brittanyseaton;CN=Brittany
// Seaton:mailto:[email protected]
// DURATION:PT6H30M
// END:VEVENT
// END:VCALENDAR
- 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)
/*
You cannot use fs in Frontend libraries like React so you rather import a module to save files to the browser as follow [ import { saveAs } from 'file-saver'; // For saving the file in the browser]
const blob = new Blob([value], { type: 'text/calendar' });
saveAs(blob, `${title}.ics`);
*/
})
- 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
- 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:[email protected]
// 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: '[email protected]', dir: 'https://linkedin.com/in/adamgibbons', sentBy: '[email protected]' }
| attendees | Persons invited to the event | [{ name: 'Mo', email: '[email protected]', rsvp: true }, { name: 'Bo', email: '[email protected]', 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