Availability
Custom connector is only available on the Pro tier introduced in March 2022 (not on any legacy Pro tier). To change to the new Pro tier, click here.
Purpose
You can build your own calendar service and integrate it with the Calendar app and make it work just like Google Calendar or Office 365 Calendar. This can be useful for other cloud based calendar services but you can also build a cloud connector for an on-premise calendar solution such as Microsoft Exchange.
Setup
Even when using a calendaring service that isn't visible to the public internet, a proxy can be built which then only needs to be exposed through the firewall but only to the IP addresses of the SweetHawk app server. We strongly recommend using HTTPS exclusively.
Enter your endpoint to your custom calendar service in the Calendar app in the Admin section, note the endpoint must be available on the public internet. You may configure your firewall to only allow SweetHawk's IP addresses documented here.
Authentication
Individual Calendar users can add a custom calendar account by supplying their username and password, which will then be passed on the user's behalf on any API calls.
API definition
An external calendar sync service must provide the following APIs:
List calendars
Must return a list of all calendars for the current user.
GET /calendars
Response
[
{
"Id": "abc1234",
"Name": "My Custom Calendar",
"Color": "LightBlue",
"Owner": null,
"CanEdit": true
},
{
"Id": "def1235",
"Name": "A second one",
"Color": "#cccccc",
"Owner": null,
"CanEdit": false
},
{
"Id": "xyz1236",
"Name": "Cal number 3",
"Color": "LightOrange",
"Owner": {
"Name": "Jane Smith",
"Address": "jsmith@example.com"
},
"CanEdit": true
}
]
Event format
Events must use the following format:
{
"Id": "AAMkAGI2TG93AAA=",
"Subject": "Weekly Meeting on Contoso Project",
"BodyPreview": "Setting up some time to review the budget and planning on the Contoso Project",
"Body": {
"Content": "<html>\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\r\n</head>\r\n<body>\r\nSetting up some time to review the budget and planning on the Contoso Project\r\n</body>\r\n</html>\r\n"
},
"Start": {
"DateTime": "2014-10-13T21:00:00",
"TimeZone": "Pacific Standard Time"
},
"End": {
"DateTime": "2014-10-13T22:00:00",
"TimeZone": "Pacific Standard Time"
},
"Location": {
"DisplayName": "My Office",
"Address": null
},
"IsAllDay": false,
"Attendees": [
{
"EmailAddress": {
"Address": "jschorr@example.com",
"Name": "Janet Schorr"
}
}
],
"Sensitivity": "Private",
"WebLink": "http://example.com/event/event123"
}
Note "WebLink" is a URL that will show the event to the end-user. This does not have to be an internet-facing URL, it can be a private/intranet/local link.
Please use this event format for all APIs below.
List events
List all events in a calendar between specific timeframe between 'start' and 'end' parameters. The 'time_zone' parameter specifies in which time zone the events need to be shown. Recurring events must be expanded into actual occurrences of the event. The purpose of this API is to create a calendar view, so for any recurring events it should only show instances that would fall in the intended time range.
GET /calendars/1/events?start=2020-12-31T23:59:59&end=2021-12-31T23:59:59&time_zone=America/Los_Angeles
Response
[
{
"Id": "event123",
"Subject": "A test event",
"Sensitivity": "Private",
"IsAllDay": true,
"Start": { "DateTime" => "2020-12-31T00:00:00" },
"End": { "DateTime" => "2021-01-01T00:00:00" },
"Location": null,
"WebLink": "http://example.com/event/event123",
},
{
"Id": "event124",
"Subject": "Another test event",
"Sensitivity": "Public",
"IsAllDay": false,
"Start": { "DateTime" => "2020-12-31T22:59:59" },
"End": { "DateTime" => "2020-12-31T23:59:59" },
"Location": { "DisplayName" => "Home" },
"WebLink": "http://example.com/event/event124",
}
]
Show event
Lookup an event by ID.
GET /calendars/1/events/123456
Response
{
"Id": "event124",
...
}
Create event
In writeable calendars, Calendar app will sync events when created on a ticket. This method call is expected to return the ID of the created event in case of success.
POST /calendars/1/events
{
"Subject": "Ticket event",
...
}
Response
{
"Id": 123458
}
Update event
Similar call to create the event, but the update does not need to return anything.
PATCH /calendars/1/events/123456
{
"Subject": "Ticket event",
...
}
Delete event
DELETE /calendars/1/events/123456
Register webhook
Any updates to an event in a calendar can be synced to Calendar app. Calendar app will register a webhook to post any events that are added, changed, or deleted.
POST /calendar/1/subscription
{
"Webhook": "https://zendesk.sweethawk.co/...."
}
Response
{
"Id": 123
}
Your listener subscription should not continue forever but rather have an expiry. Each day when the 2-way sync is still actively listening, we will send further requests to keep the subscription alive. Your service should respond with an identifier of the created subscription, so we can send subsequent calls as:
Keep webhook alive
PATCH /calendar/1/subscription/123
{
"Webhook": "https://zendesk.sweethawk.co/...."
}
To call the webhook, please pass the following payload:
{
"ChangeType": "Created",
"Id": "123459"
}
{
"ChangeType": "Updated",
"Id": "123459"
}
{
"ChangeType": "Deleted",
"Id": "123459"
}
Should the HTTP response be code 410, the sync is no longer needed and the webhook can be removed.
Comments
0 comments