Zoom Keyhole

Documentation Status

A small FastAPI service that shows who is in a Zoom room on one or more Miro boards. Room configuration (users, rooms, boards, role symbols) is read from a Google Sheet; Miro text widgets are updated to display live participants.

Quick start

  1. Prepare your Miro boards:

  • Add a text widget per Zoom room, with the room name and the literal text “Meeting ID:”. The service will insert the meeting ID as a clickable link and keep the participant list up to date.

  1. Prepare your Google Sheet:

  • Create a sheet with tabs named: Users, Rooms, Boards, Role symbols. Populate them according to your conventions. The service periodically reloads these tabs.

  1. Run locally:

  • Create a .env file (or export the variables in your shell) with the required environment variables listed below. The Makefile will auto-load .env.

  • Start the service:

make run
# or:
uvicorn src.zoom_keyhole.main:APP --host 0.0.0.0 --port 8000 --loop asyncio --reload

The service exposes its routes under the optional ROOT_PATH (default is set by the Helm chart).

Environment variables

Required:

  • ZOOM_KEYHOLE_MIRO_API_TOKEN: Miro API token. For multiple tokens, use a semicolon-separated list locally; when set via Helm/values, use colon-separated.

  • ZOOM_KEYHOLE_ZOOM_CLIENT_ID: Zoom OAuth client ID.

  • ZOOM_KEYHOLE_ZOOM_CLIENT_SECRET: Zoom OAuth client secret.

  • ZOOM_KEYHOLE_ZOOM_ACCOUNT_ID: Zoom account ID for server-to-server OAuth.

  • ZOOM_KEYHOLE_WEBHOOK_SECRET_TOKEN: Secret used to validate Zoom webhook URL challenges and payloads.

  • ZOOM_KEYHOLE_GSHEET_ID: Google Sheet ID containing configuration.

  • One of:

    • GOOGLE_SERVICE_ACCOUNT_KEY_B64: Base64-encoded Google service account JSON (recommended), or

    • ZOOM_KEYHOLE_GSHEET_KEY: Google Sheets API key (fallback).

Optional (sensible defaults exist):

  • ROOT_PATH: URL prefix when running behind a reverse proxy (Helm defaults to /ska/zoom-keyhole).

  • ENABLE_DEBUG_METHODS: Enable debug/admin routes (default: true). Disable in production.

  • ZOOM_KEYHOLE_FILE_LOGGER: Enable file logging when set to a non-zero value.

  • Scan/refresh periods (seconds): ZOOM_ROOM_SCAN_PERIOD, MIRO_BOARD_SCAN_PERIOD, MIRO_BOARD_UPDATE_PERIOD, GSHEET_USERS_SCAN_PERIOD, GSHEET_BOARDS_SCAN_PERIOD, GSHEET_ROOMS_SCAN_PERIOD, GSHEET_ROLES_SCAN_PERIOD.

Kubernetes (Helm)

The included chart deploys the service and sets the default ingress path to /ska/zoom-keyhole. Install by providing sensitive values at install time:

helm install zoom ./charts/ska-zoom-keyhole --values values.yaml

Minimal values.yaml example (redacted):

---
env:
  ZOOM_KEYHOLE_MIRO_API_TOKEN: "<token or token:token2>"
  ZOOM_KEYHOLE_ZOOM_CLIENT_ID: "<client id>"
  ZOOM_KEYHOLE_ZOOM_CLIENT_SECRET: "<client secret>"
  ZOOM_KEYHOLE_ZOOM_ACCOUNT_ID: "<account id>"
  ZOOM_KEYHOLE_WEBHOOK_SECRET_TOKEN: "<webhook secret>"
  ZOOM_KEYHOLE_GSHEET_ID: "<sheet id>"
  # Choose one auth method for Google Sheets:
  GOOGLE_SERVICE_ACCOUNT_KEY_B64: "<base64 service account json>"
  # or, as a fallback:
  ZOOM_KEYHOLE_GSHEET_KEY: "<api key>"
  # Optional
  ROOT_PATH: "/ska/zoom-keyhole"

In environments using an ingress controller (e.g. NGINX), the default path is /ska/zoom-keyhole. Adjust ROOT_PATH and ingress settings as needed in the chart values.

Documentation

Full documentation (architecture, configuration, operations) is available on Read the Docs:

https://zoom-keyhole.readthedocs.io/en/latest/

For chart defaults, see charts/ska-zoom-keyhole/values.yaml in this repository.