---
title: "Automation via Outcoming WebHooks"
canonical: "https://help.releasemanagement.app/space/RM4J/331710465/Automation%20via%20Outcoming%20WebHooks"
format: markdown
---
> Macro (include)

# Renaming “Releases“ to “Packages“

> ℹ️ As of **June, 2024 **we re renaming **“Releases“** to **“Packages“** to be aligned with our Cloud products and avoid long running confusion with “Releases“ in Jira. Some areas of our App will still have release notion/naming due to technical limitations, namely:
> ℹ️ 
> ℹ️ - **API roots** will still be called */ release / *while tags and descriptions in [Swagger](https://releasemanagement.atlassian.net/wiki/spaces/RM4J/pages/1081347) changed to packages
> ℹ️ - **Webhook** [injectable variables](https://releasemanagement.atlassian.net/wiki/spaces/RM4J/pages/331710465/Automation+via+Outcoming+WebHooks#Injectable-variables-in-URL) will be called *entity.**
> ℹ️ - **Release notes **[injectable variables](https://releasemanagement.atlassian.net/wiki/spaces/RM4J/pages/1081356/Flexible+Release+Notes#Releasevariables) will be called *release.**
> ℹ️ - **JQL functions **will still be called *[versionsOfReleases..](https://releasemanagement.atlassian.net/wiki/spaces/RM4J/pages/1703945/Custom+JQL+functions#%E2%80%9CfixVersion-in-..%E2%80%9C-JQL-functions)** & **[issuesOfReleases..](https://releasemanagement.atlassian.net/wiki/spaces/RM4J/pages/1703945/Custom+JQL+functions#%E2%80%9Cissue-in-..%E2%80%9C-JQL-functions-(ver.-4.1.0%2B))*

# Topics

> Macro (toc)

# Overview

Webhooks are aimed to integrate the Release Management app with other software in your organization to create a single and integrated workspace. Typical use cases are the following:

- Sending notifications. (for instance to Slack, Teams ad etc.)
- Trigger actions in your CI/CD server (for instance trigger build or deployment ). As a result, there is no need to educate all members of your team on how  to use CI/CD tools and create separate accounts for them. It could be orchestrated from Release Management App.
- Execute some actions on the same Jira instance (for instance, create a separate Jira issue for integration testing, compliance approval etc). This will open a lot of opportunities on the release workflow automation.

Webhooks configuration is located on the board administration tab.

![image](media://0e15a3b6-9b86-4240-8763-31e8e04d062e)

# Create a Hook

In order to create new webhook: 

Click “Add webhook“ button.

Webhook creation dialog has two tabs.

- Summary.
- Headers.

## Hook definition

Summary tab contains the main properties

![image](media://7ca2e859-fb3f-4298-aee8-f7a1e40e660e)

**Name**. The webhook name to be displayed in the table.

**Columns**. At the moment, the hooks could be triggered only when a package and/or version is moved to a particular column. You are able to choose <u>All </u>or <u>multiple</u> columns from package or version workflows.

> ℹ️ In the following version of the Release management app we will add other types of webhook triggers. Such as:
> ℹ️ 
> ℹ️ - Start or release date change for package and version
> ℹ️ - Summary changed for package or version
> ℹ️ - Comment added or edited
> ℹ️ - Package and version is archived or unarchived
> ℹ️ - Package or version is deleted
> ℹ️ - A version was deployed on the environment or removed from the environment
> ℹ️ 
> ℹ️ Please contact us in case you need to speed up the development of the above mentioned features.

### Active or Suspended status

You can put Webhook in Active or Suspended status. The later is good fit while you are creating a new one and/or troubleshooting.

### Conditions

Hook executes upon move into specific column. You can define additional conditions to check before executing the hook. If one or all conditions (depending on configuration) fails execution will be interrupted.

![image](media://8c0c7fe2-3b04-4f6e-a515-3642cdd4daba)

Thus you can specify conditions by:

- **Projects**. You can shortlist projects for your Package and Versions.
- **Entities**. You can configure it for Packages, Fix Versions, Epic or JQL Version only or a subset of it.
- **Properties**. You can define specific conditions for your custom properties defined.

### Injectable variables in URL 

You are able to inject the following variables to the hook URL

#### Package or version

- Package or version id
- Package or version name
- Destination column id. Internal id of the column where package or version has been moved. List of columns with their ids you can receive via REST API.
- Destination column name.
- Start date. Package or version start date.
- Release Date.
- Link to package or version. The direct URL to package or version which has triggered the webhook. Such a variable is very convenient for any kink of notifications so the people can navigate to package or version to see the details.
- User name. Full name of a user who has triggered the webhook.

#### Custom Properties for versions/packages

[https://releasemanagement.atlassian.net/wiki/spaces/RM4J/pages/2459172921](https://releasemanagement.atlassian.net/wiki/spaces/RM4J/pages/2459172921)

#### Version only variables

<u>They will not be replaced to any value if they will be used on the package context</u>

- Project name. Name of a parent version project
- Project Key. Key of a parent version project
- Project id. Id of a parent version project

#### *TIME functions (or date-time offsets)*

You can also insert the following time functions. The App will insert an appropriate Macro that is also editable. Datetime formatting functions are the same as listed in following section.

| **Name** | **Macro inserted** | **Other examples** |
| --- | --- | --- |
| Date Offset | {{date.**now**(<span style="color: #bf2600">**0**</span>,'dd/MM/yyyy', 'GTM+1')}} - today | - {{date.now(<span style="color: #bf2600">**1**</span>)}} - tomorrow
- {{date.now(-<span style="color: #bf2600">**1**</span>)}} - yesterday
- {{date.now(-<span style="color: #bf2600">**7**</span>)}} - 7 days ago |
| Start of Week | {{date.**startOfWeek**(<span style="color: #bf2600">**0**</span>,'dd/MM/yyyy', 'GTM+1')}} - start of the week | - {{date.startOfWeek(<span style="color: #bf2600">**-1**</span>,'dd/MM/yyyy', 'GTM+1')}} - start of the previous week
- {{date.startOfWeek(<span style="color: #bf2600">**1**</span>,'dd/MM/yyyy', 'GTM+1')}} - start of the next week |
| End of Week | {{date.**endOfWeek**(<span style="color: #bf2600">**0**</span>,'dd/MM/yyyy', 'GTM+1')}} - end of the week | - {{date.endOfWeek(<span style="color: #bf2600">**-1**</span>,'dd/MM/yyyy', 'GTM+1')}} - end of the previous week
- {{date.endOfWeek(<span style="color: #bf2600">**1**</span>,'dd/MM/yyyy', 'GTM+1')}} - end of the next week |
| Start of Month | {{date.**startOfMonth**(<span style="color: #bf2600">**0**</span>,'dd/MM/yyyy', 'GTM+1')}} - start of this month | - {{date.startOfMonth(<span style="color: #bf2600">**1**</span>,'dd/MM/yyyy', 'GTM+1')}} - start of the next month |
| End of Month | {{date.**endOfMonth**(<span style="color: #bf2600">**0**</span>,'dd/MM/yyyy', 'GTM+1')}} - end of month | - {{date.endOfMonth(-<span style="color: #bf2600">**1**</span>,'dd/MM/yyyy', 'GTM+1')}} - end of the previous month |
| Start of Year | {{date.**startOfYear**(<span style="color: #bf2600">**0**</span>,'dd/MM/yyyy', 'GTM+1')}} - start of the year | - {date.startOfYear(<span style="color: #bf2600">**1**</span>,'dd/MM/yyyy', 'GTM+1')}} - start of the next year |
| End of Year | {{date.**endOfYear**(<span style="color: #bf2600">**0**</span>,'dd/MM/yyyy', 'GTM+1')}} - end of the year | - {date.endOfYear(<span style="color: #bf2600">**-1**</span>,'dd/MM/yyyy', 'GTM+1')}} - end of the previous year |

> 📝 If you need a different formatting rather than 'dd/MM/yyyy', 'GTM+1' please use the following documentation for format notion - [https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)

#### “Helpers”

##### JS-like functions for injectable variables

To finetune your web hooks even further you can use JS-like function for injectable variables in **URL **and **Body **sections of the hook. Below is a list of functions that could be used:

*[concat()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat)** - concatenates the string arguments to the calling string and returns a new string*

```
{{entity.name.concat('-version')}}
```

*equals() - returns boolean true/false if a calling string matches (exactly) the argument*

```
{{entity.name.equals('version')}}
```

*isEmpty (not exist) - returns boolean true/false if a calling string is empty*

```
{{entity.name.isEmpty()}}
```

*[split (string regex)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split)** - divides a calling string into an ordered list of substrings by searching for the pattern, puts these substrings into an array, and returns the array. So, you can use .split(pattern)[index] to pickup the right element of the array. If used only .split(pattern) it will return a string of comma separated substrings.*

```
{{entity.name.split(',')[0]}}
{{entity.name.split('_')}}
```

*[slice (int beginIndex, int endIndex)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice)** - extracts a section of a string and returns it as a new string, without modifying the calling string*

```
{{entity.name.slice(1,5)}}
```

*[toLowerCase()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase)** - returns the calling string value converted to lower case*

```
{{entity.name.toLowerCase()}}
```

*[toUpperCase()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase)** - returns the calling string value converted to UPPER case*

```
{{entity.name.toUpperCase()}}
```

*[trim()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim)** - removes whitespace from both ends of a string and returns a new string, without modifying the original string*

```
{{entity.name.trim()}}
```

*[replaceAll (string regex, string replacement)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll)** - returns a new string with all matches of regex a replaced by a replacement*

```
{{entity.name.replaceAll(/\d/,'_')}}
```

> 📝 `entity.name` above variable is used for example only. Functions are applicable to any string variable from the list.

##### Datetime formatting

> ℹ️ *Coming soon*

> ⚠️ For the datetime fields we use machine readable format what could be recognized and processed by other systems/Apps.
> ⚠️ 
> ⚠️ e.g. 2023-04-22T11:00+0000
> ⚠️ 
> ⚠️ If you want to outline date/time in some Slack/Teams/Email messages you need to format it to something human readable.

Therefore, we support `.formatDate(param1, param2)` function where

- param1 is your date/time
- param2 is optional and represent the desirable timezone, otherwise GMT will be used

Examples:

`.formatDate('MMM dd, yyyy HH:mm:ss','GMT+3')`

`.formatDate('yyyy/MM:dd HH:mm','GMT+4:30')`

`.formatDate('yyyy/MM:dd')`

Here’s a link to supported formats [https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) .

### HTTP calls

**Method**. HTTP method which will be used for the webhook. Available options are:

- Get
- Post
- Put
- Delete

**URL**. The URL which will be called from the Jira server while the webhook execution.

**Injectable variables in Body.** The variables which could be injected into the body while the webhook execution. The variable list is the same as for URL.

**Request body.** The request body which will be used while the webhook execution. For instance. it could contact XML or JSON.

## Additional headers

On the headers tab, you can define headers for the webhook HTTP request.

The headers could be added in Key-Value format. Multiple headers are supported.

![image](media://d183b365-b024-4d42-bdf7-42d3a230b9e3)

# Webhook execution and history

The webhook will be executed if the trigger condition will be fulfilled. In the current version, the condition is a move of package or version to a particular column. 

Release management app, will execute outbound HTTP request with the defined parameters and store execution results in the history table.

The history table is available under the hooks list table. In the table, you can see all the webhooks executions for the past 5 days. Older history items will be automatically deleted.

For each history items, the details could be reviewed: - full HTTP request with headers and full HTTP response. This will help to spot and solve any potential problems.

![image](media://0c5bd50d-ed58-4bac-a3aa-a525629b4a3d)

# Use cases 

## Slack Integration

Webhooks could be used for pushing notifications to Slack. Let’s configure the notification for a case when a version is moved to Done status.

**Step 1. **Navigate to [https://api.slack.com/apps?new_app=1](https://api.slack.com/apps?new_app=1) to create an app “From scratch“

![image](media://bc3cf67b-04d3-4850-b4e6-74795af778d8)

**Step 2. **Choose the name of the App (integration) and a space to send notifications

![image](media://377b997f-2e82-4a67-96f9-6bbb59b77b21)

**Step 3. **Enable “Incoming Webhooks”

**Step 4. **Activate it and add new Webhook

![image](media://7353fb53-3f93-4a15-8501-93034a49ddad)

**Step 5. **Allow integration and choose the destination channel from the selected space

![image](media://57fa680c-8b96-4636-9b11-95447a5ce34b)

**Step 6. **Copy URL for the Hook

![image](media://8020024b-dd3f-4df8-9806-ff870bdf9e46)

**Step 7. **Open webhooks configuration in Release management and clone webhook template:

![image](media://0977655c-704f-43de-93cb-ce2084f39c47)

![image](media://bff126c4-8dbf-437e-a0f3-d5f8ce0dbe93)

Choose Done column from a version in Columns field and **paste received URL on step 6 to URL filed.** Save the webhook.

![image](media://58f997e4-9bfb-4f28-8cc5-4b1bd54b7cd2)

**Step 5. **Move any version to Done column and observe a notification in the slack channel.

![image](media://bebfef3e-9c1d-4d24-9ff4-ce3f67f91a1a)

## MS Teams integration

**Step 1.** Go to the channel where you want to add the webhook and select ••• **More options** from the top navigation bar.

**Step 2. **Select **Connectors** from the dropdown menu:

![image](media://74179c9a-663d-4c85-9b3e-bd7199bb9ec7)

**Step 3. **Search for **Incoming Webhook** and select **Add**.

**Step 4.** Select **Configure**, provide a name, and upload an image for your webhook if required:

![image](media://1549fcf2-64e9-4925-b8e5-480487ac50db)

**Step 5.** The dialog window presents a unique URL that maps to the channel. Copy and save the webhook URL, to send information to Microsoft Teams and select **Done**:

![image](media://0e61132f-6f15-4ca6-8f7e-dea6ff9fcc11)

**Step 6. **Open webhooks configuration in Release management and clone **[Template] Sample MS Teams Notification**:

![image](media://50511060-b980-48c4-a45b-e183bc608df3)

![image](media://b7062fd3-6492-4f5e-872e-c205ca365c4e)

Choose Done column from a version in Columns field and paste received URL on **step 5** to URL filed. Save the webhook.

![image](media://1d53f79e-e676-4274-8309-bb0dfdbd4b77)

**Step 7. **Move any version to Done column and observe a notification in the MS Teams channel.

![image](media://5b2a73f5-0b01-4e6b-a95f-c1f84633ac02)


The webhook is available in the Teams channel.

Use the following code to create Adaptive Card JSON file:

```
{
   "type":"message",
   "attachments":[
      {
         "contentType":"application/vnd.microsoft.card.adaptive",
         "contentUrl":null,
         "content":{
            "$schema":"http://adaptivecards.io/schemas/adaptive-card.json",
            "type":"AdaptiveCard",
            "version":"1.2",
            "body":[
                {
                "type": "TextBlock",
                "text": "For Samples and Templates, see [https://adaptivecards.io/samples](https://adaptivecards.io/samples)"
                }
            ]
         }
      }
   ]
}
```

The properties for Adaptive Card JSON file are as follows:

- The `"type"` field must be `"message"`.
- The `"attachments"` array contains a set of card objects.
- The `"contentType"` field must be set to Adaptive Card type.
- The `"content"` object is the card formatted in JSON.

## Create Jira Issue

Let’s create a webhook which can help us to create a Jira ticket when a version is moved to UAT status on the board.

> ⚠️ The below guide is not super straighforward and requires some advanced skills. We are conssidering options to make it more user friiendly in future versions. For now it just solves the problem & provide and option to create Jira issues

**Step 1. **Create Atlassian API token.

- Navigate to [https://id.atlassian.com/manage-profile/security/api-tokens](https://id.atlassian.com/manage-profile/security/api-tokens)
- Fill token name (anything you like).
- Store generated token somewhere as it will not be accessible in the future

![image](media://0232764c-e613-4254-9855-79ef0d0f8f45)

![image](media://cacaa3c9-381b-4917-9fac-c2eaa94daa07)

**Step 2. **Retrieve required parameters for issue creation, in particular

- ProjectID  where you want to create issue
- and IssueTypeID of the issue type that you want to create

*Click “Create“ to open Create issue dialog in Jira. Select Project and Issue Type you would like to create.*

![image](media://c220c1c9-9a0e-4092-97a1-fe582a209db2)

*Open the Development Panel in your browse, select Network Tab and click Fetch/XHR button*

![image](media://2c9d6dea-61ce-4621-94df-aed263c4aff3)

*Create an issue and check “issue“ call*

![image](media://246b9726-51dc-42f6-a52c-1d0a3c0c1150)

*Open Payload and copy ProjectID and IssueTypeID*

![image](media://87560744-0a09-4787-8024-3e493bb724a8)

**Step 3.** Generate an authorization token (BASE64 token).

Open any site for generating basic authentication base64 string (for instance this one: [https://mixedanalytics.com/knowledge-base/api-connector-encode-credentials-to-base-64/](https://mixedanalytics.com/knowledge-base/api-connector-encode-credentials-to-base-64/))

*Enter your username and token from Step 1.*

![image](media://2eeb5ddc-1289-481e-b88a-df66324c3b28)

*Copy Base 62 authentication spring*

> ⚠️ For a security reason, we strongly recommend creating a special (different) account for webhooks with just enough permissions to execute required operations. Please don’t use your personal account, especially if it has administrator permissions. Please keep in mind that the token is encoded your login and password in Base64 and it could be decoded back by anybody else. :warning: This method will not protect your credentials
> ⚠️ 
> ⚠️ You are able to use more secure methods of authentication in the hooks.
> ⚠️ 
> ⚠️ Read more about other authorization methods: [https://developer.atlassian.com/cloud/jira/platform/security-for-other-integrations/](https://developer.atlassian.com/cloud/jira/platform/security-for-other-integrations/)

**Step 4. **Create a new WebHook in Release Management App. 

Configure the following parameters.

*Summary section*

- **Method: **POST
- **URL: **`https://JIRA_INSTANCE_NAME.atlassian.net/rest/api/2/issue`
- **Body: **`{"fields":{"summary":"ISSUE_SUMMARY","issuetype":{"id":"YOUR_ISSUE_TYPE_ID_FROM_PREVIOUS_STEP"},"project":{"id":"YOUR_PROJECT_ID_FROM_PREVIOUS_STEP"}}}`

*Headers section*

- Add **Authorization **header
  - Key: Authorization
  - Value: *BASE64_TOKEN_FROM_PREVIOUS_STEP*
- Add **Content-Type **header
  - Key: Content-Type
  - Value: application/json

## Jenkins Integration

By using this guide, you can trigger builds in Jenkins remotely as a result of version and/or package appearance in a specific status.

**Step 1.** Make sure that your Jenkins server is accessible from Jira

**Step 2.** Create a new user in Jenkins

- Select Manage Jenkins > Manage Users
- Click on Create User
- Fill in the information for your user (I’ll assume you’ve called this user “auto”)
- Click the Sign Up button

**Step 3.** Turn job trigger URL on

- Click Configure to edit the job. Under Build Triggers, check the box next to “Trigger Builds Remotely”. You’ll be asked to provide a secure token for validation. This should not in any way be related to the user which was created on Step 2, so don’t reuse the password. You might want to generate a new key using a tool like the Random Key Generator. Click Save to save the job information.

**Step 4.** Configure permissions for the created user

- Select Manage Jenkins > Configure Global Security
- ·Assuming you’re using matrix-based security: add user from Step 2 to the list and check off the boxes:
  - Overall - Read
  - Job - Build
  - Job - Read
  - Job - Workspace
- Click Save

**Step 5.** Create the URL

- From the user list, find a user from step 2, click on the “configure” icon (the wrench and screwdriver) next to the user name
- Underneath the user’s full name and description is a section labelled “API Token”. Click on the “Show API Token” button. This will reveal the API token you need to provide when triggering a job by URL
- With this information, you can now create a URL that looks like this:  
*http://user_name:your_tocken@your_jenkins.com/job/your_job_name/build?token=your_auth_tocken_from_step_3*

## More use cases

Please share your cases with us so we can share them here and help others.

> Macro (include)