n8n-nodes-nextcloud-calendar
Version:
n8n Node für die Integration mit Nextcloud Calendar
284 lines • 10.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.searchEvents = exports.deleteEvent = exports.updateEvent = exports.createEvent = exports.getEvent = exports.getEvents = void 0;
const client_1 = require("../helpers/client");
const calendar_1 = require("./calendar");
const parser_1 = require("../helpers/parser");
async function getEvents(context, calendarName, start, end) {
const client = await (0, client_1.initClient)(context);
const calendar = await (0, calendar_1.findCalendar)(context, client, calendarName);
const response = await client.fetchCalendarObjects({
calendar,
timeRange: {
start: start,
end: end,
},
});
return response.map(parser_1.parseICalEvent);
}
exports.getEvents = getEvents;
async function getEvent(context, calendarName, eventId) {
const client = await (0, client_1.initClient)(context);
const calendar = await (0, calendar_1.findCalendar)(context, client, calendarName);
const events = await client.fetchCalendarObjects({
calendar,
filters: [{
'comp-filter': {
_attributes: {
name: 'VCALENDAR',
},
'comp-filter': {
_attributes: {
name: 'VEVENT',
test: 'allof',
},
'prop-filter': {
_attributes: {
name: 'UID',
test: 'equals',
},
'text-match': {
_attributes: {
'match-type': 'equals',
},
_text: eventId,
},
},
},
},
}],
});
if (!events || events.length === 0) {
throw new Error(`Event with ID "${eventId}" not found`);
}
return (0, parser_1.parseICalEvent)(events[0]);
}
exports.getEvent = getEvent;
async function createEvent(context, data) {
var _a;
const client = await (0, client_1.initClient)(context);
const calendar = await (0, calendar_1.findCalendar)(context, client, data.calendarName);
const credentials = await context.getCredentials('nextcloudCalendarApi');
const event = {
...data,
uid: `n8n-${Date.now()}@nextcloud-calendar`,
credentials: credentials,
};
console.log(`Erstelle Termin mit UID: ${event.uid}`);
const iCalString = generateICalString(event);
console.log(`iCal-String: ${iCalString}`);
const response = await client.createCalendarObject({
calendar,
filename: `${event.uid}.ics`,
iCalString: iCalString,
});
console.log(`Response von createCalendarObject:`, response);
try {
const createdEvent = await getEvent(context, data.calendarName, event.uid);
console.log(`Termin erfolgreich erstellt und gefunden:`, createdEvent);
}
catch (error) {
console.log(`Warnung: Erstellter Termin konnte nicht gefunden werden:`, error.message);
}
const result = {
success: true,
message: 'Termin erfolgreich erstellt',
uid: event.uid,
details: {
title: event.title,
start: event.start,
end: event.end,
attendeesCount: ((_a = event.attendees) === null || _a === void 0 ? void 0 : _a.length) || 0,
}
};
if (response && typeof response === 'object') {
if ('url' in response) {
result.url = response.url;
}
if ('etag' in response) {
result.etag = String(response.etag);
}
}
return result;
}
exports.createEvent = createEvent;
async function updateEvent(context, data) {
var _a;
const client = await (0, client_1.initClient)(context);
const calendar = await (0, calendar_1.findCalendar)(context, client, data.calendarName);
const existingEvent = await getEvent(context, data.calendarName, data.eventId);
const updatedEvent = {
...existingEvent,
...data,
};
const events = await client.fetchCalendarObjects({
calendar,
filters: [{
'comp-filter': {
_attributes: {
name: 'VCALENDAR',
},
'comp-filter': {
_attributes: {
name: 'VEVENT',
test: 'allof',
},
'prop-filter': {
_attributes: {
name: 'UID',
test: 'equals',
},
'text-match': {
_attributes: {
'match-type': 'equals',
},
_text: data.eventId,
},
},
},
},
}],
});
if (!events || events.length === 0) {
throw new Error(`Event with ID "${data.eventId}" not found`);
}
const headers = {};
if (data.attendees && data.attendees.length > 0) {
headers['X-Requested-With'] = 'XMLHttpRequest';
headers['Schedule-Reply'] = 'true';
headers['Prefer'] = 'return=representation';
}
const response = await client.updateCalendarObject({
calendarObject: {
...events[0],
data: generateICalString(updatedEvent),
},
headers: headers,
});
const result = {
success: true,
message: 'Termin erfolgreich aktualisiert',
uid: data.eventId,
details: {
title: updatedEvent.title,
start: updatedEvent.start,
end: updatedEvent.end,
attendeesCount: ((_a = updatedEvent.attendees) === null || _a === void 0 ? void 0 : _a.length) || 0,
}
};
if (response && typeof response === 'object') {
if ('url' in response) {
result.url = response.url;
}
if ('etag' in response) {
result.etag = String(response.etag);
}
}
return result;
}
exports.updateEvent = updateEvent;
async function deleteEvent(context, calendarName, eventId) {
const client = await (0, client_1.initClient)(context);
const calendar = await (0, calendar_1.findCalendar)(context, client, calendarName);
const events = await client.fetchCalendarObjects({
calendar,
filters: [{
'comp-filter': {
_attributes: {
name: 'VCALENDAR',
},
'comp-filter': {
_attributes: {
name: 'VEVENT',
test: 'allof',
},
'prop-filter': {
_attributes: {
name: 'UID',
test: 'equals',
},
'text-match': {
_attributes: {
'match-type': 'equals',
},
_text: eventId,
},
},
},
},
}],
});
if (!events || events.length === 0) {
throw new Error(`Event with ID "${eventId}" not found`);
}
await client.deleteCalendarObject({
calendarObject: events[0],
});
return { success: true };
}
exports.deleteEvent = deleteEvent;
async function searchEvents(context, calendarName, searchTerm, start, end) {
const events = await getEvents(context, calendarName, start, end);
return events.filter(event => {
const searchString = searchTerm.toLowerCase();
return ((event.title && event.title.toLowerCase().includes(searchString)) ||
(event.description && event.description.toLowerCase().includes(searchString)) ||
(event.location && event.location.toLowerCase().includes(searchString)));
});
}
exports.searchEvents = searchEvents;
function generateICalString(event) {
const timestamp = new Date().toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z';
const startDate = event.start ? new Date(event.start) : new Date();
const endDate = event.end ? new Date(event.end) : new Date(startDate.getTime() + 60 * 60 * 1000);
const formatDateTime = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}${month}${day}T${hours}${minutes}${seconds}`;
};
let iCalString = `BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//n8n//Nextcloud Calendar Node//EN
BEGIN:VTIMEZONE
TZID:Europe/Berlin
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
BEGIN:VEVENT
UID:${event.uid}
DTSTAMP:${timestamp}
DTSTART;TZID=Europe/Berlin:${formatDateTime(startDate)}
DTEND;TZID=Europe/Berlin:${formatDateTime(endDate)}
SUMMARY:${event.title || 'Unbenannter Termin'}
`;
if (event.description) {
iCalString += `DESCRIPTION:${event.description.replace(/\n/g, '\\n')}\n`;
}
if (event.location) {
iCalString += `LOCATION:${event.location}\n`;
}
console.log(`ORGANIZER wird temporär NICHT gesetzt (Debugging)`);
if (event.attendees && event.attendees.length > 0) {
console.log(`WARNUNG: ${event.attendees.length} Teilnehmer werden temporär ignoriert (Debugging)`);
}
iCalString += `END:VEVENT
END:VCALENDAR`;
return iCalString;
}
//# sourceMappingURL=event.js.map