---
title: How to add a new provider
description: How to add a new provider to Gitroom
---

The system is designed to be easily extensible.
Each provider need to implement multiple things.
There are two main options:
- Implement a social media provider (oAuth2)
- Implement a publishing provider (Token)

<ol>
  <li>
    ### The backend logic:
    <ul>
      <li>Define DTO for the settings of the provider</li>
      <li>Generate an authentication URL</li>
      <li>Authenticate the user from the callback</li>
      <li>Refresh the user token</li>
    </ul>
  </li>
  <li>
    ### The frontend logic:
    <ul>
      <li>Implement the settings page</li>
      <li>Implement the preview page</li>
      <li>Upload the provider image</li>
    </ul>
  </li>
</ol>

## Social Media

### Backend
For our example, we will use the X provider.<br />
1. First, we need to create a DTO for the settings of the provider.<br />
head over to `nestjs-libraries/src/dtos/posts/providers-settings`
And create a new file `x-provider-settings.dto.ts`<br />
(you don't have to create a DTO if there are no settings)<br /><br />
Once created head over to `nestjs-libraries/src/dtos/posts/providers-settings/all.providers.settings.ts`
And add the new DTO.<br /><br />
Head to `libraries/nestjs-libraries/src/dtos/posts/create.post.dto.ts`<br />
look for the discriminator and add another line in the format of<br />

```typescript create.post.dto.ts
{ value: DTOClassName, name: 'providerName' },
```

2. head over to `libraries/nestjs-libraries/src/integrations/social`<br />
And create a new provider file `providerName.provider.ts`<br />
The content of the file should look like this:

<CodeGroup>
```typescript For oAuth2 providers
import {
  AuthTokenDetails,
  PostDetails,
  PostResponse,
  SocialProvider,
} from '@gitroom/nestjs-libraries/integrations/social/social.integrations.interface';

export class XProvider implements SocialProvider {
  identifier = 'providerName';
  name = 'Provider Name';
  async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
    ...refresh the token
  }

  async generateAuthUrl() {
    ...generate the auth url
  }

  async authenticate(params: { code: string; codeVerifier: string }) {
    ...authenticate the user
  }

  async post(
    id: string,
    accessToken: string,
    postDetails: PostDetails<DTOClassName>[]
  ): Promise<PostResponse[]> {
    ...post the content
  }
}
```

```typescript For Token providers
import { ArticleProvider } from '@gitroom/nestjs-libraries/integrations/article/article.integrations.interface';

export class DevToProvider implements ArticleProvider {
  identifier = 'providerName';
  name = 'ProviderName';
  async authenticate(token: string) {

  }

  async post(token: string, content: string, settings: DTOClassName) {

  }
}
```
</CodeGroup>

Take a look at the exising providers to see how to implement the methods.

### Custom functions
You might want to create custom functions for the providers for example: get available orgs, get available pages, etc.<br />
You can create a public function in the provider for example `organizations` and later call it from a special hook from the frontend.

### Integration Manager
Open `libraries/nestjs-libraries/src/integrations/integration.manager.ts`
And add the new provider to either `socialIntegrationList` (oAuth2) or `articleIntegrationList` (Token)

---

### Frontend

1. Head over to `apps/frontend/src/components/launches/providers`
Create a new folder with the providerName<br />
Add a new file `providerName.provider.tsx`<br />
The content of the file should look like this:

```typescript providerName.provider.tsx
import { FC } from 'react';
import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider';
import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values';
import { useIntegration } from '@gitroom/frontend/components/launches/helpers/use.integration';

const ProviderPreview: FC = () => {
  const { value } = useIntegration();
  const settings = useSettings();

  return (
    ...Preview
  );
};

const ProviderSettings: FC = () => {
  const form = useSettings();
  const { date } = useIntegration();
  return (
    ...Settings
  );
};

export default withProvider(DevtoSettings, DevtoPreview, DTOClassName);
```

If you want to use a custom function for the provider you can use the `useCustomProviderFunction` hook.

```typescript
import { useCustomProviderFunction } from '@gitroom/frontend/components/launches/helpers/use.custom.provider.function';
import { useCallback } from 'react';
const customFunc = useCustomProviderFunction();

// and use it like that:
const getOrgs = useCallback(() => {
  customFunc.get('organizations', {
      anyKey: 'anyValue'
  })
}, []);
```

It will automatically interact with the right provider saved for the user.

You can look at the other integration to understand what data to put inside.

2. Open `apps/frontend/src/components/launches/providers/show.all.providers.tsx`
And add the new provider to the list.
```typescript show.all.providers.tsx
    {identifier: 'providerName', component: DefaultImportFromHighOrderProvider},
```
