Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(integration-templates): add discourse integration template #2722

Merged
merged 6 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
hassan254-prog marked this conversation as resolved.
Show resolved Hide resolved
endpoint: /discourse/active-users
sync_type: full
runs: every 1 hour
hassan254-prog marked this conversation as resolved.
Show resolved Hide resolved
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
Loading