---
title: Automatically synchronizing staging and integration tasks
related:
  - https://docs.kentico.com/13/deploying-websites/content-staging.md
  - https://docs.kentico.com/13/deploying-websites/content-staging/automatic-content-synchronization/synchronizing-content-using-the-api.md
  - https://docs.kentico.com/13/integrating-3rd-party-systems/using-the-integration-bus.md
  - https://docs.kentico.com/13/custom-development/handling-global-events.md
  - https://docs.kentico.com/13/custom-development/handling-global-events/reference-global-system-events.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

You can use [event handlers](https://docs.kentico.com/13/custom-development/handling-global-events.md) to automatically synchronize [content staging](https://docs.kentico.com/13/deploying-websites/content-staging.md) and [integration bus](https://docs.kentico.com/13/integrating-3rd-party-systems/using-the-integration-bus.md) tasks. Use the API to synchronize the required tasks during the following events:

- **StagingEvents.LogTask.After**
- **IntegrationEvents.LogInternalTask.After**
- **IntegrationEvents.LogExternalTask.After**

> **Tip:** **Tip**: Access the data of the synchronization task through the **Task** property of the event handler's **StagingLogTaskEventArgs** or **IntegrationTaskEventArgs** parameter.

## Example

The following example demonstrates how to automatically synchronize staging tasks and outgoing integration tasks:

1. Open your solution in Visual Studio.
2. Create a [custom module class](https://docs.kentico.com/13/custom-development/creating-custom-modules/initializing-modules-to-run-custom-code.md).
   - Add the class into a custom _Class Library_ project within the solution.
3. Override the module's **OnInit** method and assign handlers to the **StagingEvents.LogTask.After** and **IntegrationEvents.LogInternalTask.After** events.

   ```csharp

   using CMS;
   using CMS.DataEngine;
   using CMS.Synchronization;
   using CMS.SynchronizationEngine;

   // Registers the custom module into the system
   [assembly: RegisterModule(typeof(LogTaskHandlerModule))]

   public class LogTaskHandlerModule : Module
   {
       // Module class constructor, the system registers the module under the name "LogTaskHandlers"
       public LogTaskHandlerModule()
           : base("LogTaskHandlers")
       {
       }

       // Contains initialization code that is executed when the application starts
       protected override void OnInit()
       {
           base.OnInit();

           // Assigns a handler to the StagingEvents.LogTask.After event
           // This event occurs after the system creates content staging synchronization tasks (separately for each task)
           StagingEvents.LogTask.After += LogStagingTask_After;

           // Assigns a handler to the IntegrationEvents.LogInternalTask.After event
           // This event occurs after the system creates outgoing integration tasks (separately for each task)
           IntegrationEvents.LogInternalTask.After += LogIntegrationTask_After;
       }
   }

   ```
4. Define the handler methods (inside the custom module class):

   ```csharp

   // Automatically synchronizes staging tasks
   private void LogStagingTask_After(object sender, StagingTaskEventArgs e)
   {
       if (e.Task != null)
       {
           // Gets the identifiers of the staging servers for which the task was created
           var taskServerIds = SynchronizationInfo.Provider.Get()
                                                           .Column("SynchronizationServerID")
                                                           .WhereEquals("SynchronizationTaskID", e.Task.TaskID);

           // Gets the task's staging servers based on the retrieved identifiers
           var targetServers = ServerInfo.Provider.Get().WhereIn("ServerID", taskServerIds);

           // Processes the task for all relevant servers
           foreach (ServerInfo server in targetServers)
           {
               // Synchronizes the processed staging task to the target server
               new StagingTaskRunner(server.ServerID).RunSynchronization(e.Task.TaskID);
           }
       }
   }

   // Automatically synchronizes outgoing integration tasks
   private void LogIntegrationTask_After(object sender, IntegrationTaskEventArgs e)
   {
       // Gets the info object for an integration connector
       IntegrationConnectorInfo connectorInfo = IntegrationConnectorInfo.Provider.Get("MyConnector");

       if ((connectorInfo != null) && (e.Task != null))
       {
           // Gets an instance of the integration connector class
           BaseIntegrationConnector connector = IntegrationHelper.GetConnector(connectorInfo.ConnectorName) as BaseIntegrationConnector;

           // Synchronizes the processed integration task
           connector.ProcessInternalTask(e.Task);
       }
   }

   ```
5. Save the class and Rebuild the solution.

The handlers ensure that the system immediately synchronizes:

- All staging tasks to all relevant target servers
- All outgoing integration tasks using a specified connector
