Skip to content

Webhook Transforms

You may have noticed that there is one key limitation with the base Custom Data functionality that prevents it from being a fully end-to-end solution for sharing data from external systems with your Apps in Jira.

Custom Data is a great tool for storing data in a way that can be easily consumed by your apps, but it required the data to be sent to App Maker in a specific format/shape - and obviously your internal systems won't be using that format/shape to send data when they fire Webhooks.

As mentioned previously, you could use something like Jira Automation to do this translation for you, but that's a lot of complexity and work we don't want to have to manage.

This is where the final piece of the App Maker puzzle comes in - Webhook Transforms.

Summary

Webhook Transforms are a powerful tool that allows you to simply aim webhooks from your external systems at a URL on your Jira site, and have App Maker automatically translate the data from that webhook into Custom Data.

Overview:

  • Webhook Transforms are managed very similarly to UI Components and Custom Data.
    • They are defined as JSON, and share a very similar structure.
  • Each Webhook Transform defines a series of fieldMaps which allow you to map data from a webhook you receive to the fields required to store it as Custom Data.
  • When you create a Webhook Transform, it will generate a unique URL on your Jira site that you will aim your external system's webhooks at.
  • When a webhook request is received at that URL, App Maker will automatically translate the data from the webhook into Custom Data and store it in your Jira site, ready to be displayed inside your Apps.

Example Workflow:

  • Head back to the App Admin page in your Jira site by clicking the cog icon in the top right corner of the screen and selecting "Apps" from the dropdown, then select "Custom Apps" in the sidebar, and click on the "App Maker" tab.
  • On that page, you will see a URL for "Update Webhook Transform", copy that URL and save it for later.
  • Now, head back to your API client and create a new POST request aimed at the URL you just copied.

Webhook Transform Request:

  • In the body of that request, add the following JSON:
json
{
  "action": "set",
  "resourceType": "site",
  "title": "my-first-webhook-transform",
  "transformData": {
    ...
  }
}
  • You'll notice that most of the top-level fields are very familiar; action, resourceType, and title are all the same as they were for Custom Data and UI Components.
    • The main difference for Webhook Transforms is that they can (currently) only be created at the site level, so the resourceType should always be "site" and the title should be unique to your site.
    • Note that although Webhook Transforms themselves can only be created at the site level, they can be used to create Custom Data at any level in the hierarchy.

Transform Data Object:

  • The transformData object is where you define the actual field mappings for your Webhook Transform.
    • This object should contain a series of fieldMaps that define how to map data from the webhook into Custom Data.
    • Each fieldMap should contain a source and a target field.
      • The source field should be the path to the data you want to use in the webhook payload.
      • The target field should be the path to the Custom Data field you want to store the source data in.
  • In some situations, instead of mapping data from the webhook dynamically, you may simply want to set some fields as static values.
    • You can do this by simply wrapping the value of the source field in single quotes like "source": "'my static string value'".
  • The path you specify in the source field should assume a top-level object with two properties, body & queryParams.
    • The body object will contain the JSON payload of the webhook.
    • The queryParams object will contain any query parameters that were contained in the URL the webhook was sent to.

Mapping Example:

Heads Up:

So that you can make the mapping entirely dynamic, all fields on the Custom Data object are mapped as part of the Webhook Transform.

This means that required fields like action, resourceType, & title must be explicitly mapped in the Webhook Transform.

  • For the sake of the example, assume a webhook payload for a status change event from an app monitoring tool that looks like this, sent to a Webhook Transform URL that includes the query param project=ABC:
json
{
  "event": {
    "status-checks": {
      "website": "Offline",
      "api": "Online"
    }
  }
}
  • When this webhook is received by App Maker, it will combine all the data into an object like below:
json
{
  "body": {
    "event": {
      "status-checks": {
        "website": "Offline",
        "api": "Online"
      }
    }
  },
  "queryParams": {
    "project": "ABC"
  }
}
  • Now, we want to map this data to be used in the System Status widget we created in Advanced Dynamic Content.
  • The first thing you want to do is create the field mappings for all the top-level fields in the Custom Data object.
    • We'll set static values for the action, title, and resourceType fields.
    • And we'll map the project value from the queryParams to the resourceKey field.
json
{
  "action": "set",
  "resourceType": "site",
  "title": "my-first-webhook-transform",
  "transformData": {
    "fieldMaps": [
      {
        "source": "'set'",
        "target": "action"
      },
      {
        "source": "'system-status'",
        "target": "title"
      },
      {
        "source": "'project'",
        "target": "resourceType"
      },
      {
        "source": "queryParams.project",
        "target": "resourceKey"
      }
    ]
  }
}
  • Next up we need to map the actual status data from the webhook payload.
  • The two source values we need (website, and api) are accessed via the:
    • "body.event.status-checks.website" path for the Website.
    • "body.event.status-checks.api" paths for the API.
  • We'll map these to target fields in the Custom Data object using the:
    • "customData.website" path for the Website.
    • "customData.api" path for the API.
json
{
  "action": "set",
  "resourceType": "site",
  "title": "my-first-webhook-transform",
  "transformData": {
    "fieldMaps": [
      // ...previous fields
      {
        "source": "body.event.status-checks.website",
        "target": "customData.website"
      },
      {
        "source": "body.event.status-checks.api",
        "target": "customData.api"
      }
    ]
  }
}

Note:

App Maker will automatically generate the required structure in your Custom Data object based on the target paths you specify in your Webhook Transform.

  • For example, the target of "customData.website" will automatically create the customData object if it doesn't already exist, and nest the website field/value inside of it.

Complete Transform:

  • Your final Webhook Transform JSON should look like this:
json
{
  "action": "set",
  "resourceType": "site",
  "title": "my-first-webhook-transform",
  "transformData": {
    "fieldMaps": [
      {
        "source": "'set'",
        "target": "action"
      },
      {
        "source": "'system-status'",
        "target": "title"
      },
      {
        "source": "'project'",
        "target": "resourceType"
      },
      {
        "source": "queryParams.project",
        "target": "resourceKey"
      },
      {
        "source": "body.event.status-checks.website",
        "target": "customData.website"
      },
      {
        "source": "body.event.status-checks.api",
        "target": "customData.api"
      }
    ]
  }
}
  • Hit "Send" and the Webhook Transform will be created in App Maker.
  • In the response from the API call, you will see a property called "transformUrl", which is the URL you will point your external system's webhooks at.

Webhook Transform Response

Testing the Transform:

Updating the System Status widget.

  • Before you can test your Webhook Transform, we need to make one small change to the System Status widget we created in the advanced dynamic content guide.
    • In that widget, we read the system status values from Custom Data stored at the site level, but this Webhook Transform has been setup to store its Custom Data at the project level.
  • Open back up your API client and make a POST request to the UI Update URL (not the Webhook Transform URL) with the following JSON body:
json
{
  "resourceType": "site",
  "module": "jira:issueContext",
  "title": "system-status-widget",
  "action": "set",
  "componentData": {
    "type": "StackedInformationGroup",
    "title": "System Status",
    "children": [
      {
        "type": "FieldValue",
        "key": "Website",
        "value": "{{customData.project.system-status.website}}"
      },
      {
        "type": "FieldValue",
        "key": "API",
        "value": "{{customData.project.system-status.api}}"
      }
    ]
  }
}
  • All we changed was the template paths in the two field values, swapping from:
    • customData.site.system-status.website to customData.project.system-status.website
    • customData.site.system-status.api to customData.project.system-status.api
  • This means the System Status widget will read the Custom Data stored at the project level, instead of the site level.

Executing the Webhook Transform:

  • Now that you have the Webhook Transform created, you can test it by sending a POST request to the transformUrl with the payload you used in the example above.
json
{
  "event": {
    "status-checks": {
      "website": "Offline",
      "api": "Online"
    }
  }
}

Note:

  • Because this Webhook Transform is scoping the data it creates to a specific project, you will need to get the key of the project you are using for testing in Jira, and include it in the request you make to the transform URL.
  • Include project={your project key here} in the URL as a query parameter by adding &project={your project key here} to the end of the transformUrl.

Webhook Transform Executed

  • You will see in the response from the Webhook Transform, the Custom Data object that was created by transforming the webhook payload.
  • Now navigate back to your Jira project and take a look at the System Status widget, you should now see the values updated to reflect the most recent request.

Updated System Status Widget

Recap

Congratulations! You've successfully created a Webhook Transform in App Maker that can receive webhooks from an external system, translate the data from those webhooks into Custom Data, and store it in your Jira site.

You've learned how to scope Custom Data to particular Jira projects, meaning you can now store data from multiple external systems in the same Jira site without it getting mixed up.

You've also updated your System Status widget to consume that Custom Data and display it in your Jira project.

From here, we hope you can see how the Custom Data system, combined with Webhook Transforms, allows you to build powerful, dynamic, and data-driven Apps in Jira that can be used to monitor and manage your systems in a way that suits your team's needs.

If you have any questions or need help with anything, please don't hesitate to reach out to us for support.