Skip to content

Commit

Permalink
feat(integration-templates): add discourse integration template (#2722)
Browse files Browse the repository at this point in the history
## Describe your changes

- Add discourse integration template

## Issue ticket number and link

## Checklist before requesting a review (skip if just adding/editing
APIs & templates)
- [ ] I added tests, otherwise the reason is: 
- [ ] I added observability, otherwise the reason is:
- [ ] I added analytics, otherwise the reason is:

---------

Co-authored-by: Samuel Bodin <1637651+bodinsamuel@users.noreply.github.com>
  • Loading branch information
hassan254-prog and bodinsamuel authored Sep 16, 2024
1 parent e99ae8b commit 960e267
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 0 deletions.
21 changes: 21 additions & 0 deletions docs-v2/integrations/integration-templates/discourse.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: 'Discourse API Integration Template'
sidebarTitle: 'Discourse'
---

## Get started with the Discourse 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 Discourse template"
href="https://github.com/NangoHQ/nango/tree/master/integration-templates/discourse"
icon="github">
Get the latest version of the Discourse 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!
1 change: 1 addition & 0 deletions docs-v2/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@
"integrations/integration-templates/checkr-partner",
"integrations/integration-templates/checkr-partner-staging",
"integrations/integration-templates/clari-copilot",
"integrations/integration-templates/discourse",
"integrations/integration-templates/expensify",
"integrations/integration-templates/exact-online",
"integrations/integration-templates/evaluagent",
Expand Down
44 changes: 44 additions & 0 deletions integration-templates/discourse/helpers/paginate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { NangoSync, ProxyConfiguration } from '../../models';

export interface PaginationParams {
endpoint: string;
initialPage?: number;
params?: Record<string, any>;
}

/**
* Asynchronous generator function for paginating through API results.
*
* This function handles pagination by making repeated requests to the specified API endpoint.
* It yields arrays of results for each page until no more data is available.
*
* @param nango The NangoSync instance used for making API calls.
* @param params Configuration parameters for pagination, including the endpoint, initial page, and additional params.
* @returns An async generator that yields arrays of results from each page.
*/
async function* paginate<T>(nango: NangoSync, { endpoint, initialPage = 1, params }: PaginationParams): AsyncGenerator<T[], void, undefined> {
let currentPage = initialPage;

while (true) {
const payload: ProxyConfiguration = {
endpoint,
params: {
page: currentPage,
...params
}
};

const response = await nango.get<T[]>(payload);
const responseData = response.data;

if (!responseData || responseData.length === 0) {
break;
}

yield responseData;

currentPage++;
}
}

export default paginate;
17 changes: 17 additions & 0 deletions integration-templates/discourse/mappers/toUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { User } from '../../models';
import type { DiscourseUser } from '../types';

/**
* Converts a DiscourseUser object to a slim User object.
* Only includes essential properties mapped from DiscourseUser.
* @param user The DiscourseUser object to convert.
* @returns User object representing DiscourseUser user information.
*/
export function toUser(user: DiscourseUser): User {
return {
id: user.id,
username: user.username,
name: user.name,
admin: user.admin
};
}
17 changes: 17 additions & 0 deletions integration-templates/discourse/nango.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
integrations:
discourse:
syncs:
active-users:
description: |
Fetches a list of active users from Discourse.
endpoint: /discourse/active-users
sync_type: full
runs: every 1 hour
output: User
track_deletes: true
models:
User:
id: number
username: string
name: string
admin: boolean
32 changes: 32 additions & 0 deletions integration-templates/discourse/syncs/active-users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { NangoSync, User } from '../../models';
import type { DiscourseUser } from '../types';
import paginate from '../helpers/paginate.js';
import type { PaginationParams } from '../helpers/paginate';
import { toUser } from '../mappers/toUser.js';

/**
* Fetches user data from an API and saves it in batch.
*
* This function uses the `paginate` helper to fetch active users from the specified API endpoint in a paginated manner.
* It maps the raw user data to a `User` format using the `toUser` mapper function and then saves the mapped data
* using the `nango.batchSave` method.
* For detailed endpoint documentation, refer to:
* https://docs.discourse.org/#tag/Admin/operation/adminListUsers
*
* @param nango The NangoSync instance used for making API calls and saving data.
* @returns A promise that resolves when the data has been successfully fetched and saved.
*/
export default async function fetchData(nango: NangoSync): Promise<void> {
const config: PaginationParams = {
endpoint: '/admin/users/list/active',
params: {
order: 'created',
asc: 'true',
stats: true // Additional parameters for the API request can be added in here
}
};

for await (const users of paginate<DiscourseUser>(nango, config)) {
await nango.batchSave<User>(users.map(toUser), 'User');
}
}
26 changes: 26 additions & 0 deletions integration-templates/discourse/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export interface DiscourseUser {
id: number;
username: string;
name: string;
avatar_template: string;
email: string;
secondary_emails: (string | null)[];
active: boolean;
admin: boolean;
moderator: boolean;
last_seen_at: string;
last_emailed_at: string;
created_at: string;
last_seen_age: number;
last_emailed_age: number;
created_at_age: number;
trust_level: number;
manual_locked_trust_level: string;
title: string;
time_read: number;
staged: boolean;
days_visited: number;
posts_read_count: number;
topics_entered: number;
post_count: number;
}
16 changes: 16 additions & 0 deletions packages/shared/flows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,22 @@ integrations:
body:
storage: object
atlas_doc_format: object
discourse:
syncs:
active-users:
description: |
Fetches a list of active users from Discourse.
endpoint: /discourse/active-users
sync_type: full
runs: every 1 hour
output: User
track_deletes: true
models:
User:
id: number
username: string
name: string
admin: boolean
evaluagent:
syncs:
users:
Expand Down

0 comments on commit 960e267

Please sign in to comment.