Building a mute button toggler for Zoom with Espruino and Puck.js

• ~700 words • 3 minute read

Wouldn't it be nice if you had a little device you could click to mute and unmute yourself on a Zoom call? In this remote-work world many of us have plunged into post COVID, I don't think it's that uncommon to find yourself on an occasional Zoom meeting, camera-off, milling about your kitchen while you listen.

If you find yourself needing to chime-in though, what do you do? Run back over to your computer like a goofball Wrestle with the mouse or keyboard to unmute yourself and say "Yup, that sounds about right!" before running back to your kitchen business?

My friends, this is a task the Puck.js was born to solve.

Inspired by an idle thought from a coworker, I whipped up a simple program to turn my neglected clicker into a little Zoom muter.

Espruino, Puck.js and JavaScripton Things™

The Puck.js is a custom Bluetooth beacon powered by Espruino—a custom flavor of JavaScript designed to work on low-powered, single board microcontrollers. Both the language and the device(s) were designed by Gordon Williams.

HID, Bluetooth HID and

One of the more fun things you can do hacking around with a Bluetooth-capable controller is broadcast the services your device offers and identify what kind of device it is. Other device can see this "profile" broadcast and will use that to interpret how it should interface with you based on some established standard in the HID and/or BLE HID spec.

An exampe: I have (mostly undeserved) credit for contributing to the BLE MIDI module for the Espruino ecosystem here:

That module makes it so that computers can specifically recognize it as a Bluetooth MIDI device. When it's connected to another device that understands it to be a BLE MIDI device, it's now for all intents and purposes a MIDI instrument and can behave/communicate as such.

👆 If you're curious how or why I did this, check out my Puck.js MIDI instrument code and peruse some of my videos on YouTube.

What other kinds of devices can you trick tell other computers you are? A completely unexhaustive list includes:

  • Joysticks
  • Mice
  • Keyboards
  • Headsets
  • MIDI Instruments (technically not HID, I think, but in the same spirit)
  • Webcams
  • Health Devices
  • Audio/Video Remote Controls

Rules! Standards! They are what separate us from the animals... and also the reason your AirPods can talk to your Android phone.

How did the Zoom mute toggler work?

For our Zoom mute toggler, I focused on the keyboard profile. I was basically going to turn it into a bluetooth keboard that did exactly one thing.

My approach was simple:

  • Tell the Puck.js to broadcast itself as BLE keyboard
  • When the button (there is only one button) is pressed, "tap" the keyboard shortcut for toggling the microphone in Zoom
  • When the button is released, "type" the same keyboard shortcut again (so it acts like a toggle)

That's... it! All-in-all, about 20 lines of code:

With the code flashed to the Puck.js I can now connect to it from the Bluetooth settings in macOS. It will recognize it as a BLE keyboard and start accepting keystrokes from it immediately.

Shortcoming of this approach:

  • It is literally hard-coded to Zoom. If you're using ofter video chat software, you'd have to change the keyboard shortcut.
  • It requires Zoom to be the application current in focus on your system. Otherwise it will send Ctrl/Cmd+Shift+A to whatever the foreground application is.

Future improvements:

  • Maybe I could adopt the single/double/triple click code I implemented for the MIDI clicker to give this device different "modes" depending on the video software I'm using? It's mostly a Zoom world out there for me, but once in a while I find myself on a Slack huddle or Google ... whatever they're calling their video stuff these days. Meet?
  • The behavior currently is designed around holding it down when you want to speak and releasing the button when you want to go on mute again. Still not sure if that's the most ergonomic UX, but it seems fine for now.

I want one!

If you'd like your own, simply:

  1. Go to puck-js.com and buy one
  2. Copy the code and flash it to your device using the Espruino Web IDE

That's it!

If you'd like me to make one for you—or have some other idea for a single-button "thing" you'd like to see implemented this way—get in touch! My prices are very reasonable :-)