n8n-nodes-caldav-pro 1.0.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -252
- package/dist/credentials/CalDavApi.credentials.d.ts +1 -1
- package/dist/credentials/CalDavApi.credentials.js +23 -11
- package/dist/credentials/CalDavApi.credentials.js.map +1 -1
- package/dist/nodes/CalDav/CalDav.node.d.ts +8 -1
- package/dist/nodes/CalDav/CalDav.node.js +496 -53
- package/dist/nodes/CalDav/CalDav.node.js.map +1 -1
- package/dist/nodes/CalDav/CalendarDescription.d.ts +3 -0
- package/dist/nodes/CalDav/CalendarDescription.js +25 -0
- package/dist/nodes/CalDav/CalendarDescription.js.map +1 -0
- package/dist/nodes/CalDav/EventDescription.d.ts +3 -0
- package/dist/nodes/CalDav/EventDescription.js +297 -0
- package/dist/nodes/CalDav/EventDescription.js.map +1 -0
- package/dist/nodes/CalDav/GenericFunctions.d.ts +135 -0
- package/dist/nodes/CalDav/GenericFunctions.js +951 -0
- package/dist/nodes/CalDav/GenericFunctions.js.map +1 -0
- package/dist/nodes/CalDav/caldav.svg +10 -0
- package/dist/package.json +5 -19
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -19
- package/dist/nodes/CalDav/CalDavTool.node.d.ts +0 -6
- package/dist/nodes/CalDav/CalDavTool.node.js +0 -255
- package/dist/nodes/CalDav/CalDavTool.node.js.map +0 -1
- package/dist/nodes/CalDav/descriptions/SharedDescriptions.d.ts +0 -11
- package/dist/nodes/CalDav/descriptions/SharedDescriptions.js +0 -232
- package/dist/nodes/CalDav/descriptions/SharedDescriptions.js.map +0 -1
- package/dist/nodes/CalDav/helpers/AgentInput.d.ts +0 -2
- package/dist/nodes/CalDav/helpers/AgentInput.js +0 -159
- package/dist/nodes/CalDav/helpers/AgentInput.js.map +0 -1
- package/dist/nodes/CalDav/helpers/CalDavClient.d.ts +0 -40
- package/dist/nodes/CalDav/helpers/CalDavClient.js +0 -246
- package/dist/nodes/CalDav/helpers/CalDavClient.js.map +0 -1
- package/dist/nodes/CalDav/helpers/ICal.d.ts +0 -48
- package/dist/nodes/CalDav/helpers/ICal.js +0 -216
- package/dist/nodes/CalDav/helpers/ICal.js.map +0 -1
- package/dist/nodes/CalDav/helpers/Operations.d.ts +0 -14
- package/dist/nodes/CalDav/helpers/Operations.js +0 -425
- package/dist/nodes/CalDav/helpers/Operations.js.map +0 -1
- package/dist/nodes/CalDav/helpers/Recurrence.d.ts +0 -29
- package/dist/nodes/CalDav/helpers/Recurrence.js +0 -204
- package/dist/nodes/CalDav/helpers/Recurrence.js.map +0 -1
- package/dist/nodes/CalDav/helpers/Timezone.d.ts +0 -11
- package/dist/nodes/CalDav/helpers/Timezone.js +0 -142
- package/dist/nodes/CalDav/helpers/Timezone.js.map +0 -1
- package/dist/nodes/CalDav/helpers/Utils.d.ts +0 -17
- package/dist/nodes/CalDav/helpers/Utils.js +0 -129
- package/dist/nodes/CalDav/helpers/Utils.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,313 +1,186 @@
|
|
|
1
1
|
# n8n-nodes-caldav-pro
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A community node for n8n that connects to **CalDAV calendar servers** — Infomaniak, Nextcloud, iCloud, Radicale, Baikal, SOGo, and any RFC 4791-compliant server.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- **CalDAV** – standard node for workflows (triggers, schedulers, HTTP, etc.).
|
|
8
|
-
- **CalDAV Tool** – AI-Agent tool variant with `$fromAI()` support, tolerant
|
|
9
|
-
parameter casing, and error-as-JSON default behaviour.
|
|
10
|
-
|
|
11
|
-
Tested against Infomaniak kMeet/Calendar, Nextcloud, Apple iCloud, Radicale,
|
|
12
|
-
Baikal, SOGo and generic RFC 4791 servers.
|
|
5
|
+
**Version 2.0.0** — single unified node with native AI Agent support (`usableAsTool: true`).
|
|
13
6
|
|
|
14
7
|
---
|
|
15
8
|
|
|
16
9
|
## Features
|
|
17
10
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Additional guarantees:
|
|
27
|
-
|
|
28
|
-
- **Timezones:** pulled from `this.getTimezone()`. VTIMEZONE is generated
|
|
29
|
-
dynamically with proper DAYLIGHT + STANDARD components and correct DST
|
|
30
|
-
rules for Europe, North America, Australia, New Zealand, Chile.
|
|
31
|
-
`DTSTART;TZID=Europe/Berlin:20260414T120000` – never UTC literals for
|
|
32
|
-
timed events.
|
|
33
|
-
- **RFC 5545 compliance:** CRLF line endings, line folding at 75 octets,
|
|
34
|
-
escape sequences in TEXT properties, UTC DTSTAMP/CREATED/LAST-MODIFIED.
|
|
35
|
-
- **Security:** UID sanitization (`/[^\w\-.@]/g → '_'`), path-traversal
|
|
36
|
-
guard, XML-safe response parsing, no credential or body logging.
|
|
37
|
-
- **AI-friendly:** every enum is a free-form string with allowed values in
|
|
38
|
-
the description, and parameters accept camelCase, snake_case, UPPER_CASE
|
|
39
|
-
and kebab-case interchangeably.
|
|
11
|
+
- **Resource/Operation pattern** — Calendar: Get All | Event: Create, Get, Get All, Update, Delete
|
|
12
|
+
- **Native AI Agent support** — expose directly to Claude, GPT-4, or any LLM tool via n8n's AI Agent node without extra wiring
|
|
13
|
+
- **Calendar dropdown** — pick your calendar from a dynamic list (auto-discovered from your server)
|
|
14
|
+
- **Recurring events** — DAILY, WEEKLY (with day-of-week), MONTHLY, YEARLY; COUNT or UNTIL end types
|
|
15
|
+
- **Reminders** — VALARM blocks with configurable lead time
|
|
16
|
+
- **All-day events** — full DATE-only support
|
|
17
|
+
- **Zero external dependencies** — pure TypeScript, only `n8n-workflow` as peer dependency
|
|
40
18
|
|
|
41
19
|
---
|
|
42
20
|
|
|
43
21
|
## Installation
|
|
44
22
|
|
|
45
|
-
###
|
|
46
|
-
|
|
47
|
-
`Settings → Community Nodes → Install` and enter:
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
n8n-nodes-caldav-pro
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### From npm (CLI install)
|
|
23
|
+
### Community Nodes panel (recommended)
|
|
54
24
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
25
|
+
1. Open n8n → **Settings** → **Community Nodes**
|
|
26
|
+
2. Click **Install a community node**
|
|
27
|
+
3. Enter: `n8n-nodes-caldav-pro`
|
|
28
|
+
4. Click **Install**
|
|
58
29
|
|
|
59
|
-
|
|
30
|
+
### Manual (tgz)
|
|
60
31
|
|
|
61
32
|
```bash
|
|
62
|
-
|
|
63
|
-
|
|
33
|
+
# In your n8n data directory
|
|
34
|
+
npm install /path/to/n8n-nodes-caldav-pro-2.0.0.tgz
|
|
64
35
|
```
|
|
65
36
|
|
|
66
|
-
|
|
37
|
+
Then restart n8n.
|
|
67
38
|
|
|
68
39
|
---
|
|
69
40
|
|
|
70
|
-
##
|
|
41
|
+
## Infomaniak Quickstart
|
|
71
42
|
|
|
72
|
-
|
|
43
|
+
### 1 — Create an App Password (required for 2FA accounts)
|
|
73
44
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
| Username | Your account username |
|
|
78
|
-
| Password | Account or app-specific password |
|
|
45
|
+
1. Go to [manager.infomaniak.com](https://manager.infomaniak.com) → **Security** → **App passwords**
|
|
46
|
+
2. Create a new password — label it "n8n CalDAV"
|
|
47
|
+
3. Copy the generated password (you won't see it again)
|
|
79
48
|
|
|
80
|
-
|
|
49
|
+
### 2 — Find your short username
|
|
81
50
|
|
|
82
|
-
|
|
51
|
+
1. Go to [config.infomaniak.com](https://config.infomaniak.com)
|
|
52
|
+
2. Your CalDAV username is the **short name** shown there — e.g., `DK03456` — **not your email address**
|
|
83
53
|
|
|
84
|
-
|
|
85
|
-
open **Calendar → ⚙ Settings → Synchronize → CalDAV**.
|
|
86
|
-
2. Copy the CalDAV URL. It looks like:
|
|
54
|
+
### 3 — Set up credentials in n8n
|
|
87
55
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
56
|
+
1. In n8n, go to **Credentials** → **New** → search for **CalDAV**
|
|
57
|
+
2. Fill in:
|
|
58
|
+
- **Server URL**: `https://sync.infomaniak.com/` (default, no change needed)
|
|
59
|
+
- **Username**: your short name, e.g. `DK03456`
|
|
60
|
+
- **Password**: the App password from step 1
|
|
61
|
+
3. Click **Test** — you should see "Connection successful"
|
|
91
62
|
|
|
92
|
-
|
|
93
|
-
app password for n8n.
|
|
94
|
-
4. In n8n create a new `CalDAV API` credential with:
|
|
95
|
-
- **Server URL:** paste the CalDAV URL above (keep the trailing `/`).
|
|
96
|
-
- **Username:** your Infomaniak login (email).
|
|
97
|
-
- **Password:** the app password.
|
|
63
|
+
### 4 — Create your first event
|
|
98
64
|
|
|
99
|
-
|
|
65
|
+
1. Add a **CalDAV** node to your workflow
|
|
66
|
+
2. Set **Resource** → `Event`, **Operation** → `Create`
|
|
67
|
+
3. Pick your calendar from the **Calendar** dropdown
|
|
68
|
+
4. Fill in Title, Start, End — click **Execute**
|
|
100
69
|
|
|
101
|
-
|
|
102
|
-
https://cloud.example.com/remote.php/dav/calendars/<user>/<calendar-id>/
|
|
103
|
-
```
|
|
70
|
+
---
|
|
104
71
|
|
|
105
|
-
|
|
106
|
-
Devices & sessions).
|
|
72
|
+
## AI Agent Usage
|
|
107
73
|
|
|
108
|
-
|
|
74
|
+
This node is registered with `usableAsTool: true`, so n8n's AI Agent node can call it directly without any wrapper.
|
|
109
75
|
|
|
110
|
-
|
|
111
|
-
https://caldav.icloud.com/<principal-id>/calendars/<calendar-id>/
|
|
112
|
-
```
|
|
76
|
+
### Wiring it up
|
|
113
77
|
|
|
114
|
-
|
|
78
|
+
1. Add an **AI Agent** node to your workflow
|
|
79
|
+
2. In the agent's **Tools** section, add the **CalDAV** node
|
|
80
|
+
3. The agent will automatically discover all available operations and parameters
|
|
115
81
|
|
|
116
|
-
###
|
|
82
|
+
### Example system prompt
|
|
117
83
|
|
|
118
|
-
|
|
119
|
-
|
|
84
|
+
```
|
|
85
|
+
You are a scheduling assistant. You have access to a CalDAV calendar tool.
|
|
120
86
|
|
|
121
|
-
|
|
87
|
+
When the user asks to create, read, update, or delete calendar events, use the CalDAV tool.
|
|
122
88
|
|
|
123
|
-
|
|
89
|
+
Guidelines:
|
|
90
|
+
- Always confirm event details (title, date/time, calendar) before creating
|
|
91
|
+
- When listing events, default to the next 7 days unless the user specifies otherwise
|
|
92
|
+
- For recurring events, confirm the frequency and end condition
|
|
93
|
+
- Times should be provided in ISO 8601 format with timezone offset, e.g. 2026-04-20T14:00:00+02:00
|
|
94
|
+
- If the user doesn't specify a calendar, use the first available calendar
|
|
124
95
|
|
|
125
|
-
|
|
126
|
-
|
|
96
|
+
Today's date: {{$now.toISO()}}
|
|
97
|
+
```
|
|
127
98
|
|
|
128
|
-
###
|
|
99
|
+
### Parameter flexibility for LLMs
|
|
129
100
|
|
|
130
|
-
|
|
131
|
-
You are a scheduling assistant. You can use the "caldav" tool to read,
|
|
132
|
-
create, update and delete events on the user's calendar, and to check
|
|
133
|
-
free/busy for specific time windows.
|
|
134
|
-
|
|
135
|
-
Rules:
|
|
136
|
-
- All datetimes MUST be ISO-8601 with a timezone offset, e.g.
|
|
137
|
-
"2026-04-14T12:00:00+02:00". Never emit "Z" for local events.
|
|
138
|
-
- Before creating an event, call getFreeBusy for the requested window.
|
|
139
|
-
If the window is busy, propose the next free slot instead.
|
|
140
|
-
- For recurring events: set Recurring_Event to true and fill in
|
|
141
|
-
Recurrence_Frequency (DAILY/WEEKLY/MONTHLY/YEARLY), Recurrence_Interval,
|
|
142
|
-
Recurrence_End_Type (count/until/never), Recurrence_Count or
|
|
143
|
-
Recurrence_Until, and Recurrence_By_Day when relevant
|
|
144
|
-
(e.g. "MO,WE,FR").
|
|
145
|
-
- If the tool returns {success:false, error:...}, tell the user what went
|
|
146
|
-
wrong and ask for a correction; do not retry identical input.
|
|
147
|
-
- Today's date: {{$today}}. User timezone: {{$now.zoneName}}.
|
|
148
|
-
```
|
|
101
|
+
The node accepts parameters in camelCase, snake_case, or UPPER_CASE — so LLMs don't need to match exact field names:
|
|
149
102
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
"Start_Date": "2026-04-21T15:00:00+02:00",
|
|
157
|
-
"End_Date": "2026-04-21T16:00:00+02:00"
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
Response: `{ success: true, isBusy: false, free: [...], busy: [] }`.
|
|
161
|
-
|
|
162
|
-
2. Agent calls `caldav` with:
|
|
163
|
-
```json
|
|
164
|
-
{
|
|
165
|
-
"operation": "createEvent",
|
|
166
|
-
"Event_Title": "Meeting with Jane",
|
|
167
|
-
"Start_Date_and_Time": "2026-04-21T15:00:00+02:00",
|
|
168
|
-
"End_Date_and_Time": "2026-04-21T16:00:00+02:00",
|
|
169
|
-
"Location": "Office",
|
|
170
|
-
"Reminder": 15
|
|
171
|
-
}
|
|
172
|
-
```
|
|
173
|
-
Response:
|
|
174
|
-
```json
|
|
175
|
-
{
|
|
176
|
-
"success": true,
|
|
177
|
-
"operation": "createEvent",
|
|
178
|
-
"uid": "c4b1c9de-...@n8n-caldav",
|
|
179
|
-
"etag": "\"f00\"",
|
|
180
|
-
"timezone": "Europe/Berlin",
|
|
181
|
-
"event": { ... }
|
|
182
|
-
}
|
|
183
|
-
```
|
|
103
|
+
| Canonical | Also accepted |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `eventTitle` | `event_title`, `EVENT_TITLE` |
|
|
106
|
+
| `startDateAndTime` | `start_date_and_time`, `START_DATE_AND_TIME` |
|
|
107
|
+
| `calendarUrl` | `calendar_url`, `CALENDAR_URL` |
|
|
108
|
+
| `recurringEvent` | `recurring_event` |
|
|
184
109
|
|
|
185
110
|
---
|
|
186
111
|
|
|
187
|
-
##
|
|
188
|
-
|
|
189
|
-
###
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
|
225
|
-
|
|
226
|
-
| UID (optional) | string | Empty → UUID generated. |
|
|
227
|
-
| Event_Title | string | **required**. |
|
|
228
|
-
| Start_Date_and_Time | string | **required** – ISO-8601 with offset. |
|
|
229
|
-
| End_Date_and_Time | string | Default start + 1h. |
|
|
230
|
-
| Location | string | |
|
|
231
|
-
| Description | string | |
|
|
232
|
-
| All_Day_Event | boolean | If true, emits `DTSTART;VALUE=DATE:YYYYMMDD`. |
|
|
233
|
-
| Reminder | number | Minutes before start. 0 → no VALARM. |
|
|
234
|
-
| Recurring_Event | boolean | Enables RRULE. |
|
|
235
|
-
| Recurrence_Frequency | string | `DAILY` / `WEEKLY` / `MONTHLY` / `YEARLY`. |
|
|
236
|
-
| Recurrence_Interval | number | Default `1`. |
|
|
237
|
-
| Recurrence_End_Type | string | `count` / `until` / `never`. |
|
|
238
|
-
| Recurrence_Count | number | When `end_type=count`. |
|
|
239
|
-
| Recurrence_Until | string | When `end_type=until`. |
|
|
240
|
-
| Recurrence_By_Day | string | Comma-separated BYDAY tokens: `MO,TU,WE,TH,FR,SA,SU` (ordinals allowed: `2MO`, `-1FR`). |
|
|
241
|
-
|
|
242
|
-
### Update Event
|
|
243
|
-
|
|
244
|
-
All fields optional except **UID**. Omitted fields keep their existing
|
|
245
|
-
values. Uses `If-Match` with the current ETag.
|
|
246
|
-
|
|
247
|
-
### Delete Event
|
|
248
|
-
|
|
249
|
-
| Field | Type |
|
|
250
|
-
|-------|--------|
|
|
251
|
-
| UID | string (required) |
|
|
252
|
-
|
|
253
|
-
HTTP 404 → `deleted:false` (no error thrown).
|
|
254
|
-
|
|
255
|
-
### Get Free/Busy
|
|
256
|
-
|
|
257
|
-
| Field | Type |
|
|
258
|
-
|--------------|--------|
|
|
259
|
-
| Start_Date | string (required) |
|
|
260
|
-
| End_Date | string (required) |
|
|
261
|
-
|
|
262
|
-
Output:
|
|
263
|
-
|
|
264
|
-
```json
|
|
265
|
-
{
|
|
266
|
-
"success": true,
|
|
267
|
-
"operation": "getFreeBusy",
|
|
268
|
-
"method": "freebusy-query",
|
|
269
|
-
"rangeStart": "2026-04-14T08:00:00.000Z",
|
|
270
|
-
"rangeEnd": "2026-04-14T18:00:00.000Z",
|
|
271
|
-
"busy": [ { "start": "...", "end": "..." } ],
|
|
272
|
-
"free": [ { "start": "...", "end": "..." } ],
|
|
273
|
-
"isBusy": true
|
|
274
|
-
}
|
|
275
|
-
```
|
|
112
|
+
## Node Reference
|
|
113
|
+
|
|
114
|
+
### Calendar resource
|
|
115
|
+
|
|
116
|
+
| Operation | Description |
|
|
117
|
+
|---|---|
|
|
118
|
+
| Get All | List all calendars on the server |
|
|
119
|
+
|
|
120
|
+
### Event resource
|
|
121
|
+
|
|
122
|
+
| Operation | Description |
|
|
123
|
+
|---|---|
|
|
124
|
+
| Create | Create a new calendar event |
|
|
125
|
+
| Get | Retrieve a single event by UID |
|
|
126
|
+
| Get All | List events within a date range |
|
|
127
|
+
| Update | Modify an existing event |
|
|
128
|
+
| Delete | Remove an event |
|
|
129
|
+
|
|
130
|
+
### Key fields
|
|
131
|
+
|
|
132
|
+
| Field | Operations | Notes |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| Calendar | All event ops | Dynamic dropdown, auto-populated |
|
|
135
|
+
| UID | Get, Update, Delete (required) | Unique event identifier |
|
|
136
|
+
| Title | Create (required) | Event summary/title |
|
|
137
|
+
| Start Date & Time | Create (required) | ISO 8601, e.g. `2026-04-20T14:00:00+02:00` |
|
|
138
|
+
| End Date & Time | Create | Defaults to 1 hour after start |
|
|
139
|
+
| Location | Create, Update | Free text |
|
|
140
|
+
| Description | Create, Update | Free text |
|
|
141
|
+
| All Day Event | Create, Update | Toggle — uses DATE values |
|
|
142
|
+
| Reminder (minutes before) | Create, Update | 0 = at event time |
|
|
143
|
+
| Recurring Event | Create, Update | Toggle to enable recurrence |
|
|
144
|
+
| Recurrence Frequency | Create (recurring) | DAILY / WEEKLY / MONTHLY / YEARLY |
|
|
145
|
+
| Recurrence Interval | Create (recurring) | e.g. 2 = every 2 weeks |
|
|
146
|
+
| Recurrence Days | Create (WEEKLY) | MO, TU, WE, TH, FR, SA, SU |
|
|
147
|
+
| Recurrence End Type | Create (recurring) | Never / After N occurrences / Until date |
|
|
148
|
+
| Time Min / Max | Get All | Filter window (defaults: today / +30 days) |
|
|
149
|
+
| Return All | Get All | If off, capped by Max Results |
|
|
150
|
+
| Max Results | Get All | Default 50 |
|
|
276
151
|
|
|
277
152
|
---
|
|
278
153
|
|
|
279
|
-
##
|
|
154
|
+
## Credentials
|
|
280
155
|
|
|
281
|
-
|
|
156
|
+
| Field | Default | Notes |
|
|
157
|
+
|---|---|---|
|
|
158
|
+
| Server URL | `https://sync.infomaniak.com/` | Trailing slash required |
|
|
159
|
+
| Username | — | Short name (e.g. `DK03456`), not email |
|
|
160
|
+
| Password | — | App password if 2FA is enabled |
|
|
282
161
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
"error": "CalDAV PUT failed: HTTP 412 Precondition Failed",
|
|
287
|
-
"operation": "updateEvent",
|
|
288
|
-
"timestamp": "2026-04-19T10:12:34.567Z"
|
|
289
|
-
}
|
|
290
|
-
```
|
|
162
|
+
The credential test performs a `PROPFIND` against `/.well-known/caldav`. A 207 Multi-Status or 301 redirect is treated as success.
|
|
163
|
+
|
|
164
|
+
---
|
|
291
165
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
- **
|
|
295
|
-
|
|
166
|
+
## Tested with
|
|
167
|
+
|
|
168
|
+
- **Infomaniak kSuite** (sync.infomaniak.com) — primary target
|
|
169
|
+
- **Nextcloud** (self-hosted)
|
|
170
|
+
- **Radicale** (self-hosted)
|
|
296
171
|
|
|
297
172
|
---
|
|
298
173
|
|
|
299
|
-
##
|
|
174
|
+
## Known Limitations
|
|
300
175
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
npm run pack # builds + emits n8n-nodes-caldav-pro-1.0.0.tgz
|
|
307
|
-
```
|
|
176
|
+
- **iCloud** requires an app-specific password and uses `caldav.icloud.com` as server URL — discovery works but is slower
|
|
177
|
+
- **Recurring event updates** modify the master event (all occurrences), not individual instances (RECURRENCE-ID is not yet supported)
|
|
178
|
+
- **Attendees / RSVP** are not yet supported
|
|
179
|
+
- **Free/busy queries** are not yet supported
|
|
180
|
+
- The node queries calendar data by time range; very large calendars (10 000+ events) may be slow on Get All
|
|
308
181
|
|
|
309
182
|
---
|
|
310
183
|
|
|
311
184
|
## License
|
|
312
185
|
|
|
313
|
-
MIT
|
|
186
|
+
MIT
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
1
|
+
import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
2
|
export declare class CalDavApi implements ICredentialType {
|
|
3
3
|
name: string;
|
|
4
4
|
displayName: string;
|
|
@@ -11,14 +11,16 @@ class CalDavApi {
|
|
|
11
11
|
displayName: 'Server URL',
|
|
12
12
|
name: 'serverUrl',
|
|
13
13
|
type: 'string',
|
|
14
|
-
default: '',
|
|
14
|
+
default: 'https://sync.infomaniak.com/',
|
|
15
15
|
required: true,
|
|
16
|
-
placeholder: 'https://
|
|
17
|
-
description: '
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
16
|
+
placeholder: 'https://sync.infomaniak.com/',
|
|
17
|
+
description: 'Base URL of the CalDAV server — NOT the individual calendar URL. ' +
|
|
18
|
+
'The node discovers calendar collections automatically.\n\n' +
|
|
19
|
+
'Examples:\n' +
|
|
20
|
+
'• Infomaniak: https://sync.infomaniak.com/\n' +
|
|
21
|
+
'• Nextcloud: https://cloud.example.com/\n' +
|
|
22
|
+
'• iCloud: https://caldav.icloud.com/\n' +
|
|
23
|
+
'• Radicale / Baikal / SOGo: your server root URL',
|
|
22
24
|
},
|
|
23
25
|
{
|
|
24
26
|
displayName: 'Username',
|
|
@@ -26,6 +28,10 @@ class CalDavApi {
|
|
|
26
28
|
type: 'string',
|
|
27
29
|
default: '',
|
|
28
30
|
required: true,
|
|
31
|
+
placeholder: 'dk03456',
|
|
32
|
+
description: 'CalDAV username. For Infomaniak this is your short account name (e.g. dk03456), ' +
|
|
33
|
+
'NOT your email address. ' +
|
|
34
|
+
'Find it at https://config.infomaniak.com/ under Account → Username.',
|
|
29
35
|
},
|
|
30
36
|
{
|
|
31
37
|
displayName: 'Password',
|
|
@@ -36,7 +42,10 @@ class CalDavApi {
|
|
|
36
42
|
},
|
|
37
43
|
default: '',
|
|
38
44
|
required: true,
|
|
39
|
-
description: 'Account password or app-specific password
|
|
45
|
+
description: 'Account password or app-specific password. ' +
|
|
46
|
+
'If 2FA is enabled on your Infomaniak account, you must create an app password at ' +
|
|
47
|
+
'https://manager.infomaniak.com → Security → Application passwords. ' +
|
|
48
|
+
'Using your main password with 2FA enabled will return HTTP 401.',
|
|
40
49
|
},
|
|
41
50
|
];
|
|
42
51
|
this.authenticate = {
|
|
@@ -47,21 +56,24 @@ class CalDavApi {
|
|
|
47
56
|
password: '={{ $credentials.password }}',
|
|
48
57
|
},
|
|
49
58
|
headers: {
|
|
50
|
-
'User-Agent': 'n8n-nodes-caldav-pro/
|
|
59
|
+
'User-Agent': 'n8n-nodes-caldav-pro/2.0.0',
|
|
51
60
|
},
|
|
52
61
|
},
|
|
53
62
|
};
|
|
54
63
|
this.test = {
|
|
55
64
|
request: {
|
|
56
65
|
baseURL: '={{ $credentials.serverUrl }}',
|
|
57
|
-
url: '',
|
|
66
|
+
url: '/.well-known/caldav',
|
|
58
67
|
method: 'PROPFIND',
|
|
59
68
|
headers: {
|
|
60
69
|
Depth: '0',
|
|
61
70
|
'Content-Type': 'application/xml; charset=utf-8',
|
|
62
71
|
},
|
|
63
72
|
body: '<?xml version="1.0" encoding="utf-8" ?>' +
|
|
64
|
-
'<d:propfind xmlns:d="DAV:"
|
|
73
|
+
'<d:propfind xmlns:d="DAV:">' +
|
|
74
|
+
'<d:prop><d:resourcetype/><d:displayname/></d:prop>' +
|
|
75
|
+
'</d:propfind>',
|
|
76
|
+
ignoreHttpStatusErrors: true,
|
|
65
77
|
},
|
|
66
78
|
};
|
|
67
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalDavApi.credentials.js","sourceRoot":"","sources":["../../credentials/CalDavApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,SAAS;IAAtB;QACC,SAAI,GAAG,WAAW,CAAC;QACnB,gBAAW,GAAG,YAAY,CAAC;QAC3B,qBAAgB,GAAG,uDAAuD,CAAC;QAE3E,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"CalDavApi.credentials.js","sourceRoot":"","sources":["../../credentials/CalDavApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,SAAS;IAAtB;QACC,SAAI,GAAG,WAAW,CAAC;QACnB,gBAAW,GAAG,YAAY,CAAC;QAC3B,qBAAgB,GAAG,uDAAuD,CAAC;QAE3E,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,8BAA8B;gBACvC,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,8BAA8B;gBAC3C,WAAW,EACV,mEAAmE;oBACnE,4DAA4D;oBAC5D,aAAa;oBACb,8CAA8C;oBAC9C,2CAA2C;oBAC3C,wCAAwC;oBACxC,kDAAkD;aACnD;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,SAAS;gBACtB,WAAW,EACV,kFAAkF;oBAClF,0BAA0B;oBAC1B,qEAAqE;aACtE;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACZ,QAAQ,EAAE,IAAI;iBACd;gBACD,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EACV,6CAA6C;oBAC7C,mFAAmF;oBACnF,qEAAqE;oBACrE,iEAAiE;aAClE;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,IAAI,EAAE;oBACL,QAAQ,EAAE,8BAA8B;oBACxC,QAAQ,EAAE,8BAA8B;iBACxC;gBACD,OAAO,EAAE;oBACR,YAAY,EAAE,4BAA4B;iBAC1C;aACD;SACD,CAAC;QAYF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,+BAA+B;gBACxC,GAAG,EAAE,qBAAqB;gBAC1B,MAAM,EAAE,UAAyD;gBACjE,OAAO,EAAE;oBACR,KAAK,EAAE,GAAG;oBACV,cAAc,EAAE,gCAAgC;iBAChD;gBACD,IAAI,EACH,yCAAyC;oBACzC,6BAA6B;oBAC7B,oDAAoD;oBACpD,eAAe;gBAChB,sBAAsB,EAAE,IAAI;aAC5B;SACD,CAAC;IACH,CAAC;CAAA;AA3FD,8BA2FC"}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
1
|
+
import type { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
import { generateUid } from './GenericFunctions';
|
|
2
3
|
export declare class CalDav implements INodeType {
|
|
3
4
|
description: INodeTypeDescription;
|
|
5
|
+
methods: {
|
|
6
|
+
loadOptions: {
|
|
7
|
+
getCalendars(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
4
10
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
11
|
}
|
|
12
|
+
export { generateUid };
|