Slack is a popular communication and collaboration tool which has been adopted by many organizations including the one I work for. I am a fan of Slack and use it on a regular basis. Like most users, I am a member of several different workspaces and a ton of different channels.
I think most Slack users would agree that one of the most commonly miss-used feature of Slack is the @channel and @here notifications which allows a user to broadcast a message that notifies everyone within a specific channel. I most often see this when a user is looking for immediate assistance and think that this is the best way to get help, it is not. In some cases, inpatient uses end up spamming multiple channels which can have up to 1K+ members! As you can imagine, this type of behavior is usually not well received.
This is the modern day "reply-all" email storms that I am sure many of you have at experienced at least once if not many more times within your organization 🙂 Slack does provide a few ways of disabling notification, either within the workspace but this would disable the feature completely and I do see value in this feature when used correctly or disabling notifications on a per-channel basis as shown in the screenshot below.
If you are a member of a handful of channels, disabling notifications manually using the Slack UI is probably not a huge issue. However, if you are in a large number of channels and you forget to disable notifications when you first join, then it can be painful to go back through all the channels. I knew Slack had an API but when looking through their documentation, I was surprised to see there was no API that mapped to this specific feature. After some digging, I found out there was no public API for configuring these notifications but there was a private API which the Slack Web UI uses. I reached out to the @SlackAPI twitter handle to see if there were any way to call this private API ...
Hey @SlackAPI is there a reason there’s not a way to automate disabling [at]channel & [at]here notification?
I noticed your WebUI uses users.prefs.setNotifications which looks to be private API? Can we get this to be made public or a simply a way to automate at scale? pic.twitter.com/LZYGJ04GnD
— William Lam (@lamw) October 14, 2019
Sadly the response from Slack was no and that's when I decided to dig a bit further to see if there was a way I could automate this private API.
We're afraid not. Apologies — we realize this isn't the news you were hoping to hear, but we appreciate you flagging your interest with us.
— Slack Platform (@SlackAPI) October 14, 2019
It took a bit of trial and error to actually figure out how to call the private API since the API Access Token that I have is not scoped for this private method. In addition, I was also getting this strange token not valid even when using a valid API Access Token from the browser. It turns out there is an additional internal cookie (which is nicely documented here) called "d" which simply keeps track of the session that is logged in. Putting this together, I was now able to automate the enabling or disabling of the @channel and @here notifications for a particular Slack channel.
To make this user friendly to consume, I created a quick PowerShell function called Set-SlackNotification which accepts the following 5 arguments and will automatically enable or disable notifications for all Slack channels with the exception of the ones you whitelist.
- SlackAccessToken - This is your OAuth Access Token that you will need to either provide or generate as part of the OAuth login workflow. For more information on how to retrieve this for your account, please see the Slack documentation here. This is needed to iterate through all Slack channels you are a part of.
- SlackBrowserAccessToken - This is the OAuth Access Token which will be retrieved from the browser and is scoped to access the private Slack API. Instructions are provided below on how to retrieve this token.
- SlackBrowserSessionCookie - This is the internal Slack cookie that is required to be able to access the private Slack API. Instructions are provided below on how to retrieve this token.
- Operation - Supported values are Enable or Disable
- ExcludeChannels - This is an optional parameter that is designed to be a whitelist of channel names that you wish not disable or enable notifications. It is an array of strings and you can see an example below.
Step 1 - Open your Slack Client and right click on any channel and select the "Copy Link" which will provide you with a URL which will be used in the next step.
Step 3 - Load the URL that you retrieved from Step 1 and ensure the "record" icon is red as shown in the screenshot. There is a filter below, type auth?app and you should see a single entry after you have logged into your Slack instance. Under the Request Headers section which you will need to scroll down, under the cookie property, copy the long string for the cookie named "d" which represents the SlackBrowserSessionCookie.
Step 4 - In the filter, now type api.features and you may have a few entries. Just select the first on and on the right panel, look for token property and copy the long string which represents the SlackBrowserAccessToken.
$SlackAccessToken = ""
$SlackBrowserAccessToken = ""
$SlackBrowserSessionCookie = ""
$ExcludeChannels = @(
Step 6 - Download the slack_notification.ps1 script which contains the Set-SlackNotification function definition. To be able to call the function, you will need to load the function by simply running the following command to source the function:
Now the function can be called by simply running the following command:
Set-SlackNotification -SlackAccessToken $SlackAccessToken -SlackBrowserAccessToken $SlackBrowserAccessToken -SlackBrowserSessionCookie $SlackBrowserSessionCookie -Operation Disable -ExcludeChannels $ExcludeChannels
If everything was configured correctly, the script will iterate through all the Slack channels that you are a member of and either enable or disable notifications based on the selected operation. If you have specified the ExcludeChannels variable, then it will ignore those channels.
At the end of the script, you will get a count of the number of Slack channels that were updated. If there are any errors, the script will automatically stop and provide you with the error message returned from the API and it will most likely be related to one of the API tokens.
If you are constantly joining new channels, you could even setup a scheduled job to automatically run this script periodically (assuming your tokens are still valid). I really hope Slack considers adding this functionality to their public API, this seems like a really basic capability that should just be there so that user can easily automate this at scale.