# Synchronization

It is possible to automatically synchronize translations between Crowdin and your integration. This can be done using Cron or Webhooks.

## Cron

To enable Cron synchronization, add the following configuration to your `projectIntegration`:

```js title="index.js"
configuration.projectIntegration.withCronSync = {
  crowdin: true,
  integration: true
}
```

To enable syncing new items, add the following configuration to your `projectIntegration`:

```js title="index.js"
configuration.projectIntegration.syncNewElements = {
    crowdin: true,
    integration: true
}
```

- `crowdin` - enables synchronization from Crowdin to the integration.
- `integration` - enables synchronization from the integration to Crowdin.

### Background Tasks

To register background tasks that the application will call periodically, you can use the `cronJobs` field:

```js title="index.js"
configuration.projectIntegration.cronJobs = [
  {
    // every 10 seconds
    expression: '*/10 * * * * *',
    task: ({ projectId, client, credentials, rootFolder, settings }) => {
      console.log(`Running background task for project : ${projectId}`);
      console.log(`Api credentials : ${JSON.stringify(credentials)}`);
      console.log(`App config : ${JSON.stringify(settings)}`);
      console.log(rootFolder ? JSON.stringify(rootFolder) : 'No root folder');
    }
  }
]
```

For a guide to the cron syntax, see this [documentation](https://github.com/node-cron/node-cron#cron-syntax).

## Webhook

To enable webhook synchronization, add the following configuration to your `projectIntegration`:

```js collapse={6-11, 14-17, 23-40} wrap title="index.js"
configuration.projectIntegration.webhooks = {
  crowdinWebhookUrl: '/notify',
  integrationWebhookUrl: '/update-entity',
  urlParam: 'information',
  crowdinWebhooks: async ({ client, projectId, available, settings }) => {
    await client.webhooksApi.addWebhook(projectId, {
      name: 'Application webhook',
      url: 'https://123.ngrok.io/notify',
      events: ['file.translated'],
      requestType: 'POST'
    });
  },
  crowdinWebhookInterceptor: async ({ projectId, client, rootFolder, settings, syncSettings, webhookRequest }) => {
    return {
      '101': ['de', 'fr'],
      '103': ['de']
    };
  },
  integrationWebhooks: async ({ credentials, urlParam, available, settings, syncSettings }) => {
    // ...
  },
  integrationWebhookInterceptor: async ({ projectId, client, credentials, rootFolder, settings, syncSettings, webhookRequests }) => {
    // ...

    return [
      {
        id: '47282999980',
        name: 'Home page',
        nodeType: '1',
        parentId: '1',
        type: 'json'
      },
      {
        id: '73291251883',
        name: 'Intro',
        nodeType: '1',
        parentId: '2',
        type: 'json'
      }
    ];
  },
  queueUrl: 'amqp://localhost:5672'
}
```

### `crowdinWebhookUrl`

- *Description*: Allows you to override the default Crowdin webhook endpoint.
- *Default value*: `/notify`.
- *Required*: No.

### `integrationWebhookUrl`

- *Description*: Allows you to override the default integration webhook endpoint.
- *Default value*: `/update-entity`.
- *Required*: No.

### `urlParam`

- *Description*: Allows you to override the default request parameter name.
- *Default value*: `crowdinData`.
- *Required*: No.

### `crowdinWebhooks`

- *Description*: This function is called when the application is installed. It is used to create webhooks in Crowdin. If the default webhook doesn't work for you, you can create your own. Used with `crowdinWebhookInterceptor`.
- *Parameters*:
  - `client` - Crowdin client.
  - `projectId` - Crowdin project ID.
  - `available` - Available languages.
  - `settings` - Application settings.
- *Required*: No.

### `crowdinWebhookInterceptor`

- *Description*: This function is called when a webhook is received from Crowdin. It is used to handle the webhook and return the files that need to be synchronized. Used with `crowdinWebhooks`.
- *Parameters*:
  - `projectId` - Crowdin project ID.
  - `client` - Crowdin client.
  - `rootFolder` - Application root folder.
  - `settings` - Application settings.
  - `syncSettings` - Synchronization settings.
  - `webhookRequest` - Webhook request.
- *Required*: No.

### `integrationWebhooks`

- *Description*: This function is called when the application is installed. It is used to create webhooks in the integration. Used with `integrationWebhookInterceptor`.
- *Parameters*:
  - `credentials` - Integration credentials.
  - `urlParam` - Request parameter name.
  - `available` - Available languages.
  - `settings` - Application settings.
  - `syncSettings` - Synchronization settings.

### `integrationWebhookInterceptor`

- *Description*: This function is called when a webhook is received from the integration. It is used to handle the webhook and return the files that need to be synchronized. Used with `integrationWebhooks` and `queueUrl`.
- *Parameters*:
  - `projectId` - Crowdin project ID.
  - `client` - Crowdin client.
  - `credentials` - Integration credentials.
  - `rootFolder` - Application root folder.
  - `settings` - Application settings.
  - `syncSettings` - Synchronization settings.
  - `webhookRequests` - Webhook requests.

### `queueUrl`

- *Description*: RabbitMQ URL to listen to the webhook queue.
- *Required*: No.

## Additional Configuration

There are cases where integration files are stored as folders in Crowdin, and inside these folders, there may be several files. During the automatic synchronization of translations in the integration, the parent folders in Crowdin are deleted, and as a result, none of the translations may be sent.

When the `skipAutoSyncFoldersFilter` parameter is enabled, the program bypasses the folder filtering logic and returns the files unchanged:

```js title="index.js"
configuration.projectIntegration.skipAutoSyncFoldersFilter = true;
```