Silencing Slack while coding

I get pinged on Slack a lot. Most of the time this is fine, but the moment I open VS Code I want it silenced. Not forever, just while I am actually typing. And the second I switch away to a browser or to a meeting, I want it back, because forgetting that you are on Do Not Disturb is in my experience worse than the interruptions themselves. So this is not really about silencing Slack, this is about not having to remember anything.

I tried a few things before landing on something I am happy with.

Why not just use the Slack API

Permalink to “Why not just use the Slack API”

This was of course my first instinct. Slack has dnd.setSnooze and dnd.endSnooze, and they sound exactly like what I want. They are not. Using them needs a user OAuth token, bot tokens do not work, and depending on the workspace you might need an admin to approve the scopes. And on top of that it changes my Slack status. I do not want to stop my coworkers from messaging me, I just want to not be distracted by it for 30 minutes. These are different things.

So Slack is the wrong layer to fix this at. The right layer is macOS.

The setup

Permalink to “The setup”

There are three little pieces and each one does exactly one thing.

A Focus mode called Coding that silences Slack. Two Shortcuts called Coding Focus ON and Coding Focus OFF that toggle the focus mode. And a small Hammerspoon script that runs the ON shortcut when VS Code becomes the active app, and the OFF one when it is not.

The Focus mode and the Shortcuts are 2 minutes of clicking around in System Settings, there is nothing interesting to write about there. The only part worth showing is the Hammerspoon script in ~/.hammerspoon/init.lua:

local VSCODE_BUNDLE_IDS = {
  ["com.microsoft.VSCode"] = true,
  ["com.microsoft.VSCodeInsiders"] = true,
}

local focusOn = false

local function runShortcut(name, onDone)
  hs.task.new("/usr/bin/shortcuts", function(code)
    if code == 0 and onDone then onDone() end
  end, { "run", name }):start()
end

local function isVSCode(app)
  return app and VSCODE_BUNDLE_IDS[app:bundleID()] == true
end

hs.application.watcher.new(function(_, event, app)
  local w = hs.application.watcher
  if event == w.activated and isVSCode(app) and not focusOn then
    runShortcut("Coding Focus ON")
    focusOn = true
  elseif (event == w.deactivated or event == w.terminated) and isVSCode(app) and focusOn then
    runShortcut("Coding Focus OFF", function()
      hs.alert.show("Slack notifications restored", 2.0)
    end)
    focusOn = false
  end
end):start()

That is the whole thing.

If you want to extend it, just add more bundle IDs to the table. JetBrains, iTerm, whatever you live in. You can find a bundle ID with hs.application.get("Visual Studio Code"):bundleID() in the Hammerspoon console, takes 5 seconds.

No tokens, no Slack permissions, no admin approval, no custom app. Just one config file and a Focus mode that turns itself off the moment I look away. Honestly the best part is that I forget it exists, which is exactly what you want from a tool like this.