Disable Slack @channel and @here notification for all channels

Programming1226

Problem

Slack can get very noisy if you are part of a big organisation. Slack offers various notification controls on a per-channel basis.

You can choose to be notified if:

  • There is a new message
  • Somebody mentions you
    • Somebody mentions @channel or @here
  • Never

For example:

Slack Notification Options for a Channel

Slack points out that you can tweak your workspace-wide settings in your preferences. However, these settings do not mimic the per-channel options. They are missing the ability to suppress @channel or @here mentions. This is the main annoyance with Slack notifications! Getting a ping for a channel you are in that has nothing to do with you. My org actually discourages using these mentions in some channels but somebody eventually does (an easy mistake to make) which immediately summons a hoard of angry emoji reactors who have lost their state of focus.

Slack Workspace Wide Notification Preferences

Slack pls help?

Contacting Slack support did not help in this case. This feature was not planned on their roadmap for the foreseeable future. The only options were to manually update every single channel or turn off all notifications.

Script Solution!

Luckily, we can write a script to solve this problem for us!
It works by fetching a list of all Slack channel ids from the api/client.boot endpoint and then calling the api/users.prefs.setNotifications endpoint to update the preferences for each channel. A delay is used between each update to prevent server-side rate limiting.

First, download the latest version of the script from here:
https://gist.github.com/mobeigi/8e5372f1e14e2a302e186d1753f9a649

Or copy and paste it from here:

// Slack User Notification Preference Bulk Update
// By Mo Beigi

const slackTeamId = "EXAMPLE17";
const localConfigJson = JSON.parse(localStorage.localConfig_v2);
const slackUrl = localConfigJson.teams[slackTeamId].url;
let channel_ids = [];

// client.boot contains list of channel ids user is subscribed to amongst other things
await fetch(slackUrl + "api/client.boot?" +
    "_x_id=noversion-1609923716.289" +
    "&_x_version_ts=noversion" + 
    "&_x_gantry=true", 
  {
    method: 'post',
    credentials: 'include',
    headers: { "Content-type": "application/x-www-form-urlencoded; charset=UTF-8" },
    body: "token=" + localConfigJson.teams[slackTeamId].token + 
        "&only_self_subteams=1" + 
        "&flannel_api_ver=4" + 
        "&include_min_version_bump_check=1" + 
        "&version_ts=1609901609" + 
        "&_x_reason=deferred-data" + 
        "&_x_sonic=true",
  },
)
.then(result => result.json())
.then(result => channel_ids = result.channels);

// iterate channel id list and set notification prefs asynchronously
let fetchPromises = [];
for (i = 0; i < channel_ids.length; ++i) {
    console.log("Setting user notification prefs for channel id: " + channel_ids[i].id + " ...");
    fetchPromises.push(
        fetch(slackUrl + "api/users.prefs.setNotifications?" +
            "_x_id=03bd03b3-1609923922.760" + 
            "&_x_csid=YEOKuX4kPF4" + 
            "&slack_route=" + localConfigJson.teams[slackTeamId].enterprise_id + ":" + slackTeamId +
            "&_x_version_ts=1609901609" + 
            "&_x_gantry=true", 
            {
                method: 'post',
                credentials: 'include',
                headers: { "Content-type": "application/x-www-form-urlencoded; charset=UTF-8" },
                body: "name=suppress_at_channel" +
                    "&value=true" + 
                    "&channel_id=" + channel_ids[i].id +
                    "&global=false" + 
                    "&sync=false" +
                    "&token=" + localConfigJson.teams[slackTeamId].token +
                    "&_x_reason=prefs-store/setChannelNotificationOverride" +
                    "&_x_mode=online" +
                    "&_x_sonic=true"
            }
        )
        .then(result => result.json())
        .then(console.log("Done (" + channel_ids[i].id + ")"))
    );

    // Generous delay to get around rate limit
    await new Promise(r => setTimeout(r, 250));
}

Promise.all(fetchPromises).then(function() {
    console.log("Successfully set user notification prefs for " + channel_ids.length + " channels.");
});

Step by step guide

  1. Visit the React web app which powers the React native Slack client at:
    http://app.slack.com/client
  2. Sign in and switch to the workspace of interest and wait for the page to fully load.
  3. Open your browsers developer console
  4. Execute the following line:
    JSON.parse(localStorage.localConfig_v2).teams

    It should output an object with a bunch of team ids. Copy and paste the id of the workspace of interest.
    In my example its: EXAMPLE17
  5. Replace the slackTeamId in the Javascript script with your id from Step 4.
  6. Copy and paste the edited Javascript script into the developer console and execute it.
    The script may take a few minutes to run depending on the number of channels you have joined.
    slack_user_noti_pref_bulk_update.js script execution

Leave a comment

(required)(will not be published)(required)

Comments

Showing 6 comments from 3 commenters.

  • Display picture for Sagar
    Sagar

    This gives me the following error in Chrome:

    Uncaught TypeError: Cannot read property 'length' of undefined

    at :29:29

    I get similar errors in Firefox ("channel_ids is undefined").

    I'm not a big Javascript developer but `request.channels` does return things. I'm not sure why it doesn't like `let channel_ids = [];`...

    Reply
    • Display picture for Mo Beigi
      Mo Beigi

      Hi Sagar, it looks like `_x_id`, `version_ts`, `_x_id`, `_x_csid` and `_x_version_ts` all became out of date due to Slack updates.

      I've gone ahead and fixed this and the updated script should now work but it will break in the future, unfortunately.

      Reply
      • Display picture for T
        T

        Hi Mo, thanks for developing the script.

        Facing the same issue as Sagar.

        Can you let me know how you fetched those parameters in the first place so I can find them out and update for myself?

        Reply
        • Display picture for Mo Beigi
          Mo Beigi

          Howdy, I get them from the Slack Web UI. Log into Slack on your web browser. Open up the Network Developer Console and monitoring incoming network requests.

          You'll see the latest values for those parameters being used in various network requests. Let me know if you managed to fix it.

          Reply
          • Display picture for T
            T

            Thanks for the reply. I managed to fetch all those variables and updated them but seems like the same problem still persist, maybe they have changed something

            Reply
            • Display picture for Mo Beigi
              Mo Beigi

              I had a look at the script and it does seem like its failing now due to various errors (content type issue + CORS errors). I may try and fix it at some point if I have time, otherwise it would be better if we push on the Slack team to officially add this feature to their tool.

              Reply