This is a Spoon (or plugin) that makes it easier for Hammerspoon to interact with the Zoom videotelephony software.
If you aren’t familiar with Hammerspoon yet, it is a powerful programmable automation tool for macOS.
Using this Spoon in concert with Hammerspoon, you can do things like:
- Mute & unmute Zoom Audio or Video, even if your meeting window is buried under other apps
- Leave a meeting without having to search for the “Leave” button
- Open the Chat window that is impossible to find when you are screen sharing
- Bring the highest priority Zoom window to the forefront of all windows
- Bind custom functionality to Zoom App States that trigger when: the app opens or closes, meetings start or end, when you start or stop screensharing, and more!
- Make sure that you have Hammerspoon installed
If it’s not installed already, then use the Getting Started with Hammerspoon guide to learn how to install and use Hammerspoon.
- Install the Zoom Spoon
The easiest way to do this is to download the ZIP version of this Spoon, unzip it, remove the
-main
from the folder name, then double click theZoom.spoon
folder. Hammerspoon will install it for you.If you plan on modifying the Spoon and sending a pull request to this repo, then you should clone this repo into your
~/.hammerspoon/Spoons
Open your Hammerspoon configuration file and edit it to make use of this Spoon. Below is a sample configuration that does the following:
- Starts the Zoom Spoon
- Creates a pop-up notification whenever Zoom App status changes
- Will assign the
F1
button to bring the priority Zoom window to the forefront of all windows - Will assign the
F2
button to toggle Zoom audio mute status - Will assign the
F3
button to toggle Zoom video on/off status - Will assign the
F4
button to leave a Zoom meeting even if the meeting window is buried - Will assign the
F5
button to open Zoom Chat - Will assign the
F6
button to Zoom Screen Share Controls
hs.loadSpoon('Zoom')
updatedZoomStatus = function(currentState, audio, video)
hs.printf('Zoom App Status is now: %s', currentState)
hs.printf('Zoom Audio is: %s', audio)
hs.printf('Zoom Video is: %s', video)
if (audio == 'muted') then
hs.notify.new({
title = 'Zoom Audio',
informativeText = 'You are now muted'
}):send()
elseif (audio == 'unmuted') then
hs.notify.new({
title = 'Zoom Audio',
informativeText = 'People can hear you!'
}):send()
else
hs.notify.new({
title = 'Zoom Audio',
informativeText = 'Zoom has turned off your audio'
}):send()
end
end
spoon.Zoom:setStatusCallback(updatedZoomStatus)
spoon.Zoom:start()
hs.hotkey.bind('', 'f1', function()
spoon.Zoom:focus()
end)
hs.hotkey.bind('', 'f2', function()
spoon.Zoom.audio:toggleMute()
end)
hs.hotkey.bind('', 'f3', function()
spoon.Zoom.video:toggleMute()
end)
hs.hotkey.bind('', 'f4', function()
spoon.Zoom:leaveMeeting()
end)
hs.hotkey.bind('', 'f5', function()
spoon.Zoom.chat:open()
end)
hs.hotkey.bind('', 'f6', function()
spoon.Zoom.share:showControls()
end)
These three lines are the most important:
hs.loadSpoon('Zoom')
spoon.Zoom:setStatusCallback(updatedZoomStatus)
spoon.Zoom:start()
The first line, hs.loadSpoon('Zoom')
, loads this Spoon.
The second line, uses the spoon.Zoom:setStatusCallback()
method to have the updatedZoomStatus
function called when the state of the Zoom app changes.
And finally, the last line, spoon.Zoom:start()
starts up the Zoom spoon.
-- Zoom Spoon Controls
spoon.Zoom:start()
spoon.Zoom:stop()
spoon.Zoom:debug() -- enables hs.printf() logging in hs console
spoon.Zoom:inMeeting()
spoon.Zoom:leaveMeeting()
spoon.Zoom:focus()
-- Zoom Audio Controls
spoon.Zoom.audio:status()
spoon.Zoom.audio:mute()
spoon.Zoom.audio:unmute()
spoon.Zoom.audio:toggleMute()
-- Zoom Video Controls
spoon.Zoom.video:status()
spoon.Zoom.video:mute()
spoon.Zoom.video:unmute()
spoon.Zoom.video:toggleMute()
-- Zoom Chat Window
spoon.Zoom.chat:open()
spoon.Zoom.chat:close()
-- Zoom Participants
spoon.Zoom.participants:open()
spoon.Zoom.participants:close()
-- Zoom Share Controls
spoon.Zoom.share:stop()
spoon.Zoom.share:showControls()
-- Zoom App Event Function Callbacks
-- Registers a function to be called whenever Zoom's state is changed or examined
-- Parameters:
-- func - A function in the form function(currentState, audioStatus, videoStatus)
-- currentState = a string representing the current state of the Zoom State Machine
-- audioStatus = a string representing the current Zoom Audio state
-- videoStatus = a string representing the current Zoom Video state
spoon.Zoom:setStatusCallback(func)
-- Registers a function to be called whenever a Zoom state transition occurs
-- Parameters:
-- func - A function in the form function(stateTransition)
-- stateTransition = a string representing the state transition in the form: 'from-running-to-meeting'
spoon.Zoom:setTransitionCallback(func)
- Remove useless “Launch Zoom Meeting” tabs from Chrome that open whenever joining a meeting
- Track logged in status of Zoom App
- Track number of Participants in current meeting