📖   Chapter 8

Silence embarrassing notifications

Create a hotkey to enter Do Not Disturb and quit any embarrassing programs.

Next Chapter
APIs used today Description
hs.executeAllows you to call shell commands from Hammerspoon.
hs.osascriptExecute any AppleScript with this library.

What you’re building #

In this chapter, you’ll create a hotkey that quits all your embarrassing programs and turns on Do Not Disturb, so no notifications pop up. This is really useful when you’re screen sharing at work and don’t want your coworkers to see texts from your friends, or calendar invites about your upcoming job interview at a rival company. (For some hilarious examples of embarrassing notifications, check out the landing page for Muzzle.)

The hotkey quits iMessage/Signal and enters DND mode.

Create a new config file #

First, make a config file to hold all your audio switcher code.

copy
touch ~/.hammerspoon/silence-notifications.lua

And require it in your main config:

copy
require("silence-notifications")

Create a hotkey to silence notifications #

I call this feature “pairing mode” because I use this hotkey mostly when pair programming at work over Zoom.

copy
local function enableDoNotDisturb()
  -- TODO: fill this in
end

hs.hotkey.bind(hyper, 'p', function()
  -- Enable DND to silence all notifications.
  enableDoNotDisturb()

  -- Close any embarrassing personal apps. Add yours here:
  hs.execute("killall Messages")
  hs.execute("killall Notes")
  hs.execute("killall Signal")
  hs.execute("killall Telegram")

  hs.alert.show("Entering pairing mode")
end

Press ⌘⇧⌄⌃P to try it out. You should see all of those apps quit (if open), and an alert that says Entering pairing mode.

Turn on Do Not Disturb #

In order to prevent notifications from popping up, you need to implement the blank enableDoNotDisturb() function you created in the previous step. You can accomplish this by calling a few defaults write commands with hs.execute:

copy
local function enableDoNotDisturb()
  hs.execute("defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturb -boolean true")
  hs.execute("defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturbDate -date \"`date -u +\"%Y-%m-%d %H:%M:%S +000\"`\"")

  -- Restart NotificationCenter
  hs.execute("killall NotificationCenter")
end

If you’re running macOS Catalina (10.15) or earlier, this script will work and you can stop right here. However, Big Sur recently came along and spoiled the apple cart, so we have to jump through some more hoops to enable DND on macOS Big Sur (11.x).

Making it work on Big Sur #

First, expand the enableDoNotDisturb() function to detect which OS you’re running, so you can run the correct commands to enable DND:

copy
local function isRunningBigSur()
  -- This command returns a string like "10.14.6" or "11.4.1"
  local result = hs.execute("sw_vers -productVersion")

  -- Check if the version starts with "11" - if so, we're on Big Sur.
  return result:sub(1, 2) == "11"
end

local function enableDoNotDisturbBigSur()
  -- TODO: fill me in
end

-- Change the implementation here to check for Big Sur:
local function enableDoNotDisturb()
  if isRunningBigSur() then
    enableDoNotDisturbBigSur()
  else
    hs.execute("defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturb -boolean true")
    hs.execute("defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturbDate -date \"`date -u +\"%Y-%m-%d %H:%M:%S +000\"`\"")

    -- Restart NotificationCenter
    hs.execute("killall NotificationCenter")
  end
end

Next, run some AppleScript to open the Notification Center and click the DND toggle manually:

copy
local function enableDoNotDisturbBigSur()
  -- Thanks, I hate it.

  hs.osascript.applescript(
    [[
-- This checkbox has a weird \n break in the name.
set checkboxName to "Do Not
Disturb"

tell application "System Events"
  click menu bar item "Control Center" of menu bar 1 of application process "ControlCenter"
  delay 0.1

  set isChecked to (value of checkbox checkboxName of group 1 of group 1 of window "Control Center" of application process "ControlCenter")

  -- Only click the DND checkbox if it's off.
  if not (isChecked as boolean) then
    click checkbox checkboxName of group 1 of group 1 of window "Control Center" of application process "ControlCenter"
    delay 0.1
  end if

  click menu bar item "Control Center" of menu bar 1 of application process "ControlCenter"
end tell
    ]]
  )
end

Reload Hammerspoon and try the hotkey again. You should see the Notification Center open and the DND toggle get clicked automatically.

Connect your Bluetooth headphones

Get the entire script #

Want to just paste in this whole project to your silence-notifications.lua file?

copy
TK fill this in at the very end once we're sure all the code is solid
Connect your Bluetooth headphones