Hammerspoon Spoon:全局切换 Microsoft Teams 会议麦克风的热键,可在任何软件中使用。
AI 翻译
Hammerspoon Spoon: toggle the Microsoft Teams meeting mic from a hotkey globally, from any app
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A Hammerspoon Spoon that toggles the Microsoft Teams meeting microphone from a single hotkey, from any app, and tells you whether it worked.
• One hotkey toggles mute from anywhere: if Teams isn't frontmost it's activated, the toggle is sent, then focus returns to the app you were in
• Sends Cmd+Shift+M, then confirms the toggle.
• On-screen alert for the result: 🔶 Teams Muted / 🎤 Teams Unmuted on success, or a 🛑 alert (No active Teams call, Teams did not activate in time, Mute toggle did not register, STILL MUTED/STILL UNMUTED) on failure查看完整 README ↗A Hammerspoon Spoon that toggles the Microsoft Teams meeting microphone from any app, tells you whether it worked, and shows your mute state in the menu bar.
Repository: https://github.com/hugoh/TeamsControl.spoon
🔶 Teams Muted / 🎤 Teams Unmuted, or a 🛑 alert explaining what went wrongEnsure you have Hammerspoon installed, then choose a method:
TeamsControl.spoon.zip from the latest releaseTeamsControl.spoon folder~/.hammerspoon/Spoons/hs.reload() in the console)spoon.SpoonInstall:installSpoonFromZip(
"https://github.com/hugoh/TeamsControl.spoon/releases/latest/download/TeamsControl.spoon.zip"
)
cd ~/.hammerspoon/Spoons
git clone https://github.com/hugoh/TeamsControl.spoon.git
Bind a hotkey and start the menu bar indicator:
hs.loadSpoon("TeamsControl")
:bindHotkeys({ toggleMute = { { "ctrl", "alt", "cmd" }, "m" } })
:start()
stop() removes the indicator and unbinds the hotkeys.
Or call toggleMute() yourself from your own hotkey wiring:
local teamsControl = hs.loadSpoon("TeamsControl")
hs.hotkey.bind({ "ctrl", "alt", "cmd" }, "m", function() teamsControl:toggleMute() end)
toggleMute() accepts an optional callback, invoked once the toggle has settled
(or the call was ignored as re-entrant), for driving a busy indicator.
Tune behaviour with configure() (all optional):
hs.loadSpoon("TeamsControl"):configure({
teamsBundleID = "com.microsoft.teams2", -- Teams app bundle identifier
activationTimeout = 5, -- seconds to wait for Teams to come forward when retrying
clickSettleDelay = 0.05, -- seconds between checks that the toggle registered
clickSettleMaxRetries = 10, -- checks before retrying, then before giving up
showMenubar = true, -- show the menu bar indicator
menubarStatusDot = true, -- show a 🟢/🟡 dot next to the menu bar icon
menubarPollInterval = 1, -- seconds between menu bar indicator refreshes (only while Teams runs)
useApi = true, -- use Teams' local API when available
apiPort = 8124, -- port of Teams' local API
apiRetryInterval = 30, -- seconds between attempts to reach the API
apiMaxRetries = 3, -- attempts per Teams launch before giving up
apiConfirmTimeout = 0.5, -- seconds to wait for the API to confirm a toggle before the keystroke fallback
}):start()
TeamsControl reads Teams' accessibility tree and sends synthetic keystrokes and clicks, so Hammerspoon needs Accessibility permission (System Settings → Privacy & Security → Accessibility). It never launches anything but Teams and never shells out.
TeamsControl uses Teams' local third-party API when it can, which mutes without keystrokes or bringing Teams forward, and shows the menu bar state instantly. It falls back to the keystroke and accessibility path whenever the API is off, unpaired, or doesn't answer, so nothing here is required.
To enable it:
~/Library/Containers/com.microsoft.teams2/Data/Library/Application Support/Microsoft/MSTeams/configuration.json containing {"thirdPartyDevices/thirdPartyDevicesManagerEnabled": true}, then restart Teams.The log (info level) shows which path each toggle takes. TeamsControl retries the connection apiMaxRetries times after Teams starts, so enable the API before launching Teams. Set useApi = false to turn it off.
The accessibility-tree mute-button lookup (findButton in ui.lua) is adapted from _teamsFindButtonByLabel in RobvH/teams-mac-hotkeys.
The Teams local API client (connection URL, pairing flow, token refresh and request format) follows asp55/MSTeams.spoon2 (MIT, © 2026 asp55), which in turn credits svrooij's documentation of the API.
Full API reference is generated from the docstrings in init.lua (mise run docs).