Guides

Webhooks and Callbacks

Webhooks enable you to be notified when certain events occur in Smartling. For example, you can configure a webhook to notify you when the translations are ready for download. The notification is via by Smartling via an HTTP request, known as a “callback”, sent to the URL you specify in the webhook configuration.

This sequence is illustrated below:

webhooks.png

 

Callbacks can be used to trigger automated actions in your integration, such as the download of completed translations.

Handling callbacks

To avail of callbacks you must make an internet-accessible web server available to receive and handle them. When your callback-handling server receives a valid callback request, it should respond with an HTTP status code in the 2xx range to indicate that the callback was successfully received. The Smartling callback service will resend the callback up to 10 times if such a response is not received.

Below are some additional recommendations on handling callbacks:

  • Consider restricting access to your callback-handling server to the IP address of the Smartling callback service (184.73.255.141).
  • Keep the callback handler small in order to respond quickly to the callback request. In other words, avoid putting business logic inside the request handler.
  • Use HTTPS for improved security.
  • Consider using signed requests (see below) for authenticating callback requests.
  • Don’t rely on callbacks as the only mechanism to know the status of your translations. Instead supplement them with appropriate status polling.

Testing callback

A number of websites, such as https://requestbin.com and https://webhook.site, provide free URLs that can be used to test callbacks. Simply create a URL on one of these sites, then configure your webhook to use it. These sites allow you to see the details of the request sent to them by the callback service.

In addition, the Ngrok service (https://ngrok.com/) allows you to tunnel callback requests to a non-publicly accessible server, enabling you to test your callback-handling code before making it public.

Callback request structure

Depending on the type of webhook, either GET or POST callback requests may be sent. Below is an example of a GET callback request URL:

https://webhook.site/1e2d7a5d-94d5-4919-847e-b7bea01693bd?locale=fr-FR&publishStatus=published&fileUri=strings-1-5.txt&ts=1620744030201

Note that the Smartling project ID is not included in this URL. If you need additional information such as the project ID, you can include it as part of the callback URL when configuring the webhook.

Below is an example of a POST callback request body:

{
  "projectId": "7d964bd0d",
  "hashcode": "7467e4ace11b903446003bb5a7c10e4a",
  "localeId": "fr-FR",
  "type": "string.localeCompleted",
  "publishStatus": "published",
  "translations": [
    {
      "translation": "Un exemple",
      "pluralForm": null,
      "modifiedDate": "2021-05-11T15:20:06Z"
    }
  ],
  "ts": "1620746412599"
}

You can use the testing websites mentioned above to examine the details of different types of callback requests.

Signed callback requests

Signed callbacks provide greater assurance that incoming callback requests were sent by Smartling and were not tampered with. The process relies on a shared secret held by both the Smartling callback service and your callback handler: Smartling uses the shared secret to generate a signature of the request and includes the signature in a request header; when your callback handler receives the request, it follows the same process using its copy of the shared secret to validate that the result is the same. The process is described in more detail below.

Signing Procedure

Below is the signing procedure for GET requests:

  1. Generate a timestamp (in milliseconds since January 1st, 1970 at UTC), and add it as an additional parameter ts in the request URL
  2. Generate an HMAC-SHA1 signature of the full request URL using the shared secret
  3. Base64-encode the resulting signature and add it to a request header named X-Smartling-Signature.

Below is the signing procedure for POST requests:

  1. Generate a timestamp (in milliseconds since January 1st, 1970 at UTC), and add it as an additional node ts in the request body JSON
  2. ‘Flatten’ the JSON structure. For example, for strings-api POST callbacks, this involves moving the contents of the translations node to the top level, changing the key names into the form translations[0].key. See example below.
  3. Sort the JSON content alphabetically by key
  4. Generate a string from the JSON structure in the form key1=val1|key2=val2|key3=val3
  5. Generate an HMAC-SHA1 signature for this string using the shared secret
  6. Base64-encode the resulting signature and add it to a request header named X-Smartling-Signature.

As an example of steps 2, 3, and 4 in the above process, the following POST body:

{
  "projectId": "7d964bd0d",
  "hashcode": "7467e4ace11b903446003bb5a7c10e4a",
  "localeId": "fr-FR",
  "type": "string.localeCompleted",
  "publishStatus": "published",
  "translations": [
    {
      "translation": "Un exemple",
      "pluralForm": null,
      "modifiedDate": "2021-05-11T15:20:06Z"
    }
  ],
  "ts": "1620746412599"
}

is normalized into this string:

hashcode=7467e4ace11b903446003bb5a7c10e4a|localeId=fr-FR|projectId=7d964bd0d|publishStatus=published|translations[0].modifiedDate=2021-05-11T15:20:06Z|translations[0].pluralForm=null|translations[0].translation=Un exemple|ts=1620746412599|type=string.localeCompleted

which is then signed using the shared secret.

Note that the webhook testing websites mentioned above sometimes display request parameters in a different order than they were received. This can result in the wrong signature being generated when testing.

Enabling signed requests

Contact your Smartling CSM to enable signed callbacks for your account. You will need to provide a shared secret in the form of a random string of ASCII characters (ideally with length > 12).

Configuring webhooks

Webhooks are configured via API call. For example, when you upload a file for translation, you can pass the URL to be used for the callback sent when the file is translated. The available webhooks, along with the methods of configuration, are listed below:

Files

Callback event Description Where configured
File published

Invoked when all the content in a file reaches the Published workflow step in a locale. Separate callbacks are sent for each locale.

Method: GET

The callbackUrl parameter of the Upload file endpoint, the Add file to batch endpoint, or the Upload file to a batch endpoint.
File prepublished

Invoked when all the content in a file reaches the Published workflow step, or is prepublished, in a particular locale. Separate callbacks are sent per locale. For details on prepublishing, see Prepublish Translations. This callback is not available by default—it must be enabled by your CSM.

Method: GET

Uses the same configuration as the File published event above.

Jobs

Callback event Description Where configured
Job completed

Invoked when all the content in a job, for all locales, reaches the Published step of the workflow.

Method: GET or POST

The callbackUrl and callbackMethod parameters of the Create job endpoint.
Job cancelled

Invoked when a job is cancelled.

Method: GET or POST

Uses the same configuration as the Job completed event above.

Strings

Callback event Description Where configured
String published

Invoked when a string translation reaches the Published workflow step in a locale. Separate callbacks are sent per locale.

Method: GET or POST

The callbackUrl and callbackMethod parameters of each string being added via the Add strings endpoint.
String prepublished

Invoked when a string translation reaches the Published workflow step, or is prepublished, in a locale. Separate callbacks are sent per locale. For details on prepublishing, see Prepublish Translations. This callback is not available by default—it must be enabled by your CSM.

Method: GET or POST

Uses the same configuration as String published above.

Issues

Callback event Description Where configured
Various issue-related events.

Invoked when certain issue-related events occur. Details of the supported events, and the structure of the callback requests can be found at Receive issue webhooks For more information on issues, see Using issues.

Method: POST

Issue webhooks can be enabled via Set up issue webhooks and disabled via Delete issue webhook settings

Sample callbacks

Below are some examples of callback request GET query strings and POST bodies. You can use the webhook testing websites mentioned above to see the exact requests sent for your integration.

File published (GET)

?locale=ru-RU&publishStatus=published&fileUri=example.properties&ts=1542138000086

File prepublished (GET)

?locale=ru-RU&publishStatus=prepublished&fileUri=example.properties&ts=1542138300048

Job completed (GET)

https://callback.handler.com?type=job.completed&translationJobUid=xm5rj2kmxtaj

Job cancelled (GET)

?type=job.cancelled&translationJobUid=vacryeniyvlk

String published (POST)

{
    "projectId": "cef4c4151",
    "hashcode": "493c3a41b5e4648e26f6bbfb94d12341",
    "localeId": "fr-FR",
    "type": "string.localeCompleted",
    "publishStatus":"published",
    "translations": [
        {
            "translation": "bonjour",
            "pluralForm": null,
            "modifiedDate": "2021-03-19T17:32:54Z"
        }
    ]
}

String prepublished (POST)

{
    "projectId": "cef4c4151",
    "hashcode": "493c3a41b5e4648e26f6bbfb94d12341",
    "localeId": "fr-FR",
    "type": "string.localeCompleted",
    "publishStatus": "prepublished",
    "translations": [
        {
            "translation": "bonjour",
            "pluralForm": null,
            "modifiedDate": "2021-03-19T17:32:54Z"
        }
    ]
}

 

 

Was this article helpful?