> ## Documentation Index
> Fetch the complete documentation index at: https://docs.postiz.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How to add a new provider

> How to add a new provider to Postiz

# Steps to implement a new provider

1. **The backend logic:**
   * Define DTO for the settings of the provider
   * Generate an authentication URL
   * Authenticate the user from the callback
   * Refresh the user token

2. **The frontend logic:**
   * Implement the settings page
   * Implement the preview page
   * Upload the provider image

## Social Media

### Backend

For our example, we will use the X provider.

<Steps>
  <Step title="Create a DTO for provider settings">
    Head over to `nestjs-libraries/src/dtos/posts/providers-settings` and create a new file `x-provider-settings.dto.ts`

    <Note>
      You don't have to create a DTO if there are no settings
    </Note>

    Once created head over to `nestjs-libraries/src/dtos/posts/providers-settings/all.providers.settings.ts` and add the new DTO.

    Head to `libraries/nestjs-libraries/src/dtos/posts/create.post.dto.ts`, look for the discriminator and add another line in the format of:

    ```typescript theme={null}
    { value: DTOClassName, name: 'providerName' },
    ```
  </Step>

  <Step title="Create the provider file">
    Head over to `libraries/nestjs-libraries/src/integrations/social` and create a new provider file `providerName.provider.ts`

    For oAuth2 providers, the content of the file should look like this:

    ```typescript theme={null}
    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
      }
    }
    ```

    Take a look at the existing providers to see how to implement the methods.
  </Step>

  <Step title="Register with Integration Manager">
    Open `libraries/nestjs-libraries/src/integrations/integration.manager.ts` and add the new provider to either `socialIntegrationList` (oAuth2) or `articleIntegrationList` (Token)
  </Step>
</Steps>

### Custom functions

You might want to create custom functions for the providers for example: get available orgs, get available pages, etc.

You can create a public function in the provider for example `organizations` and later call it from a special hook from the frontend.

***

### Frontend

<Steps>
  <Step title="Create provider component">
    Head over to `apps/frontend/src/components/launches/providers` and create a new folder with the providerName.

    Add a new file `providerName.provider.tsx` with the following content:

    ```typescript theme={null}
    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);
    ```
  </Step>

  <Step title="Use custom provider functions (optional)">
    If you want to use a custom function for the provider you can use the `useCustomProviderFunction` hook.

    ```typescript theme={null}
    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 integrations to understand what data to put inside.
  </Step>

  <Step title="Register the provider">
    Open `apps/frontend/src/components/launches/providers/show.all.providers.tsx` and add the new provider to the list.

    ```typescript theme={null}
    {identifier: 'providerName', component: DefaultImportFromHighOrderProvider},
    ```
  </Step>
</Steps>
