A webhook is a mechanism to notify external services like chat clients, project management tools or other external APIs of events or changes that happened in PhraseApp.This feature allows you to register a callback URL that will receive a call whenever a certain event takes place in PhraseApp.

It is currently possible to track events of the following types:

  • locales:create - A new Language Version has been created on a project
  • locales:update - A Language Version has been changed, renamed or reconfigured
  • locales:delete - A Language Version has been deleted
  • uploads:create - A Locale File has been uploaded
  • uploads:processing - A Locale File was processed
  • keys:create - A Key has been created
  • keys:update - A Key has been renamed or changed
  • keys:delete - A Key has been deleted
  • keys:batch_delete - Multiple Keys were deleted
  • translations:create - A Translation of a Key in a certain Language Version has been added
  • translations:update - A Translation of a Key in a certain Language Version has been edited
  • translations:deliver - A Translation of a Key in a certain Language Version has been delivered by a language service provider
  • comments:create - A Comment on a Translation Key has been added
  • jobs:start - A Job was started
  • jobs:complete - A Job was marked as completed
  • jobs:locale:complete - A Locale of a Job was marked as completed

Configure a Webhook

You can configure webhooks in your Translation Center as follows:

  1. Go to the “Integrations” tab
  2. Click the “Configure”-button
  3. Click the “Add Webhook”-button
  4. Choose a project for which you want to add the webhook from the dropdown
  5. Enter a Callback-URL that will be called by PhraseApp every time an event of the selected event types has occurred
  6. Choose one or more events you want to listen for from the dropdown menu
  7. Add a description to remember what the webhook is for
  8. Save the Webhook

Testing a Webhook

You can test your webhooks in order to verify that the endpoint is receiving the event notification. Just click the “Send test notification”-link. This will send an example event notification to the provided callback URL.

An easy way to capture the contents of a webhook is to use a service like RequestBin. It gives you a URL that will collect requests made to it so that you can easily inspect their content.

Receive Webhooks

Once you register a webhook, we will send a POST request to the specified callback URL every time an event of the specified type occurs. The request’s POST payload is a JSON-encoded document with relevant data for the event. The attributes event and message will always be included with additional relevant resources like the user and project.

Response headers

HTTP requests made to your callback URL will contain several special headers:

X-PhraseApp-Event
Ty of event that triggered this hook.

X-PhraseApp-Signature
HMAC hex digest of the payload, using the hook's secret as they key.
 

Content-Type: application/json
X-PhraseApp-Event: translation:create
X-PhraseApp-Signature: abc123

{
  "event": "translations:create",
  "message": "Peter translated page.help.title in fr.",
  "user": {
    "id": "abcd1234cdef1234abcd1234cdef1234",
    "username": "joe.doe",
    "name": "Joe Doe",
    "email": "joe@phraseapp.com",
    "position": "Lead Developer",
    "created_at": "2015-01-28T09:52:53Z",
    "updated_at": "2015-01-28T09:52:53Z"
  },
  "project": {
    "id": "abcd1234cdef1234abcd1234cdef1234",
    "name": "My Android Project",
    "main_format": "xml",
    "project_image_url": "http://assets.phraseapp.com/project.png",
    "account": "account",
    "created_at": "2015-01-28T09:52:53Z",
    "updated_at": "2015-01-28T09:52:53Z"
  },
  "translation": {
    "id": "abcd1234cdef1234abcd1234cdef1234",
    "content": "My translation",
    "unverified": false,
    "excluded": false,
    "plural_suffix": "",
    "key": {
      "id": "abcd1234cdef1234abcd1234cdef1234",
      "name": "home.index.headline",
      "plural": false
    },
    "locale": {
      "id": "abcd1234cdef1234abcd1234cdef1234",
      "name": "de",
      "code": "de-DE"
    },
    "placeholders": [
      "%{count}"
    ],
    "created_at": "2015-01-28T09:52:53Z",
    "updated_at": "2015-01-28T09:52:53Z"
  }
}

Respond to a Webhook

Your webhook endpoint is required to return a HTTP status in the 2xx range within 5 seconds upon receiving a callback. Any other HTTP status code or a request timeout is considered to be a delivery failure. A webhook will be deactivated if delivery fails for more than 10 consecutive events. Callbacks are not repeated.

If you’re receiving a callback, the most important thing to do is respond within the 5 second request-timeout-period. To make sure that apps do not accidentally trigger a timeout, we recommend that apps defer processing to a time after the http response has been sent.

Verify a Webhook

Each webhook request includes a X-PhraseApp-Signature header which is generated using your app’s shared secret, along with the data sent in the request.

You can verify that the request originated from PhraseApp by computing the HMAC digest of the request body and comparing it to the value in the X-PhraseApp-Signature header.

Example Code

 Ruby 

def verify_webhook(signatureheader)
  digest = OpenSSL::Digest::Digest.new('sha256')
  hmac = OpenSSL::HMAC.digest(digest, SHARED_SECRET, request.body)
  hmac = Base64.encode64(hmac).strip
  hmac == signatureheader
end

 PHP  

function verify_webhook($signatureheader){
  $hmac = hash_hmac('sha256', $requestBody, $sharedSecret, true);
  $hmac = trim(base64_encode($hash));
  return $hmac == $signatureheader;
}

Integrate with Slack

Slack is a platform for team communication: everything in one place, instantly searchable, available wherever you go. Slack enables integrations that let you automatically pull information and activity from outside tools into Slack in a way that’s timely, relevant and searchable.

To integrate notifications generated by a PhraseApp webhook into a Slack channel you will need to setup an incoming webhook service integration within Slack to obtain your webhook URL as follows:

  1. Go to ‘Add Incoming Webhook’ in your slack account.
  2. Select the desired channel to post to.
  3. Once created, copy the provided Webhook URL and follow the steps describe above to create a webhook within PhraseApp using the Webhook URL as Callback-URL.

We will send a POST request to the provided URL every time an event of the specified type occurs. The request’s POST payload is a JSON-encoded document with relevant data required by Slack to display a short description of the occurred event in a dedicated channel.

Example Payload

{
  "text": "Andre has updated a translation in project: 'my project'",
  "username": "PhraseApp"
}

Deactivate a webhook

You can deactivate an existing webhook by clicking “Deactivate Webhook” under “More”, without the need of deleting it completely.

Did this answer your question?