JetBrains Space Help

Webhooks

Webhooks let your application receive notifications about events in Space. When an event is triggered, Space will send a POST request to the specified application endpoint. The request contains a JSON payload with event details. In Space, webhooks are an integral part of applications: Each application can have its own set of configured webhooks, and it's not possible to create a webhook separately from an application.

There are two ways to create webhooks for an application:

  • Programmatically through the Space HTTP API or Space SDK – This is the only way to add webhooks for multi-org applications.

  • Manually through the Space user interface (UI) – You can use this way for single-org applications or testing purposes during application development.

This section contains instructions for both ways.

Create a webhook

The following example creates a webhook with a subscription to issue events in a specific project.

import space.jetbrains.api.ExperimentalSpaceSdkApi import space.jetbrains.api.runtime.helpers.ProcessingScope import space.jetbrains.api.runtime.resources.applications import space.jetbrains.api.runtime.types.* @ExperimentalSpaceSdkApi suspend fun ProcessingScope.setupWebhooks() { val spaceClient = clientWithClientCredentials() // Create a webhook for the app val webhook = spaceClient.applications.webhooks.createWebhook( // The application for which the webhook is created application = ApplicationIdentifier.Me, name = "Issue and project events", description = "Track when an issue is created, or a title or a description is updated", // List of HTTP codes treated as successful responses acceptedHttpResponseCodes = listOf(200), // Create subscriptions for specific events. // We recommend creating one subscription per webhook // or several subscriptions for closely related events. subscriptions = listOf(SubscriptionDefinition( name = "Issues created, deleted, or updated", subscription = CustomGenericSubscriptionIn( // The subject of the subscription. // E.g. "Issue", "Project", "Meeting", etc. subjectCode = "Issue", // Event filters. The filters depend on the subject. // E.g. for "Issue", you can subscribe to events in a specific project. filters = listOf(ProjectCommonSubscriptionFilterIn( project = "2PCwjr4gY8Bs" )), // To apply no filters, use emptyList as shown below // filters = emptyList(), eventTypeCodes = listOf( "Issue.Created", "Issue.Deleted", "Issue.TitleUpdated", "Issue.DescriptionUpdated" ) ) )), // Fields to be included in the webhook payload. // By default, only top-level fields are included. payloadFields = { issue{ id() title() description() projectId() archived() } } ) }

In case of a multi-org application, we recommend creating a webhook during application installation, i.e., during processing InitPayload:

Space.processPayload(ktorRequestAdapter, spaceHttpClient, AppInstanceStorage) { payload -> when (payload) { is InitPayload -> { setupWebhooks() // other installation activities // ... } is WebhookRequestPayload -> { // process webhook asynchronously, respond to Space immediately launch { processWebhookEvent(payload) } } } SpaceHttpResponse.RespondWithOk }

The following example creates a webhook with a subscription to issue events in a specific project.

POST https://mycompany.jetbrains.space/api/http/applications/me/webhooks Authorization: Bearer here-goes-the-access-token Accept: application/json Content-Type: application/json { "name": "Issue and project events", "description": "Track when an issue is created, or a title or a description is updated", "acceptedHttpResponseCodes": [], "payloadFields": "issue", "subscriptions": [ { "name": "Issues created, deleted, or updated", "subscription": { "subjectCode": "Issue", "filters": [ { "className": "ProjectCommonSubscriptionFilterIn", "project": "2PCwjr4gY8Bs" } ], "eventTypeCodes": [ "Issue.Created", "Issue.Deleted", "Issue.TitleUpdated", "Issue.DescriptionUpdated" ] } } ] }
  1. In Extensions | Applications, open the required application.

  2. Open the Webhooks tab and click New webhook.

  3. Specify the webhook Name and click Create.

  4. On the Webhooks tab, open the required webhook.

  5. If you want to use the endpoint different from the application's endpoint, click the Edit Edit button next to Endpoint. Then turn off Use application settings and specify new Endpoint URL and other options.

  6. If you want to use a verification method different from the application's verification method, click the EditEdit button next to Authentication. Then turn off Use application settings and specify a new verification method.

  7. Typically, after Space sends a POST request, the application must respond with the 200 OK HTTP status. By default, Space treats all 2xx codes as successful. If you want Space to accept other codes as successful, add these codes to the Status Codes for Successful HTTP responses list.

    In case, Space receives some other code or doesn't receive a response at all, it will try to resend the request up to three times. To disable this behavior, clear Retry on failure in the Endpoint settings.

  8. After you configure the endpoint, you can test the configuration by clicking the Test endpoint button. In this case, Space will send a request with the PingWebhookEvent payload. Note that your application must accept this payload type. Learn more

Create a subscription

After you create a webhook, you must subscribe it to the events you need to track. A webhook can have any number of event subscriptions.

  1. Click the AddAdd button next to Subscriptions.

  2. Specify subscription's Name and other settings:

    • Source: a Space module from which you want to receive notifications, for example, Teams, Issues, Meetings, and so on.

    • Events: an event that triggers sending a POST request to the application. The list of available events depends on the selected Source.

    • Additional filters: you can narrow the subscription scope by specifying additional event filters. The list of available filters depends on the selected Source. For example, this could be Filter by team, Filter by project, Filter by location, and so on.

    Webhook event subscription
  3. After you create the subscription, you can define which event data to send in the payload. To reduce the payload size, Space sends only the minimum required data set. More specifically, it sends only top-level fields.

    For example, a payload of the IssueWebhookEvent class has the issue: Issue field. While the Issue class provides full issue data, by default, Space will send only the issue.id field.

    { "className": "WebhookEvent", ... "payload": { "className": "IssueWebhookEvent", ... "issue": { "id": "30PnZX2QSoWo" }, ... } }

    To check the insides of the payload, go to Payload. To change the payload contents, click the Edit Edit button next to Payload and select the required fields.

Webhooks and application permissions

For a webhook to start working, the application must be granted the corresponding permission. For example, the subscription for the Document created event requires the View documents permission.

After the application owner (the user who installs the application) or the application itself creates a webhook, the permission approval request is sent to the corresponding administrator. Learn more

If the application owner has the requested permissions themselves, Space will grant the permissions automatically without contacting the administrator. However, this works only for global permissions, i.e., approval from the corresponding administrator is still required for the permissions from the project and chat channel scopes.

Send webhook event data as URL parameters

By default, Space sends event data to the webhook endpoint in an HTTP request payload. Also, Space can send the data as endpoint URL parameters. Macros are placeholders that will be substituted with real event values when the event occurs. For example, https://my.endpoint.url/api?id={{member.id}} will transform into a real user ID, like https://my.endpoint.url/api?id=1234.

To use URL macros, you should change the default application endpoint URL to a custom one.

val webhook = spaceClient.applications.webhooks.createWebhook( // specify a custom endpoint with required macros endpoint = EndpointCreateDTO(" https://myapp.example.com/api/space?issue={{issue}}", false), // other webhook settings // ... )
POST https://mycompany.jetbrains.space/api/http/applications/me/webhooks Authorization: Bearer here-goes-the-access-token Accept: application/json Content-Type: application/json { "name": "Issue and project events", "description": "Track when an issue is created, or a title or a description is updated", "endpoint": { "url": " https://myapp.example.com/api/space?issue={{issue}}", "sslVerification": false }, // other webhook settings // ... }
  1. Open the webhook settings.

  2. Open the Endpoint settings by clicking the Edit Edit button.

  3. Clear the Use application settings checkbox.

  4. Specify the endpoint URL with required macros.

    The macros available in the current context correspond to the fields of the event type. For example, if your webhook is subscribed to the Blog post published event, Space will send a payload of the BlogWebhookEvent type. This means that you can use BlogWebhookEvent type fields as URL macros. For instance, to get a title of a blog post: https://my.endpoint.url/api?id={{title}}.

    The Edit Endpoint window shows the list of macros available in the current context.

    URL macros

Process webhook notifications in an application

When an event is triggered, a webhook will send a WebhookRequestPayload to the application's endpoint. To help you process the event payload, Space SDK provides a number of classes. After processing the payload, the application must respond with the 200 OK HTTP status.

Here you can find an example of an application that shows how to process webhook payload.

Payload contents

For example, this payload is sent when a new user is added to the organization:

{ "className": "WebhookRequestPayload", "accessToken": "", "verificationToken": null, "serverUrl": "https://mycompany.jetbrains.space", "clientId": "a1b83dac-6e26-46cb-b3cb-7e264eab5e9e", "orgId": "o0Ghr0EewX8", // id issued to a webhook during registration "webhookId": "3EZUCW3RmsZY", "payload": { // event class name "className": "ProfileOrganizationEvent", // event-specific data "meta": { "principal": { "name": "admin", "details": { "className": "CUserPrincipalDetails", "user": { "id": "2ZJrHC3ouUQz" } } }, "timestamp": { "iso": "2021-06-15T14:51:35.545Z", "timestamp": 1623768695545 }, "method": "Created" }, "member": { "id": "4Zg1mS4aBsOm" }, "joinedOrganization": true, "leftOrganization": false } }

Process event payload

To help you process the event payload, Space SDK provides a number of classes: A separate class for each event type. All these classes implement the WebhookEvent interface. Fields of the event classes let you get particular data from the event payload. You can find the full list of event classes in the API reference.

For example, you can create a webhook for the Member joined organization event. In this case, each time a new user is added to the organization, Space will send an instance of the ProfileOrganizationEvent class to the application. You can use its fields to get data on the added user:

if (event is ProfileOrganizationEvent) { // get id of the created member from event val userId = event.member.id // use id to get username val username = userId.let { val profile = spaceClient.teamDirectory.profiles. getProfile(ProfileIdentifier.Id(userId)) println("ADDED USER: ${profile.username}") } }

If you create a webhook in the Space UI, you can get the detailed information about a particular event class when adding a subscription to the webhook.

Test webhook connection

When adding a webhook, you can test the connection to the application using the Test endpoint button on the Endpoint page.

Test endpoint

This will send the payload of the PingWebhookEvent class. Make sure you handle this event type in your application.

{ "className": "WebhookRequestPayload", "accessToken": "", "verificationToken": null, "serverUrl": "https://mycompany.jetbrains.space", "clientId": "135d429f-4d7e-4aa1-9872-ea5ba0b6736e", "orgId": "o0Ghr0EewX8", "webhookId": "1HArWk184jyL", "payload": { "className": "PingWebhookEvent", "webhookName": "MyFirstWebhook" } }

Customize webhook payload

You can configure a webhook to send a request body in a custom format. This can be useful if you integrate Space with some well-established system that accepts only a specific request format. An example of such integration might be a webhook that sends a message to a Slack channel.

To make a webhook use a custom payload format, you must provide it a format template. You can do this when creating or editing a webhook.

val webhook = spaceClient.applications.webhooks.createWebhook( // use the Slack message format for the request body payloadTemplate = """ { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "{{message.author.name}} said \\"{{message.text}}\\"" } } ] } """.trimIndent(), // other webhook settings // ... )
POST https://mycompany.jetbrains.space/api/http/applications/me/webhooks Authorization: Bearer here-goes-the-access-token Accept: application/json Content-Type: application/json { "name": "Message webhook", "description": "Sends a message to a Slack channel", "payloadTemplate": "{\"blocks\": [{\"type\": \"section\",\"text\": {\"type\": \"mrkdwn\",\"text\": \"{{message.author.name}} said \\\\\"{{message.text}}\\\\\"\"}}]}", // other webhook settings // ... }
  1. Open the webhook settings.

  2. Open the Payload settings by clicking the Edit Edit button.

  3. In the Edit Payload window, switch to String template.

  4. Specify the template for the request body and click Save.

Template format

  • The template is a string that can contain text and variables.

  • Variables represent event data and are replaced with their values when the webhook is triggered.

  • To reference a variable, use the following syntax: {{variableName}}. To reference a variable that is a part of a JSON object, use the dot notation: {{objectName.variableName}}. For example, in case of issue events, {{issue.title}} will be replaced with the issue title.

  • You can use only variables that are available in the standard webhook payload. For example, if you create a webhook in the Space UI, you can view the available fields in the Payload section under the payload node. Learn more

    Template variables
  • If a variable is not available, the webhook returns an empty string in place of the expected variable value.

  • Use backslash \ for escaping: \{, \}, and \\.

  • For example, the following template uses the Slack Block Kit:

    { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "The issue \\"{{issue.title}}\\" was created by {{issue.createdBy.name}}" } } ] }

Example. Send a message to Slack with a webhook

In this example, we will create a webhook that sends a message to a Slack channel when an issue is created in Space.

  1. Create a Slack app and install it to your workspace.

  2. Go to Slack app settings and open the Incoming Webhooks page.

  3. Click Add New Webhook to Workspace and select a channel.

  4. Copy the webhook URL.

    Incoming webhook in Slack
  5. Create an application in Space.

  6. Add a webhook to the application.

  7. As the application's endpoint, specify the Slack webhook URL.

  8. Create a webhook subscription:

    • Source: Issue

    • Events: Created

  9. In Payload, click the Edit Edit button

  10. Switch to String template and specify the following template:

    { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "The issue \\"{{issue.title}}\\" was created by: \\n*{{issue.createdBy.name}}*" } } ] }

Now, when an issue is created in Space, the webhook will send a message to the Slack channel.

Message in Slack

Add custom HTTP headers

Space lets you customize headers of requests that will be sent to the application. Typically, this makes sense in case your application uses a non-standard authentication/authorization flow.

  1. On the Webhooks tab, open the required webhook.

  2. Click the AddAdd button next to Custom Headers.

  3. Specify a Name of the header and provide its Value.

  4. Click Save.

View webhook request history

In case of webhooks created via the Space UI, you can check the history of requests sent to the application.

  1. On the Webhooks tab, open the required webhook.

  2. Open the Recent Deliveries tab.

Last modified: 04 August 2023