guideImport and export

# Overview

The process of saving the data of the document in an active collaboration session with multiple users can be challenging. A simple implementation using the autosave plugin comes with some drawbacks. Another approach to initializing and saving collaboration data can solve most of them.

The import and export feature, based on the REST API, improves the process of synchronizing the data of the document which is saved in your database. When using this feature, the responsibility for saving the current document data will be transferred from the users to your server.

# The Import and Export endpoints

This feature utilizes two methods available from the REST API:

  • Import a document – Use this endpoint to set the initial content and create a new collaboration session. This endpoint will not work if a collaboration session with a given documentId already exists.
  • Export a document – Use this endpoint to fetch the content from an active collaboration session. In the response, you will get plain HTML or Markdown output from the editor (depending on the editor configuration), just like you would call editor.getData() on the client side.

Follow this guide to learn how to properly setup and use this feature.

# Prerequisites

To use the import and export feature, an editor with its configuration needs to be uploaded to the CKEditor Cloud Services server. Cloud Services is using your editor to generate the correct output during the export and to validate the input during the import. Thanks to this approach, your custom plugins that could generate some custom data will also work correctly.

There are two steps that need to be taken, before you can start using the feature:

  1. Upload your editor bundle with the editor configuration to the CKEditor Cloud Services server. Refer to the Editor bundle guide for more information.
  2. Set the required bundleVersion property in the editor configuration. Refer to the Editor configuration section of the editor bundle documentation for more details.

It is also possible to initialize a new collaboration session with your data without uploading the editor bundle using the use_inital_data parameter. Please remember that this will only work when importing a document. The Export feature always requires an uploaded editor bundle. Refer to the REST API documentation for more details.

# Usage

After successfully uploading your editor bundle to CKEditor Cloud Services you can start using the import and export feature. Every request made to Cloud Services REST API needs to have the following headers:

  • X-CS-Timestamp – the value of this header will be used for the signature generation and validation and it is very important to use a unique value for every request to make sure that the generated signatures will be unique as well. This value needs to be a number. Good example of a timestamp is the current Unix time.
  • X-CS-Signature – the value of this header is generated using a SHA-256 algorithm and is signed with the API Secret. CKEditor Cloud Services are also generating signatures for every request and only accept the ones with a correct signature. Refer to the Request signature guide for more information.

Check an example of an application that uses this mechanism in Node.js and Express.js or follow this guide for more details on the feature’s usage.

Also, you can check the CKEditor Cloud Services samples repository, where you can find more examples.

# Import

Importing a document means creating a new collaboration session using the previously saved document data. It is based on sending a request from your server to CKEditor Cloud Services using the POST /collaborations REST API method with the required data in the body:

{
  "document_id": "your_document_id",
  "bundle_version": "your_editor_id",
  "data": "<p>document_content</p>"
}

At this point, CKEditor Cloud Services converts the document data sent in the request using the previously uploaded editor bundle with a set bundle_version and creates an active collaborative session for the document_id.

After this operation, users can connect to the newly created collaboration session and continue working on the loaded document.

There are more Cloud Services REST API methods that you will find when working with collaboration data:

  • The document exists – use this API endpoint to check if an active collaboration session with a given documentId already exists. Remember that import will only succeed, when there is no active collaboration session, and you can use this method to check it before importing the data.
  • Flush a document – use this API endpoint to remove an active collaboration session. Collaboration sessions without connected users will be removed after 24 hours, but in case when the removal should be immediate, this API method can be used to remove it manually.

# Example

This example is using node.js and npm. Make sure that you have these tools installed before you follow the next steps. This snippet assumes that you have already followed the steps from Prerequisites section.

  1. Run the following commands:
mkdir cs-import-example && cd cs-import-example
npm init -y && npm i axios
  1. Create a new file named import.js in the cs-import-example folder with the following content:
const crypto = require( 'crypto' );
const axios = require( 'axios' );

// Update with your credentials and application endpoint
const environmentId = 'txQ9sTfqmXUyWU5LmDbr';
const apiSecret = '4zZBCQoPfRZ7Rr7TEnGAuRsGgbfF58Eg0PA8xcLD2kvPhjGjy4VGgB8k0hXn';
const applicationEndpoint = 'https://33333.cke-cs.com';
const apiEndpoint = `${ applicationEndpoint }/api/v4/${ environmentId }/collaborations/`;

const body = {
   document_id: "document-1", // Set document_id of created collaboration session
   bundle_version: "bundleversion-1", // Use bundle_version from uploaded editor bundle
   data: "<p>Lorem Ipsum is <b>simply dummy</b> text of the printing and typesetting industry.</p>"
};

const CSTimestamp = Date.now();
const config = {
   headers: {
      'X-CS-Timestamp': CSTimestamp,
      'X-CS-Signature': generateSignature( apiSecret, 'POST', apiEndpoint, CSTimestamp, body )
   },
};

axios.post( apiEndpoint, body, config )
   .then( response => {
      console.log ( response.status );
   } ).catch( error => {
      console.log( error.message );
      console.log( error.response.data );
   } );

function generateSignature( apiSecret, method, uri, timestamp, body ) {
   const url = new URL( uri );
   const path = url.pathname + url.search;
   const hmac = crypto.createHmac( 'SHA256', apiSecret );

   hmac.update( `${ method.toUpperCase() }${ path }${ timestamp }` );

   if ( body ) {
      hmac.update( Buffer.from( JSON.stringify( body ) ) );
   };

   return hmac.digest( 'hex' );
}
  1. Update your credentials, the document_id and bundle_version values in the code snippet.

  2. Run the import with the node import.js command.

After a successful response with a status code 204 you can open the editor with the same document_id as set in the snippet to see your imported content. You can also check the content using the export method.

# Export

Exporting a document means getting the current data of the document from an active collaboration session. It is based on sending a request from your server to CKEditor Cloud Services using the GET /collaborations/{document_id} REST API method.

At this point, using the previously loaded editor bundle, CKEditor Cloud Services converts an active collaboration session to the configured output form (HTML, Markdown, text etc.) which your server will receive in response to the request. Your server should save the received document data in the database.

It is recommended to perform this operation at least once after all users disconnect from the document.

You can achieve this with the GET /collaborations/{document_id}/users REST API method to fetch information about users connected to the collaboration session. Alternatively, you can use the User disconnected webhook event.

# Example

This example is using node.js and npm. Make sure that you have these tools installed before you follow the next steps. This snippet assumes that you have already followed the steps from the Prerequisites section.

  1. Run the following commands:
mkdir cs-export-example && cd cs-export-example
npm init -y && npm i axios
  1. Create a new file named export.js in the cs-export-example folder with the following content:
const crypto = require( 'crypto' );
const axios = require( 'axios' );

// Update with your credentials and application endpoint
const environmentId = 'txQ9sTfqmXUyWU5LmDbr';
const apiSecret = '4zZBCQoPfRZ7Rr7TEnGAuRsGgbfF58Eg0PA8xcLD2kvPhjGjy4VGgB8k0hXn';
const applicationEndpoint = 'https://33333.cke-cs.com';

const documentId = 'document-1'; // Set document_id of an active collaboration session
const apiEndpoint = `${ applicationEndpoint }/api/v4/${ environmentId }/collaborations/${ documentId }`;

const CSTimestamp = Date.now();
const config = {
   headers: {
      'X-CS-Timestamp': CSTimestamp,
      'X-CS-Signature': generateSignature( apiSecret, 'GET', apiEndpoint, CSTimestamp )
   },
};

axios.get( apiEndpoint, config )
   .then( response => {
      console.log ( response.data );
   } ).catch( error => {
      console.log( error.message );
      console.log( error.response.data );
   } );

function generateSignature( apiSecret, method, uri, timestamp, body ) {
   const url = new URL( uri );
   const path = url.pathname + url.search;
   const hmac = crypto.createHmac( 'SHA256', apiSecret );

   hmac.update( `${ method.toUpperCase() }${ path }${ timestamp }` );

   if ( body ) {
      hmac.update( Buffer.from( JSON.stringify( body ) ) );
   };

   return hmac.digest( 'hex' );
}
  1. Update your credentials and the documentId value in the code snippet.

  2. Run the export with the node export.js command.

You should see the content of an active collaboration session in your console.