Mention someone directly in Slack via Jira Automation

Automation can do some great things, including sending messages to Slack. But what if you want to get someone’s attention in Slack? This used to be quite simple. However, when GDPR came along, both Slack and Jira Cloud removed usernames & user keys which made customer data safer than ever BUT individual Slack pings impossible… until now!

I should start off with the caveat that this unfortunately isn’t as simple as clicking a button. However, using the steps below, you’ll be able dynamically @mention in a message or even dynamically send a direct message to a relevant user.

image.png

Why is this helpful?

Consider rules where you might want to:

  • Send a ping to John when his issue is about to breach SLA

  • Send an individual Slack message to the boss when a high priority issue is raised

  • Send a congratulations message to a teammate on their work anniversary (article on this in the future!)

  • Notify the project owner when a new issue is added to the sprint

  • Alert senior Help Desk staff when the CEO raises an issue

What you need is to dynamically mention someone in Slack based on user properties in Jira. In this article, we’ll make sure Automation has access to the data it needs to @mention someone in Slack on the fly.

We’re going to break this down into a few short sections:

  1. Configuring Slack to allow API access

  2. Configuring Jira to allow API access

  3. Running a sync script

  4. Calling the @mention in Automation

 

Slack setup

Our sync script will require a Slack token with users:read permission to get user properties. You can get one by creating a new app in your workspace:

  1. Visit the Your Apps page in Slack’s administration and click “Create New App

  2. Name your app (“Jira Automation Sync” might be a good name) and select the workspace you’d like to sync with Jira

  3. Click the Permissions tab to go to the OAuth & Permissions page in the app settings

  4. In the Scopes section, scroll down to User Token Scopes and click “Add an OAuth Scope”

  5. Type/select users:read.email in the searcher box. A message should appear telling you it will also add users:read - click “Add Scopes” on this prompt.

  6. At the top of this page, click “Install App to Workspace”.

  7. Copy down the OAuth Access Token that’s now present (or leave this tab open). We’ll make use of this later!

Jira setup

  1. Ensure that you / the account you’re using has Jira Administrator permissions on the site you’re configuring.

  2. Visit the API Tokens section in your Atlassian Account to generate a new API token.
    Note: This is an API token tied to your Atlassian user account. Treat this like a password; do not store this API token in code repositories, document it in Confluence, or share it in Slack.

  3. Click the “Create API Token” button to create the token, using a descriptive name. Copy the token and store it locally (at the very least, don’t close this window yet) as the token will only be presented once.

Sync Script setup

  1. Download the sync script (sync.py) from Bitbucket

  2. Use pip to install the requisite slackclient library:

    pip3 install slackclient

     

  3. Prepare to call the script:

    python3 sync.py --slack_token $SLACK_TOKEN --jira_url $JIRA_URL --username $USERNAME --apikey $APIKEY


    A guide for the values:

    $SLACK_TOKEN = the OAuth Access token from the Slack setup section. Starts with “xoxp-”
    $JIRA_URL = the URL of the Jira instance you’re connecting to, e.g. “https://something.atlassian.net”   
    $USERNAME = the email address of the account you used to generate the Atlassian API token
    $APIKEY = the Atlassian API key from the Jira setup section

  4. Run the script. This should take some time to complete, scaling with the amount of users you have in Slack/Jira

image.png

Using the mentions

Once the script completes its work, every user in Jira that had a matching account in that Slack workspace (based on their email address) will now have two additional properties on their user in Jira:

  • metadata.slack_id (the raw UID Slack uses for mentions / DMs done via API - this is what we'll use in Automation)

  • metadata.slack_username (the @handle you see as a person in Slack; can help you de-code the Slack UID if you need)

To call these values in Automation, you use a smart value, specifically one for the user you’d like to mention.

Let’s get the Slack mention ID for the reporter of a Jira issue:

{{issue.reporter.properties.metadata.slack_id}}

Formatted to work in Slack (the value must be surrounded by “<@>”), this is:

<@{{issue.reporter.properties.metadata.slack_id}}>

Here’s an example issue summary that dynamically Slack mentions the reporter:

<{{issue.toUrl}}|*{{issue.key}}*  {{issue.summary}}>
{{issue.description}} Reporter: <@{{issue.reporter.properties.metadata.slack_id}}>

 image.png

 

You can also use the smart values to send messages directly to any user you can call by smart value! Just add the smart value (plus the @ in front – no angle brackets here) to the "Channel or user" field.

image.png

Keeping values up to date

The great thing about Slack IDs is that they follow the user’s handle changes. It’s possible for the handle in Jira to become stale (metadata.slack_username), but since you’re using metadata.slack_id for the actual mention, there’s no problem with this.

You may want to run this script occasionally to catch up with new users in Jira/Slack. Just remember to treat the API tokens with care and not to store them publicly or in code repositories.

77 comments

David Michelson
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
November 10, 2020

This is awesome! Slack has become the best place to grab someone's attention when something is important/urgent. Adding automation + the power of mentions makes this so much easier.

Like # people like this
Zaur Suleymanov November 18, 2020

Hi, thanks for this article. Is it possible to configure this rule in a way that the message to Slack is send on behalf of a particular user, NOT by "Automation for Jira" or "incoming-webhook".  When there are several teams posting message into the same channel with the same header it creates confusion who released what.

Daniel Eads
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
December 9, 2020

@Zaur Suleymanov I understand how that could be a bit confusing. Currently Automation uses the "legacy" incoming webhook app in Slack, which does allow different usernames/logos - that's what selecting the "Send message as Automation for Jira" checkbox does. We've hardcoded the value in to Automation though, so there's no user-configurable option to override this in Jira. In the future however, it's possible we may need to switch from the legacy webhook to the Slack Apps webhook, which does not allow customization on the trigger side. Adding the option to customize now would be something that could easily break in the future.

As a workaround, I might suggest creating project emoji in Slack, and then using the project emoji in the message sent by Automation. While it's not as large as the actual user icon, this could give a more visual representation than text alone:

:your-project-icon: YOUR AWESOME PROJECT :your-project-icon:
<the rest of your Automation message>

If a single emoji isn't enough, you can edit an image into multiple emoji to get a longer banner:

image.png 

Like Zaur Suleymanov likes this
Zaur Suleymanov December 11, 2020

@Daniel Eads that's exactly the workaround I applied for our team to distinguish )) Thank you!

rick.leach December 17, 2020

Nice, thanks. One question: How do I undo it, if I need to?

noa December 17, 2020

INFO:root:Found account ID: 5fd628058332a1010efbe482 for user: max@orca.security

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/urllib3/connectionpool.py:1013: InsecureRequestWarning: Unverified HTTPS request is being made to host 'orcasecurity.atlassian.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

  warnings.warn(

ERROR:root:Could not add property for account: 5fd628058332a1010efbe482 [400] {'errors': {}, 'errorMessages': ['The property value can not be empty.'], 'httpStatusCode': {'present': True}}

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/urllib3/connectionpool.py:1013: InsecureRequestWarning: Unverified HTTPS request is being made to host 'orcasecurity.atlassian.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

 

@Daniel Eads any idea what is this issue?

Daniel Eads
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
December 17, 2020

@rick.leach The mention UID is stored as a user entity in Jira - this doesn't really affect anything else in Jira but if you want to remove it, a Jira Administrator can make a REST API call to null the value for a particular user. For the mentions - Automation rules in Jira can be toggled on and off. Does that answer your question?

rick.leach January 5, 2021

@Daniel EadsI mean, if something goes wrong for any reason and I want to undo, how do I do it? So that it goes back to not being linked?

Nofar Ben Kereth January 6, 2021

Is this available only for those who use Bitbucket?

Daniel Eads
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
January 9, 2021

@rick.leach messages sent in to Slack already could be deleted by a Slack workspace admin. Future messages can be un-coupled from at-mentioning someone by simply modifying the Jira Automation rule and taking out the smart value from the body of the message that is sent to Slack.

@Nofar Ben Kereth the code should be publicly accessible at https://bitbucket.org/atlassianlabs/slack_jira_sync - it doesn't require being signed in to access and download.

Nalaka Deegala January 22, 2021

@Daniel Eads First off, thanks for this workaround.  We desperately need a way to mention folks in Slack.  I configured as described but getting the following message for each of the email addresses, when the script is run:

INFO:root:Looking up 53 users in Jira server: https://accountingseed.atlassian.net
WARNING:root:No user found for email: <email address>
WARNING:root:No user found for email: <email address>
WARNING:root:No user found for email: <email address>
WARNING:root:No user found for email: ...

But the email addresses are present in the JIRA accounts

Like Adam Hudelson likes this
Daniel Eads
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
January 25, 2021

Hi @Nalaka Deegala , I'm glad this is helpful! The messages you see are informational; it will put a WARNING if it can't match a Jira user with a Slack account, or an INFO line when it can.

Once all the accounts have been iterated over by the script, you'll get a summary of all the matches like this:

INFO:root:Finished updating 153 propertie(s) in 153 account(s) found in Jira (Total 250 Slack member(s))

If the email addresses are separate between Jira and Slack, or if some users have access to one tool but not the other, you'll see a lot of warning lines in your terminal. I'd suggest looking at the totals on that last line and see if it sounds right. If you're getting matches at all, that means the script is running and should find all the accounts it can match. Then I'd double-check that the Slack account email addresses are the same as the ones in Jira if you're just not getting as many matches as you expect. They need to be an exact match - some companies with multiple domains have employees that use both emails like employee@company.com and employee@otherdomain.com; the script can't match accounts if the email addresses aren't exactly the same in both Jira and Slack.

dmitri.altum February 1, 2021

We're running into an issue with some users where the automation returns an error "Error sending Slack message Error from Slack [404]: channel_not_found". Our automation is simply notifying the assignee when a task moves to "In Progress".

We're using "@{{issue.assignee.properties.metadata.slack_id}}" as our value in the "Channel or user" box, and I have verified that the script did find the user and populate successfully. The user has the same email in both Slack & Jira. Any ideas where we can start to troubleshoot this?


Edit: We may have figured out why this is occurring. In the script run one of the users we are having issues with shows this message (note I've changed the actual characters of the account ID but left the formatting the same as what the script shows):

INFO:root:Found account ID: qm:ae47bdf2-431a-471f-897f-8267f9e7dbc0:ae94ce88-83c8-44b0-bd75-afdafadsfsdfsf for user: REDACTED


The successful users show:

INFO:root:Found account ID: 5fcad1e70d2f6100asdfghjk for user: REDACTED


For some reason the account ID is formatted extremely differently.


Edit Edit: For anyone else who runs into this issue, because of the small number of accounts that were affected by this we decided to just update those specific accounts manually with an API call and this worked successfully:

curl --request PUT --url 'https://<yourdomain>.atlassian.net/rest/api/3/user/properties/metadata?accountId=<user's Jira account ID>' --user '<your jira email>:<your API key>' --header 'Accept: application/json' --header 'Content-Type: application/json' --data '{"slack_id":"<user's slack ID>"}'

 

Like # people like this
dharper March 9, 2021

Hi , this looks great but would it be safe to assume that this is strictly for Cloud ? 

janez_m March 25, 2021

Thank you for this fantastic workaround @Daniel Eads. I have an issue with running the script though and would need some help if you're so kind.

I've tried many different combinations, the user is in admin group, but the script always crashes here:

[code]

INFO:root:Looking up 276 users in Jira server: https://jira-url-redacted.com
Traceback (most recent call last):
File "sync.py", line 225, in <module>
account_id = jira.get_user(email)
File "sync.py", line 44, in wrapper
return func(*args, **kwargs)
File "sync.py", line 137, in get_user
self._wrap_error("Failed to call search API.", response)
File "sync.py", line 94, in _wrap_error
log.error("{} [{}] {}".format(error_message, response.status_code, response.json()))
File "/usr/lib/python3/dist-packages/requests/models.py", line 897, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib/python3/dist-packages/simplejson/__init__.py", line 518, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 12 column 1 (char 11)

[code]

What am I missing? 

 

Edit: Apparently this is a Cloud only solution and apikey authorization won't work for server version - Is there a solution for a server version or is everything these days only for the Cloud version?

Like Hans likes this
Hans April 12, 2021

@Daniel Eads +1 on the question re: whether this procedure only applies to Cloud?

Sean M April 27, 2021

It would be really great if the author could explicitly mention whether this is exclusively for Cloud or if it works on On-Premises installations as well. Preferably near the top of the article.

Hans April 27, 2021

@Sean M fwiw, I couldn't get it to work on Server as written. I needed to revise the python script to change the authentication and have it set an API property instead of a GUI property.

Like # people like this
Sean M April 28, 2021

Thanks @Hans. I was thinking about looking into that, but I just delegated the manual process of dumping the slack ID into each user's 'legacy' properties. We have less than 100 users so it only took a couple of hours. From now on it will be part of our onboarding process for new employees.

Automation can access the property with the following syntax (where 'slackID' is the key of the property and the value is the Slack user ID)

<@issue.reporter.legacyProperties."jira.meta.slackID">
Like Luanna Gobbato likes this
Ibrahim Alamri June 20, 2021

Hello @Daniel Eads for some reason the script cannot find any users in Jira even though the same emails are used for both Jira and slack. 
We log-in to Jira using google account, will that be an issue? 

this is what I got after running the script 

INFO:root:Finished updating 0 propertie(s) in 0 account(s) found in Jira (Total 83 Slack member(s))


Like # people like this
Oana Barbulescu August 4, 2021

Hi,

With Jira Cloud i get the following error: 

INFO:root:Looking up 18 users in Jira server: https://something.atlassian.net
Traceback (most recent call last):
File "C:\Users\Oana\slack_jira_sync\sync.py", line 225, in <module>
account_id = jira.get_user(email)
File "C:\Users\Oana\slack_jira_sync\sync.py", line 44, in wrapper
return func(*args, **kwargs)
File "C:\Users\Oana\slack_jira_sync\sync.py", line 137, in get_user
self._wrap_error("Failed to call search API.", response)
File "C:\Users\Oana\slack_jira_sync\sync.py", line 94, in _wrap_error
log.error("{} [{}] {}".format(error_message, response.status_code, response.json()))
File "C:\Users\Oana\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\models.py", line 910, in json
return complexjson.loads(self.text, **kwargs)
File "C:\Users\Oana\AppData\Local\Programs\Python\Python39\lib\json\__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "C:\Users\Oana\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\Oana\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

 

The account from which I added the API key is an admin account. Also, I'm using  Python 3.9.6

Update : I was using the wrong variable for the $API_KEY -> the value must be the value of the api token created in jira.I was using the label.

yoga.pramono September 3, 2021

Hi @Daniel Eads 

hope you’re safe and healthy.

i've got an error when running the script : 

python3 sync.py --slack_token $SLACK_TOKEN --jira_url $JIRA_URL --username $USERNAME --apikey $APIKEY

its look like this: 

slack.errors.SlackApiError: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'}

i think that's because ratelimited

do you have a clue or suggestion to solve this error?

 

thanks before

Like Yurii Andrushchakevych likes this
yurii.karpenko September 10, 2021

Hey @Daniel Eads thanks for this awesome tutorial, works for me perfectly! But I've been wondering if it's possible to set this workflow to work with any user, not only reporter or assignee? F.ex if there is discussion happens under the ticket between few people from the team? 

Closest solution I've got so far is to use 

{{comment.body.text}}

but somehow it works only for users who doesn't have display name in Jira settings, so maybe you can hint me with a way how I can change it to ones who's with display names? Screenshot 2021-09-10 at 11.51.15.png

Like Nina Shcheglova likes this
Evan Nixon November 18, 2021

Hi @Daniel Eads , thanks very much for putting this together!

I'm having trouble getting sync.py from Bitbucket, both when logged in and in a private browsing window I just get this :

Screenshot 2021-11-18 114649.png

Is there anywhere else I can get sync.py? I've done some deep dive Googlin' for it and have come up with nada. 

Like Luanna Gobbato likes this
armcaelria January 4, 2022

Hi! Is this possible to mention list of users with this method? We have custom multiple users field and I need to mention all of them in message

Like # people like this

Comment

Log in or Sign up to comment
TAGS
AUG Leaders

Atlassian Community Events