Skip to content

Commit 5f3376e

Browse files
authored
Merge pull request #34 from Resgrid/develop
Updating calendar docs
2 parents e509f53 + 47e048b commit 5f3376e

8 files changed

Lines changed: 708 additions & 10 deletions

File tree

docs/api/calendar-export.md

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
---
2+
sidebar_position: 6
3+
---
4+
5+
# Calendar Export API
6+
7+
The Calendar Export API provides endpoints for exporting calendar events as iCalendar (`.ics`) files and managing calendar feed subscriptions. These endpoints are part of the v4 API and are served by the `CalendarExportController`.
8+
9+
## Endpoints Overview
10+
11+
| Endpoint | Method | Auth | Description |
12+
|----------|--------|------|-------------|
13+
| `v4/CalendarExport/ExportICalFile` | GET | Bearer token | Download a single event as `.ics` |
14+
| `v4/CalendarExport/ExportDepartmentICalFeed` | GET | Bearer token | Download full department calendar as `.ics` |
15+
| `v4/CalendarExport/GetCalendarSubscriptionUrl` | GET | Bearer token | Get or activate the calendar subscription URL |
16+
| `v4/CalendarExport/RegenerateCalendarSubscriptionUrl` | POST | Bearer token | Regenerate the subscription URL (invalidates old) |
17+
| `v4/CalendarExport/CalendarFeed/{token}` | GET | Anonymous | Fetch the iCal feed via encrypted token |
18+
19+
## Export Single Event
20+
21+
```
22+
GET /api/v4/CalendarExport/ExportICalFile?calendarItemId={id}
23+
Authorization: Bearer {access_token}
24+
```
25+
26+
Returns a single calendar event as a `.ics` file with content type `text/calendar`.
27+
28+
### Parameters
29+
30+
| Parameter | Type | Required | Description |
31+
|-----------|------|----------|-------------|
32+
| `calendarItemId` | int | Yes | The ID of the calendar item to export |
33+
34+
### Response
35+
36+
- **Content-Type:** `text/calendar`
37+
- **Content-Disposition:** attachment with `.ics` filename
38+
- Body contains a valid iCalendar file with a single `VEVENT`
39+
40+
## Export Department Calendar
41+
42+
```
43+
GET /api/v4/CalendarExport/ExportDepartmentICalFeed
44+
Authorization: Bearer {access_token}
45+
```
46+
47+
Returns all calendar events for the authenticated user's department as a single `.ics` file.
48+
49+
### Response
50+
51+
- **Content-Type:** `text/calendar`
52+
- Body contains a valid iCalendar file with multiple `VEVENT` entries
53+
54+
## Get Calendar Subscription URL
55+
56+
```
57+
GET /api/v4/CalendarExport/GetCalendarSubscriptionUrl
58+
Authorization: Bearer {access_token}
59+
```
60+
61+
Returns the user's calendar subscription URL. If the user has not yet activated calendar sync, it is activated automatically and a new subscription URL is generated.
62+
63+
### Response
64+
65+
```json
66+
{
67+
"Data": {
68+
"SubscriptionUrl": "https://api.resgrid.com/api/v4/CalendarExport/CalendarFeed/{encrypted_token}",
69+
"WebCalUrl": "webcal://api.resgrid.com/api/v4/CalendarExport/CalendarFeed/{encrypted_token}",
70+
"IsActive": true
71+
},
72+
"Status": "success"
73+
}
74+
```
75+
76+
## Regenerate Calendar Subscription URL
77+
78+
```
79+
POST /api/v4/CalendarExport/RegenerateCalendarSubscriptionUrl
80+
Authorization: Bearer {access_token}
81+
```
82+
83+
Generates a new sync key, invalidating all previously issued subscription URLs for this user.
84+
85+
### Response
86+
87+
```json
88+
{
89+
"Data": {
90+
"SubscriptionUrl": "https://api.resgrid.com/api/v4/CalendarExport/CalendarFeed/{new_encrypted_token}",
91+
"WebCalUrl": "webcal://api.resgrid.com/api/v4/CalendarExport/CalendarFeed/{new_encrypted_token}",
92+
"IsActive": true
93+
},
94+
"Status": "success"
95+
}
96+
```
97+
98+
:::warning
99+
Regenerating the subscription URL immediately invalidates the previous URL. Any external calendar application using the old URL will no longer receive updates.
100+
:::
101+
102+
## Calendar Feed (Anonymous)
103+
104+
```
105+
GET /api/v4/CalendarExport/CalendarFeed/{token}
106+
```
107+
108+
This endpoint does **not** require a Bearer token. Authentication is performed via the encrypted token embedded in the URL. This is the endpoint that external calendar applications (Google Calendar, Outlook, Apple Calendar) call to fetch events.
109+
110+
### Parameters
111+
112+
| Parameter | Type | Required | Description |
113+
|-----------|------|----------|-------------|
114+
| `token` | string | Yes | URL-safe Base64-encoded encrypted token |
115+
116+
### Response
117+
118+
- **200 OK** — Content-Type `text/calendar` with the full department iCal feed
119+
- **401 Unauthorized** — Token is invalid, expired, or the sync key has been regenerated
120+
121+
### Token Format
122+
123+
The encrypted token contains `{departmentId}|{userId}|{calendarSyncToken}` encrypted via the system's `IEncryptionService`. The token is made URL-safe using Base64 URL-safe encoding (`+``-`, `/``_`, trailing `=` trimmed).
124+
125+
On each request, the system:
126+
1. Decodes and decrypts the token
127+
2. Extracts the department ID, user ID, and sync GUID
128+
3. Loads the user profile and validates that `CalendarSyncToken` matches the embedded GUID
129+
4. If valid, generates and returns the department calendar feed
130+
131+
### Feature Flag
132+
133+
The feed endpoint respects the `CalendarConfig.ICalFeedEnabled` configuration flag. When disabled, the endpoint returns an error response.
134+
135+
## iCal Output Format
136+
137+
All iCal output conforms to **RFC 5545** and is generated using the `Ical.Net` library.
138+
139+
### Event Mapping
140+
141+
| Calendar Item Field | iCal Property | Notes |
142+
|---------------------|---------------|-------|
143+
| Title | `SUMMARY` | |
144+
| Description | `DESCRIPTION` | |
145+
| Location | `LOCATION` | |
146+
| Start | `DTSTART` | `VALUE=DATE` format when all-day |
147+
| End | `DTEND` | `VALUE=DATE` format when all-day; exclusive (day after last event day) |
148+
| IsAllDay | `DTSTART`/`DTEND` format | Date-only vs. date-time |
149+
| Reminder | `VALARM` | `TRIGGER` based on `GetMinutesForReminder()` |
150+
| Attendees | `ATTENDEE` | Only if populated |
151+
152+
### All-Day and Multi-Day Events
153+
154+
- **All-day events** use `VALUE=DATE` format (no time component) per RFC 5545
155+
- **Multi-day all-day events** set `DTEND` to one day after the last event day (iCal standard uses exclusive end dates for all-day events)
156+
- **Timed events** use full date-time format with UTC offset
157+
158+
### Recurrences
159+
160+
Each materialized recurrence instance is emitted as a separate `VEVENT`. No `RRULE` properties are used because Resgrid pre-expands recurrences in the database.
161+
162+
### PRODID
163+
164+
The `PRODID` value is configurable via `CalendarConfig.ICalProductId` (default: `-//Resgrid//Calendar//EN`).
165+
166+
## Calendar Items API Enhancement
167+
168+
The existing `GetAllCalendarItems` v4 API endpoint response now includes an `IsMultiDay` boolean property on each calendar item, indicating whether the event spans multiple days (where `Start.Date != End.Date`).
169+
170+
### Updated Response Fields
171+
172+
| Field | Type | Description |
173+
|-------|------|-------------|
174+
| `IsMultiDay` | boolean | `true` if the event spans more than one day |
175+
| `IsAllDay` | boolean | `true` if the event is an all-day event (existing field) |
176+
177+
## FullCalendar JSON Enhancement
178+
179+
The `GetV2CalendarEntriesForCal` endpoint (used by the web calendar view) now includes:
180+
181+
| Field | Type | Description |
182+
|-------|------|-------------|
183+
| `allDay` | boolean | `true` for all-day events; enables FullCalendar banner rendering |
184+
185+
For all-day events, the `end` date is set to one day after the last event day to match FullCalendar's exclusive end-date convention.

docs/api/information.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,15 @@ Here you can find some core information, mainly how to authenticate, about the R
1111
The Resgrid API Exposes our Swagger documentation to showcase every call and operation you can perform against the Resgrid API. You can view the documentation by navigating to the Resgrid API Swagger page.
1212

1313
<https://api.resgrid.com/index.html>
14+
15+
## Key API Areas
16+
17+
| Area | Description |
18+
|------|-------------|
19+
| **Authentication** | JWT/OpenID Connect token management |
20+
| **Statuses** | Personnel and unit status operations |
21+
| **Calls** | Dispatch call management |
22+
| **Calendar** | Calendar events, types, and RSVP |
23+
| **Calendar Export** | iCal export, department feed subscriptions, and sync token management (see [Calendar Export API](calendar-export)) |
24+
| **Contact Verification** | Email and phone verification |
25+
| **Workflows** | Automated workflow management |

docs/configuration/calendar-types.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,16 @@ When creating or editing a calendar event, you select a type from the dropdown.
5555

5656
Calendar events also support:
5757
- **Title and Description** — event details
58-
- **Start/End Times** — with time zone support
58+
- **All-Day Events** — span full days without requiring time selection; times auto-normalize to midnight boundaries
59+
- **Start/End Times** — with time zone support (hidden when All Day is checked)
60+
- **Multi-Day Events** — events spanning multiple days display as continuous banners on the calendar
5961
- **Location** — with geocoding for map display
6062
- **Recurrence** — none, weekly, monthly, or yearly
6163
- **Signup Type** — for RSVP-based events
6264
- **Entity Targeting** — target specific groups or the whole department
6365
- **Required/Optional Attendees** — for attendance tracking
6466
- **Reminders** — automated reminders before the event
67+
- **iCal Export** — download individual events as `.ics` files or subscribe to the full calendar feed
6568

6669
## How Calendar Types Connect to Other Features
6770

@@ -71,6 +74,7 @@ Calendar events also support:
7174
| Reports | Events can be analyzed by type for operational reporting |
7275
| Notifications | New calendar events trigger notifications to targeted entities |
7376
| Permissions | Calendar event creation is controlled by the Create Calendar Entry permission |
77+
| Calendar Sync | Exported iCal feeds include event type information |
7478

7579
## Common Errors and Resolutions
7680

0 commit comments

Comments
 (0)