module.exports = function(RED){ const dav = require('dav') const IcalExpander = require('ical-expander') const moment = require('moment') const https = require('https') function NextcloudCalDav (config) { RED.nodes.createNode(this, config) this.server = RED.nodes.getNode(config.server) this.calendar = config.calendar this.pastWeeks = config.pastWeeks || 0 this.futureWeeks = config.futureWeeks || 4 const node = this node.on('input', (msg) => { let startDate = moment().startOf('day').subtract(this.pastWeeks, 'weeks') let endDate = moment().endOf('day').add(this.futureWeeks, 'weeks') const filters = [{ type: 'comp-filter', attrs: { name: 'VCALENDAR' }, children: [{ type: 'comp-filter', attrs: { name: 'VEVENT' }, children: [{ type: 'time-range', attrs: { start: startDate.format('YYYYMMDD[T]HHmmss[Z]'), end: endDate.format('YYYYMMDD[T]HHmmss[Z]') } }] }] }] // dav.debug.enabled = true; const xhr = new dav.transport.Basic( new dav.Credentials({ username: node.server.credentials.user, password: node.server.credentials.pass }) ) // Server + Basepath let calDavUri = node.server.address + '/remote.php/dav/calendars/' // User calDavUri += node.server.credentials.user + '/' dav.createAccount({ server: calDavUri, xhr: xhr, loadCollections: true, loadObjects: true }) .then(function (account) { if (!account.calendars) { node.error('Nextcloud:CalDAV -> no calendars found.') return } // account instanceof dav.Account account.calendars.forEach(function (calendar) { // Wenn Kalender gesetzt ist, dann nur diesen abrufen let calName = msg.calendar || node.calendar if (!calName || !calName.length || (calName && calName.length && calName === calendar.displayName)) { dav.listCalendarObjects(calendar, { xhr: xhr, filters: filters }) .then(function (calendarEntries) { let msg = { 'payload': { 'name': calendar.displayName, 'data': [] } } calendarEntries.forEach(function (calendarEntry) { try { const ics = calendarEntry.calendarData const icalExpander = new IcalExpander({ ics, maxIterations: 100 }) const events = icalExpander.between(startDate.toDate(), endDate.toDate()) msg.payload.data = msg.payload.data.concat(convertEvents(events)) } catch (error) { node.error('Error parsing calendar data: ' + error) } }) node.send(msg) }, function () { node.error('Nextcloud:CalDAV -> get ics went wrong.') }) } }) }, function () { node.error('Nextcloud:CalDAV -> get calendars went wrong.') }) }) function convertEvents (events) { const mappedEvents = events.events.map(_convertEvent) const mappedOccurrences = events.occurrences.map(_convertEvent) return [].concat(mappedEvents, mappedOccurrences) } function _convertEvent (e) { if (e) { let startDate = e.startDate.toString() let endDate = e.endDate.toString() if (e.item) { e = e.item } if (e.duration.wrappedJSObject) { delete e.duration.wrappedJSObject } return { startDate: startDate, endDate: endDate, summary: e.summary || '', description: e.description || '', attendees: e.attendees, duration: e.duration.toICALString(), durationSeconds: e.duration.toSeconds(), location: e.location || '', organizer: e.organizer || '', uid: e.uid || '', isRecurring: false, allDay: ((e.duration.toSeconds() % 86400) === 0) } } } } RED.nodes.registerType('nextcloud-caldav', NextcloudCalDav) }