# Exporting ICS calendar using endpoint

**URL:** <https://community.integray.com/t/exporting-ics-calendar-using-endpoint/214>\
**Category:** Handy solutions\
**Tags:** endpoint, nodejs, ical\
**Created:** [November 1, 2023, 2:47pm UTC](https://community.integray.com/t/exporting-ics-calendar-using-endpoint/214 "2023-11-01T14:47:05Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![libor.zoubek](https://avatars.discourse-cdn.com/v4/letter/l/58f4c7/32.png) [@libor.zoubek](https://community.integray.com/u/libor.zoubek)\
**Post date:** [November 1, 2023, 2:47pm UTC](https://community.integray.com/t/exporting-ics-calendar-using-endpoint/214/1 "2023-11-01T14:47:05Z")

</div>

Hello,

In our company, we have an internal system where employees request (and get approved) their vacation. Internal system provides data about approved vacations across teams.

**Requirement**

Export all vacations into a single calendar, that can be subscribed by my cell phone

**Solution**

Integray provides more solutions. You can use for example [ICS Writer Connector](https://learn.integray.app/connectoracademy/connectors/ICSWriterConnector) to produce ICS content, but i chose easier way (although it required some Javascript coding)

1. Create **Task** with following steps
  1. Load vacation data from internal system
  2. Transform data into ICS format

2. Bind such task to Integray **Endpoint** using GET method
3. Copy endpoint URL and subscribe to it in **any** calendar application

**Task**

First step of this task pretty much depends on our internal system’s ability to provide data and it’s detail is out of scope of this solution

As a second step I used [Node.js processor](https://learn.integray.app/connectoracademy/connectors/NodeJS) to transform vacations into ICS format and produce **Endpoint File Output** output schema.

```javascript
// loaded from previous step
const loaded = inputData[0].ContentJSON;
/*
loaded data is returned from internal system and contains array of vacations in following schema
[
   {
      "start": "2023-11-01T14:27:23.130Z", // vacation start date
      "end": "2023-11-01T14:27:23.130Z", // vacation end date
      "title": "Libor Zoubek", // employee name
   }
]
*/

/**
* format date to ICS date
*/
function formatDateToICal(date) {
  date = new Date(date);
  const year = date.getUTCFullYear();
  const month = String(date.getUTCMonth() + 1).padStart(2, '0'); // Months are zero-based
  const day = String(date.getUTCDate()).padStart(2, '0');
  const hours = String(date.getUTCHours()).padStart(2, '0');
  const minutes = String(date.getUTCMinutes()).padStart(2, '0');
  const seconds = String(date.getUTCSeconds()).padStart(2, '0');

  return `${year}${month}${day}T${hours}${minutes}${seconds}Z`;
}

// transform vacations into ICS events
const events = loaded.map((e) => {
  const now = formatDateToICal(new Date());
  // each event must have some uniqueID, as our system does not expose it
  // it should be sufficient to calculate hash from `start`,`end` and `title`
  const hash = crypto.createHash('sha256');
  hash.update(`${e.start}${e.end}${e.title}`);
  return `BEGIN:VEVENT
DTSTART:${formatDateToICal(e.start)}
DTEND:${formatDateToICal(e.end)}
DTSTAMP:${now}
UID:${hash.digest('hex')}
CREATED:${now}
LAST-MODIFIED:${now}
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:${e.title} - Vacation
TRANSP:OPAQUE
END:VEVENT
  `;
})

// create ICS text content
const ics = `
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:Integray team
X-WR-TIMEZONE:Europe/Prague
X-WR-CALDESC:Integray team vacation
BEGIN:VTIMEZONE
TZID:Europe/Prague
X-LIC-LOCATION:Europe/Prague
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
${events.join('\n')}
END:VCALENDAR
`;
// return as `Endpoint File Output` schema
return [{ Name: 'calendar.ics', Data: Buffer.from(ics).toString('base64') }]

```

**Endpoint**

Endpoint binding is easy to do, the only important thing is to select **Endpoint File Output** output schema

Voila … I am subscribed to vacations of all team members 😍
