Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

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.

23 comments

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 Bridget likes this

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 Dec 09, 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

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

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

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 Dec 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?

@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?

Is this available only for those who use Bitbucket?

Daniel Eads Atlassian Team Jan 09, 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.

@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

Daniel Eads Atlassian Team Jan 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.

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>"}'

 

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

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

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

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.

@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 Sean M likes this

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

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))


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.

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

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

Comment

Log in or Sign up to comment
TAGS
Community showcase
Published in Jira Automation

New to Jira Automation - goodbye Cron (sort of), hello new project created trigger, new additions to

Hey Everyone! Simeon from the Automation team here. I'm delighted to share some new features and improvements that we are shipping to Jira automation (Cloud only). Firstly, @Sam Harding&nbsp...

2,839 views 10 23
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you