forked from NangoHQ/nango
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(integration-templates): add luma integration template (NangoHQ#2490
) ## Describe your changes - Add Luma `list-events` integration template. ## Issue ticket number and link [EXT-104](https://linear.app/nango/issue/EXT-104/provide-example-of-luma-pagination)
- Loading branch information
1 parent
b628b13
commit ee0b06d
Showing
7 changed files
with
245 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
title: 'Luma API Integration Template' | ||
sidebarTitle: 'Luma' | ||
--- | ||
|
||
## Get started with the Luma template | ||
|
||
<Card title="How to use integration templates" | ||
href="/understand/concepts/templates" | ||
icon="book-open"> | ||
Learn how to use integration templates in Nango | ||
</Card> | ||
|
||
<Card title="Get the Luma template" | ||
href="https://github.com/NangoHQ/nango/tree/master/integration-templates/luma" | ||
icon="github"> | ||
Get the latest version of the Luma integration template from GitHub | ||
</Card> | ||
|
||
## Need help with the template? | ||
Please reach out in the [Slack community](https://nango.dev/slack), we are very active there and happy to help! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import type { LumaEvent } from '../types'; | ||
import type { Event } from '../../models'; | ||
/** | ||
* Converts a LumaEvent object to a slim Event object. | ||
* Only includes essential properties mapped from LumaEvent. | ||
* @param event The LumaEvent to be converted. | ||
* @returns The corresponding slim Event object. | ||
*/ | ||
export function toEvent(event: LumaEvent): Event { | ||
const formattedEvent: Event = { | ||
id: event.event.api_id, | ||
created_at: new Date(event.event.created_at).toISOString(), | ||
cover_url: event.event.cover_url, | ||
name: event.event.name, | ||
description: event.event.description, | ||
description_md: event.event.description_md, | ||
series_api_id: event.event.series_api_id, | ||
start_at: new Date(event.event.start_at).toISOString(), | ||
duration_interval_iso8601: event.event.duration_interval, | ||
end_at: new Date(event.event.end_at).toISOString(), | ||
geo_latitude: event.event.geo_latitude, | ||
geo_longitude: event.event.geo_longitude, | ||
geo_address_json: event.event.geo_address_json | ||
? { | ||
city: event.event.geo_address_json.city, | ||
type: event.event.geo_address_json.type, | ||
region: event.event.geo_address_json.region, | ||
address: event.event.geo_address_json.address, | ||
country: event.event.geo_address_json.country, | ||
latitude: event.event.geo_address_json.latitude, | ||
place_id: event.event.geo_address_json.place_id, | ||
longitude: event.event.geo_address_json.longitude, | ||
city_state: event.event.geo_address_json.city_state, | ||
description: event.event.geo_address_json.description, | ||
full_address: event.event.geo_address_json.full_address | ||
} | ||
: null, | ||
url: event.event.url, | ||
timezone: event.event.timezone, | ||
event_type: event.event.event_type, | ||
user_api_id: event.event.user_api_id, | ||
visibility: event.event.visibility, | ||
meeting_url: event.event.meeting_url, | ||
zoom_meeting_url: event.event.zoom_meeting_url | ||
}; | ||
|
||
return formattedEvent; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
integrations: | ||
luma: | ||
syncs: | ||
list-events: | ||
description: | | ||
This sync will be used to sync all of the events managed by your Calendar. See https://docs.lu.ma/reference/calendar-list-events for more details. | ||
endpoint: GET /luma/list-events | ||
sync_type: incremental | ||
runs: every day | ||
output: Event | ||
models: | ||
Timestamps: | ||
created_at: string | ||
start_at: string | ||
end_at: string | ||
Event: | ||
id: string | ||
__extends: Timestamps | ||
cover_url: string | ||
name: string | ||
description: string | ||
description_md: string | ||
series_api_id: string | null | ||
duration_interval_iso8601: string | ||
geo_latitude: string | null | ||
geo_longitude: string | null | ||
geo_address_json: GeoAddress | null | ||
url: string | ||
timezone: string | ||
event_type: string | ||
user_api_id: string | ||
visibility: string | ||
meeting_url: string | null | ||
zoom_meeting_url: string | null | ||
GeoAddress: | ||
city: string | ||
type: string | ||
region: string | ||
address: string | ||
country: string | ||
latitude: string | ||
place_id: string | ||
longitude: string | ||
city_state: string | ||
description: string | ||
full_address: string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import type { NangoSync, Event } from '../../models'; | ||
import type { LumaEvent } from '../types'; | ||
import { toEvent } from '../mappers/to-event.js'; | ||
|
||
/** | ||
* Fetches events from a specified endpoint and processes them for synchronization. | ||
* Uses pagination and retries for robust data retrieval and saving. | ||
* Convert LumaEvent to Event using mapping function. | ||
* | ||
* @param nango An instance of NangoSync for handling synchronization tasks. | ||
* @returns Promise that resolves when all events are fetched and saved. | ||
*/ | ||
export default async function fetchData(nango: NangoSync): Promise<void> { | ||
const endpoint = '/public/v1/calendar/list-events'; | ||
const config = { | ||
// Include 'after' parameter with the lastSyncDate if available | ||
...(nango.lastSyncDate ? { params: { after: nango.lastSyncDate?.toISOString() } } : {}), | ||
paginate: { | ||
type: 'cursor', | ||
cursor_path_in_response: 'next_cursor', | ||
cursor_name_in_request: 'pagination_cursor', | ||
response_path: 'entries', | ||
limit_name_in_request: 'pagination_limit', | ||
limit: 100 | ||
}, | ||
retries: 10 | ||
}; | ||
|
||
for await (const events of nango.paginate<LumaEvent>({ ...config, endpoint })) { | ||
const formattedEvents = events.map((event: LumaEvent) => toEvent(event)); | ||
await nango.batchSave<Event>(formattedEvents, 'Event'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
interface GeoAddress { | ||
city: string; | ||
type: string; | ||
region: string; | ||
address: string; | ||
country: string; | ||
latitude: string; | ||
place_id: string; | ||
longitude: string; | ||
city_state: string; | ||
description: string; | ||
full_address: string; | ||
} | ||
|
||
interface Event { | ||
api_id: string; | ||
created_at: string; | ||
cover_url: string; | ||
name: string; | ||
description: string; | ||
description_md: string; | ||
series_api_id: string | null; | ||
start_at: string; | ||
duration_interval: string; | ||
end_at: string; | ||
geo_address_json: GeoAddress | null; | ||
geo_latitude: string | null; | ||
geo_longitude: string | null; | ||
url: string; | ||
timezone: string; | ||
event_type: string; | ||
user_api_id: string; | ||
visibility: string; | ||
meeting_url: string | null; | ||
zoom_meeting_url: string | null; | ||
} | ||
|
||
interface Tag { | ||
api_id: string; | ||
name: string; | ||
} | ||
|
||
export interface LumaEvent { | ||
api_id: string; | ||
event: Event; | ||
tags: Tag[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters