# How to Integrate Retool with Google Meet

- Tool: Retool
- Difficulty: Intermediate
- Time required: 20 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Google Meet by querying Google Calendar API data — Google Meet meetings are Calendar events with conferenceData attached. Authenticate via Google OAuth 2.0 using a REST API Resource, then fetch meetings with conferenceData, extract participant information from attendees, and build team meeting analytics dashboards that surface scheduling patterns, attendance, and meeting load across your organization.

## Why connect Retool to Google Meet?

Google Meet meetings live inside Google Calendar — there is no separate Google Meet dashboard that shows you meeting analytics, team load, or scheduling patterns across an organization. Operations managers, HR teams, and engineering leads who want to understand meeting culture (who is overloaded with meetings, which teams are most collaborative, how many hours per week go to recurring syncs) have to export Calendar data manually or use expensive third-party analytics tools. Retool provides an alternative: query the Google Calendar API directly to surface Meet meeting data in fully customizable internal dashboards.

The key insight is that every Google Meet meeting is a Google Calendar event with a conferenceData object attached. This object contains the Meet conference ID, the join URL (https://meet.google.com/xxx-xxxx-xxx), and the conference solution type. Filtering Calendar API queries to events where conferenceData.conferenceSolution.key.type equals hangoutsMeet gives you all Meet meetings across any calendar you have access to. From there, each event's attendees array shows all invitees with their response status (accepted, declined, needsAction, tentative), enabling attendance analytics.

For organizations on Google Workspace Enterprise plans, a supplementary Google Meet REST API (currently in beta) allows managing Meet spaces directly — creating persistent spaces, listing active and scheduled meetings, and retrieving participant data from recently completed calls. This API is separate from Calendar and provides richer meeting-specific data but requires Workspace Enterprise licensing and specific API enablement.

## Before you start

- A Google account or Google Workspace account with Google Calendar access
- Google Calendar API enabled in Google Cloud Console (APIs & Services → Enable APIs → Google Calendar API)
- OAuth 2.0 credentials configured with the https://www.googleapis.com/auth/calendar.readonly scope
- For workspace-wide analytics: a service account with domain-wide delegation enabled to access other users' calendars
- A Retool account with Resource creation permissions

## Step-by-step guide

### 1. Enable Google Calendar API and configure OAuth credentials

Navigate to Google Cloud Console → APIs & Services → Library and search for Google Calendar API. Click Enable if it is not already active. To also enable the beta Google Meet REST API for space management, search for Google Meet API and enable it separately — this is optional for basic meeting data retrieval via Calendar. In APIs & Services → Credentials, click Create Credentials → OAuth client ID. Set the application type to Web application. In Authorized redirect URIs, add Retool's OAuth callback URL: https://oauth.retool.com/oauth/user/oauthcallback for Retool Cloud. Copy the Client ID and Client Secret. Configure the OAuth consent screen: go to APIs & Services → OAuth consent screen, set User Type to Internal for Google Workspace single-organization use, and add the scope https://www.googleapis.com/auth/calendar.readonly. This read-only scope allows listing events and reading attendee data without the risk of accidentally modifying calendar data. If you need to create or modify Meet meetings from Retool, add https://www.googleapis.com/auth/calendar.events instead. Save the consent screen. For organization-wide analytics accessing multiple employees' calendars, configure a service account with domain-wide delegation — in the service account settings, enable domain-wide delegation and add the calendar.readonly scope to the Workspace Admin Console delegated scopes. This is an advanced configuration but required for HR and ops teams that need cross-user calendar visibility.

**Expected result:** Google Calendar API is enabled, OAuth credentials are created with the calendar.readonly scope, and the consent screen is configured for either personal or domain-wide calendar access.

### 2. Create the Google Calendar REST API Resource in Retool

Navigate to the Resources tab in Retool and click Add Resource → REST API. Name the resource Google Calendar API. Set the Base URL to https://www.googleapis.com/calendar/v3. In the Authentication section, select OAuth 2.0. Enter the OAuth configuration: Authorization URL as https://accounts.google.com/o/oauth2/auth, Token URL as https://oauth2.googleapis.com/token, your Client ID, Client Secret, and Scope as https://www.googleapis.com/auth/calendar.readonly. Add access_type: offline in the additional OAuth parameters to receive a refresh token for long-lived access. Save and click Connect to trigger the OAuth authorization flow — a Google sign-in popup appears where you authorize the app with the requested calendar scope. After authorization, the resource shows as Connected with your Google account email. If you need to query multiple users' calendars using domain-wide delegation with a service account, configure the Base URL the same way but authenticate via Bearer token using the service account's access token stored in a configuration variable, similar to the Vertex AI setup. Verify the connection by creating a test query with GET path /users/me/calendarList to list your accessible calendars — this confirms the resource configuration is correct before building the main meeting queries.

**Expected result:** The Google Calendar REST API Resource is Connected in Retool and a test query to /users/me/calendarList returns the list of calendars accessible to the authenticated account.

### 3. Query Google Meet events from Calendar API

Create a new query named getMeetEvents. Select the Google Calendar API resource. Set the HTTP method to GET and the path to /calendars/primary/events. Add the following query parameters to filter and sort results: timeMin set to {{ new Date(Date.now() - 30*24*60*60*1000).toISOString() }} (30 days ago in ISO format), timeMax set to {{ new Date().toISOString() }} (current time), singleEvents set to true (expands recurring events into individual instances), orderBy set to startTime, and maxResults set to 500. Optionally add q: meet to text-search for Meet-specific events, though this is unreliable — instead filter in the transformer. Click Run. The API returns a large JSON response with an items array containing all calendar events in the specified time range. Each event has a conferenceData object when a video conference is attached. For Google Meet events specifically, conferenceData.conferenceSolution.key.type equals hangoutsMeet. Create a JavaScript transformer that filters the items array to only include events with this conference type and extracts the relevant fields: meeting title, start/end times, duration in minutes, organizer email, attendee list with statuses, and the Meet join URL from conferenceData.entryPoints[0].uri.

```
// Transformer: filter and flatten Google Calendar events to Meet meetings
const items = data.items || [];

const meetEvents = items.filter(event => {
  return event.conferenceData &&
    event.conferenceData.conferenceSolution &&
    event.conferenceData.conferenceSolution.key.type === 'hangoutsMeet';
});

return meetEvents.map(event => {
  const start = new Date(event.start.dateTime || event.start.date);
  const end = new Date(event.end.dateTime || event.end.date);
  const durationMin = Math.round((end - start) / 60000);
  
  const meetLink = (event.conferenceData.entryPoints || [])
    .find(ep => ep.entryPointType === 'video');
  
  const acceptedCount = (event.attendees || []).filter(a => a.responseStatus === 'accepted').length;
  const totalCount = (event.attendees || []).length;
  
  return {
    title: event.summary || '(No title)',
    start_time: start.toLocaleString(),
    start_iso: start.toISOString(),
    date: start.toLocaleDateString(),
    duration_min: durationMin,
    organizer: event.organizer?.email || '',
    attendee_count: totalCount,
    accepted_count: acceptedCount,
    meet_url: meetLink?.uri || '',
    conference_id: event.conferenceData.conferenceId || '',
    status: event.status || 'confirmed',
    is_recurring: !!event.recurringEventId
  };
});
```

**Expected result:** The getMeetEvents query returns a filtered list of Google Meet meetings for the specified time range, with each meeting showing title, start time, duration, organizer, attendee count, and a clickable Meet URL.

### 4. Build the meeting load analytics dashboard

Use a JavaScript query to aggregate the Meet event data by attendee for meeting load analysis. Reference getMeetEvents.data in the JavaScript query. Iterate over all meetings, then for each meeting iterate over its attendees array, and accumulate meeting counts and total minutes per attendee email. The result is a dictionary keyed by email with meeting_count and total_minutes values. Convert to an array sorted by total minutes descending for the Table component. Drag a Table component onto the canvas and bind it to this aggregated data. Configure columns: email, meeting_count (labeled Meetings This Month), and total_hours (calculated as total_minutes / 60, formatted to one decimal). Add conditional row formatting to highlight rows where total_hours exceeds a threshold — drag a Number Input component labeled Meeting Hour Threshold and reference its value in the conditional: {{ currentRow.total_hours > meetingThreshold.value }}. Drag a Bar Chart component and bind it to the same aggregated data, setting the X axis to email and Y axis to total_hours. Add a Select dropdown to filter by a specific meeting organizer or team domain. Place a DateRangePicker at the top to control the Calendar API query time range by referencing the picker values in the timeMin and timeMax parameters.

```
// JavaScript query: aggregate meeting load by attendee
const meetings = getMeetEvents.data || [];

const loadMap = {};

meetings.forEach(meeting => {
  // Parse attendee emails from the raw event data (need to map back)
  // This approach works if the transformer includes the attendees array
  const rawEvent = getMeetEventsRaw.data?.items?.find(
    e => e.conferenceData?.conferenceId === meeting.conference_id
  );
  const attendees = rawEvent?.attendees || [];
  
  attendees.forEach(attendee => {
    const email = attendee.email;
    if (!loadMap[email]) {
      loadMap[email] = { email, meeting_count: 0, total_minutes: 0 };
    }
    if (attendee.responseStatus !== 'declined') {
      loadMap[email].meeting_count += 1;
      loadMap[email].total_minutes += meeting.duration_min;
    }
  });
});

return Object.values(loadMap)
  .map(r => ({
    ...r,
    total_hours: (r.total_minutes / 60).toFixed(1)
  }))
  .sort((a, b) => b.total_minutes - a.total_minutes);
```

**Expected result:** A complete meeting analytics dashboard shows a bar chart of meeting hours per person, a sorted table with meeting load statistics, a configurable threshold highlighter, and a date range picker controlling all data.

## Best practices

- Filter Calendar API events in the JavaScript transformer rather than relying on the q (text search) parameter — filtering by conferenceData.conferenceSolution.key.type === 'hangoutsMeet' is more reliable than text search.
- Use the singleEvents=true parameter always when querying for analytics — without it, recurring meetings appear as one entry instead of individual instances, making count and duration calculations incorrect.
- Cache the getMeetEvents query results for 30-60 minutes — Calendar data does not change every second and caching significantly improves dashboard load time for organization-wide queries.
- Store the calendarId (primary or team calendar email) in a Retool configuration variable to make the dashboard reusable across different calendars without modifying query paths.
- Add a meaningful status indicator to the dashboard noting that meeting data reflects Calendar invitations, not actual join confirmation — attendees who join without RSVP acceptance are not tracked by the Calendar API alone.
- For attendance analytics, count only attendees with responseStatus=accepted as confirmed attendees — needsAction, tentative, and declined statuses should be reported separately.
- Combine Calendar API meeting data with your HR database or Slack API data to add team names, departments, and organizational hierarchy to the meeting load analytics.

## Use cases

### Team meeting load dashboard

Build a Retool dashboard that shows how many hours per week each team member spends in Google Meet meetings. Query the Calendar API for all accepted meetings across a team's calendars, filter to Meet events, calculate duration for each, and aggregate by attendee email. Display the results in a sorted Table showing person, meeting count, and total meeting hours per week. A Bar Chart shows the distribution visually, highlighting team members who are above a configurable meeting hour threshold in red using conditional formatting.

Prompt example:

```
Build a Retool dashboard that queries the Google Calendar API for all Google Meet events in the last 30 days for a list of team email addresses, calculates total meeting duration per person, and displays a Table sorted by total meeting hours with a Bar Chart showing the distribution. Highlight rows where weekly meeting hours exceed 15.
```

### Upcoming meetings panel with join links

Create a Retool panel showing all upcoming Google Meet meetings for a user or team calendar in the next 7 days, with one-click join links. The Table shows meeting title, time, duration, organizer, number of attendees, and a clickable Google Meet URL. A secondary panel shows meetings happening today sorted by start time, refreshed every 5 minutes. This serves as an internal meeting room display or a manager's meeting overview panel.

Prompt example:

```
Build a Retool app that queries the Google Calendar API for all events in the next 7 days that have conferenceData of type hangoutsMeet, displays them in a Table with columns for title, start time, duration, organizer, attendee count, and a Link component for the Meet join URL, sorted by start time ascending.
```

### Meeting attendance analytics tracker

Build an attendance analytics dashboard for recurring team meetings. Query the Calendar API for all instances of specific recurring meetings over the last quarter, extracting each attendee's RSVP status (accepted, declined, tentative) from the attendees array. Display attendance rates per person as a heatmap or grouped bar chart. This helps team leads understand participation patterns in recurring syncs and identify meetings with consistently low acceptance rates that might be candidates for cancellation.

Prompt example:

```
Build a Retool app that queries the Google Calendar API for all instances of a recurring Google Meet event over the last 90 days, extracts each attendee's response status from each event, and displays a Table with attendance rate per person (accepted / total invitations). Show a bar chart comparing attendance rates across attendees.
```

## Troubleshooting

### Calendar API returns events but none have conferenceData — Google Meet meetings are not filtered

Cause: Some Google Meet meetings created before the conferenceData field was widely populated may lack the conferenceData structure. Alternatively, the calendar being queried is not the primary calendar where the meetings were created, or the events were created as video calls from a non-Google source.

Solution: Verify the meetings exist in the primary calendar by checking the Google Calendar web interface and confirming the green camera icon is shown. In the transformer filter, also check for hangoutsMeet in event.hangoutLink (an older field) using a fallback: event.conferenceData?.conferenceSolution?.key?.type === 'hangoutsMeet' || !!event.hangoutLink. For team calendars, change the calendarId from primary to the shared team calendar email address.

```
// Expanded Meet meeting filter including hangoutLink fallback
const isMeetEvent = item =>
  (item.conferenceData?.conferenceSolution?.key?.type === 'hangoutsMeet') ||
  (!!item.hangoutLink);
```

### Query returns only 250 events even though there should be more in the date range

Cause: The Google Calendar API default maxResults is 250 and the maximum is 2500 per request. Results beyond this limit require pagination using the nextPageToken field in the response.

Solution: Increase maxResults to 2500 in the query parameters (the API maximum per page). For date ranges with more than 2500 events, implement pagination: check if data.nextPageToken exists in the response, then make a second query with pageToken set to the nextPageToken value. A Retool Workflow loop can handle multi-page results by storing nextPageToken and continuing until it is undefined.

### OAuth authorization works but events from other team members' calendars are not visible

Cause: The authenticated user only has access to their own primary calendar. Accessing other users' calendars requires domain-wide delegation or explicit calendar sharing from each user.

Solution: For workspace-wide analytics, configure a service account with domain-wide delegation in Google Workspace Admin Console → Security → API controls → Domain-wide delegation. Add the service account's client ID and the scope https://www.googleapis.com/auth/calendar.readonly. In Retool queries, impersonate a specific user by adding the sub parameter to the OAuth token request — this allows the service account to query any user's calendar on their behalf.

## Frequently asked questions

### Does Google Meet have its own API separate from Google Calendar?

Yes, but it is limited. Google launched a Google Meet REST API (v2) in beta as part of Google Workspace that manages Meet Spaces — persistent meeting rooms with ongoing conference sessions. The API is at https://meet.googleapis.com/v2/spaces/ and requires the https://www.googleapis.com/auth/meetings.space.readonly or meetings.space.created scope. However, this API does not list historical meetings or provide participant attendance data from past meetings. For historical meeting analytics, the Google Calendar API remains the primary data source since all Meet meetings are Calendar events.

### Can I see who actually joined a Google Meet call (not just who was invited)?

Not through the standard Calendar API — it only shows RSVP statuses (accepted, declined, tentative) from calendar invitations, not actual join events. For actual participant join/leave data, Google Workspace admins can access this through the Reports API (Admin SDK) using the meet activity events endpoint. This requires the https://www.googleapis.com/auth/admin.reports.audit.readonly scope and a Google Workspace Admin account. The Reports API logs Meet activity including join times, durations, and IP addresses for admin-level analytics.

### Can Retool create new Google Meet meetings directly?

Yes, by creating a Google Calendar event with a conferenceDataVersion=1 parameter and a createRequest in the conferenceData field. Send a POST request to /calendars/primary/events with conferenceDataVersion=1 as a query parameter and include conferenceData: { createRequest: { requestId: 'unique-id', conferenceSolutionKey: { type: 'hangoutsMeet' } } } in the event body. Google Calendar API automatically creates a Meet conference and populates the conferenceData field with the join link. This requires the https://www.googleapis.com/auth/calendar.events scope.

### How do I query meetings across an entire team's calendars in Retool?

Query each team member's calendar individually using their email address as the calendarId (replace primary with the user's email). This requires the authenticated account to have access to those calendars — either via explicit calendar sharing (each user shares their calendar with the service account or admin) or via domain-wide delegation with a service account. Run multiple parallel queries in Retool (one per team member) and merge the results in a JavaScript query using a reduce operation to combine all meetings into one aggregated dataset.

---

Source: https://www.rapidevelopers.com/retool-integrations/google-meet
© RapidDev — https://www.rapidevelopers.com/retool-integrations/google-meet
