Skip to main content
The MeetCost Google Meet add-on surfaces a live cost estimate in the Google Calendar side panel while an organiser is still writing an invite — and shows the actual cost after the meeting ends, once the Google Reports API has published its attendance record. It is a pure rendering layer: it reads the event the user already has open, sends attendee addresses and duration to your organisation’s own MeetCost backend, and draws whatever comes back. No pay figure is ever written back to Google, and the add-on holds no salary or rate data of any kind.

How the add-on works

The add-on is a Google Apps Script project deployed as a Workspace Add-on from the clients/google-meet-addon/ directory. When a calendar event is opened, onCalendarEventOpen fires; when attendees or times change, onCalendarEventUpdate fires. Each trigger calls buildEventCard, which reads the open event’s attendees, filters out rooms and declined guests, resolves the RRULE cadence, and POSTs to /api/v1/estimate on your MeetCost backend.
The add-on requests currentEventAccess: READ and nothing wider. It cannot see any calendar the user has not explicitly opened, and it has no write scope of any kind.

OAuth scopes


Prerequisites

Before you begin, confirm:
  • You have a deployed MeetCost backend reachable over HTTPS.
  • A Google Workspace admin account is available to grant domain-wide delegation and publish the add-on to the domain.
  • A Google Cloud service account exists (or can be created) with the Admin SDK API enabled, for directory sync and attendance polling.

Installation

1

Create the Apps Script project

Go to script.google.com and create a New project. Copy Code.gs, Config.gs, and Ui.gs from clients/google-meet-addon/ into the project.
2

Apply the manifest

In Project Settings, enable Show “appsscript.json” manifest file, then replace the contents with the appsscript.json from clients/google-meet-addon/:
Replace https://meetcost.your-company.example/ with your actual MeetCost address. Apps Script will refuse to reach any other host.
3

Set the backend URL script property

In Project Settings → Script Properties, add:If this property is unset, the add-on displays a configuration message and does nothing. There is no default and no fallback — by design.
4

Test on your own account

Go to Deploy → Test deployments, install the add-on on your own account, open a calendar event, and confirm the MeetCost card appears in the side panel.
5

Publish to your Workspace domain

Go to Deploy → New deployment → Add-on, then publish through the Google Workspace Marketplace SDK. Choose Private (domain-only) distribution — this requires no Google review and is available to everyone in your Workspace organisation immediately.

Authentication

The add-on identifies the calling user with ScriptApp.getIdentityToken(), which returns a Google-issued OpenID Connect token. The backend verifies this token against the OIDC issuer https://accounts.google.com. MeetCost has no accounts and no passwords: the identity assertion is Google’s own, travelling to your organisation’s own infrastructure.
The backend must be configured with MEETCOST_OIDC_ISSUER=https://accounts.google.com and MEETCOST_OIDC_AUDIENCE set to your Workspace client ID for token verification to succeed.

Directory sync

MeetCost looks up pay figures by email address, so it needs a copy of your Workspace user directory. The Google adapter authenticates with a service account using a JWT grant (domain-wide delegation), then pages through the Admin SDK Directory API.

Required environment variables on the server

Service account permissions

Grant the service account domain-wide delegation in your Workspace Admin console, with these OAuth scopes: The service account must have the Admin SDK API enabled in your Google Cloud project (admin.googleapis.com).
Never grant the service account write access to the directory. MeetCost is read-only; if you find yourself needing a write scope, something has gone wrong in your setup.

Attendance collection

Google Meet has no end-of-meeting webhook. Attendance is polled from the Reports API meet application, call_ended events. Because the Reports API is eventually consistent — events can lag a meeting’s end by minutes to hours — MeetCost uses a poller with an overlapping window rather than a one-shot read. Run the collector on a schedule (for example, every 15 minutes via cron):
The --hours flag sets how far back the window reaches. Use a value larger than the typical lag you observe in your domain; 3 is a reasonable starting point.

Authenticated trigger endpoint

For operator-initiated sweeps, the backend also exposes an authenticated admin endpoint:
This endpoint requires an admin-role token (or a configured service token). It immediately queues a Reports API sweep for the given window. The hours query parameter is optional and defaults to 24. It is useful for triggering a collect after a known meeting ends without waiting for the cron.
The poll trigger does not replace the cron. Reports API events can still be delayed after the trigger fires. Run both for reliable coverage.

Cadence and the annualised figure

The add-on maps Google Calendar’s RRULE values to MeetCost cadences automatically: When the cadence is one_off or cannot be determined, the annualised figure is suppressed rather than guessed. The organiser can always set the cadence manually in the card. Showing no annual figure is better than showing a wrong one.

Security model

No pay data to Google

The add-on never sends a salary, rate, or cost figure to Google. It sends attendee email addresses and duration — data the user already has on screen.

No default backend

The urlFetchWhitelist in appsscript.json and the MEETCOST_BACKEND_URL script property together enforce that the add-on contacts only the URL your administrator set. There is no fallback address.

HTTPS enforced

getBackendUrl() rejects plaintext URLs to any host other than localhost. Identity tokens are never sent over unencrypted connections to production addresses.

Read-only event access

currentEventAccess: READ is the narrowest scope Calendar add-ons can request. The add-on cannot modify any event or see any calendar the user has not opened.