The problem is simple: I have a physical on-air sign, and I need the browser to tell it when a meeting starts and ends. The solution should work without routing my meeting state through someone else’s server.
The extension is published on the Chrome Web Store and the source is on GitHub.
What it detects
The extension watches tab URLs for known meeting patterns — Google Meet, Microsoft Teams, and Zoom. It also supports custom URL prefixes, so if your company runs a self-hosted Jitsi or a custom videoconferencing tool you can add it. Detection is entirely client-side; no tab content is read, no audio or video is accessed.
How it triggers
When a meeting is detected, the extension sends an HTTP request to a configured target. There are three target types:
Local HTTP — direct request to a device on the LAN (Home Assistant, Tasmota, Shelly, an ESP32 running its own HTTP server). Zero latency, zero cloud dependency. This is the common case when you’re at home.
IoT (local + cloud hybrid) — tries the device’s local IP first. If that fails (timeout or network error), falls back to an HTTPS endpoint — in my case an API Gateway + Lambda that publishes to AWS IoT Core. The sign gets the state change whether I’m at home or not.
Push notification — if you don’t have IoT hardware, the extension can send a push notification to your phone instead. Documented separately.
Manifest V3
The extension uses Manifest V3, which is the current Chromium extension API. MV3 replaced background pages with service workers, which has real implications for persistent state — a service worker can be suspended between events, so you can’t rely on in-memory variables surviving across tab updates. The extension handles this by writing state to chrome.storage.session (cleared on browser restart, fast, synchronous-ish) rather than keeping it in module scope.
The meeting-active state needs to survive the service worker being killed and restarted mid-meeting. storage.session covers that correctly; a plain variable does not.
Settings UI
The redesigned settings page uses a template system — common IoT targets (Home Assistant webhook, Tasmota power command, the OnAir cloud bridge) are pre-built and selectable with one click. You can also build custom targets from scratch. Settings export/import is JSON, so migrating to a new machine or sharing a config is a file copy.
Privacy
No telemetry. The extension doesn’t phone home, doesn’t send meeting metadata anywhere, doesn’t log URLs beyond what’s needed for detection. The only outbound requests are the ones you configure — to your own devices or your own cloud endpoints.
The sign
The physical target for this extension is the On-Air LED sign — an ESP32-C6 running firmware that translates the extension’s HTTP payloads into WS2812 LED states. That’s covered in part 1 and part 2 of the firmware series.