From 9930a965e99bef11f3bb510918d29fd896c1e31f Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 2 Mar 2026 19:58:28 -0800 Subject: [PATCH 1/3] feat(integrations): add google meet integration --- apps/docs/components/icons.tsx | 16 ++ apps/docs/components/ui/icon-mapping.ts | 14 +- .../content/docs/en/tools/google_meet.mdx | 155 +++++++++++++++ apps/docs/content/docs/en/tools/meta.json | 3 +- .../components/oauth-required-modal.tsx | 4 + apps/sim/blocks/blocks/google_meet.ts | 182 ++++++++++++++++++ apps/sim/blocks/registry.ts | 2 + apps/sim/components/icons.tsx | 16 ++ apps/sim/lib/auth/auth.ts | 42 ++++ apps/sim/lib/oauth/oauth.ts | 12 ++ apps/sim/lib/oauth/types.ts | 2 + apps/sim/tools/google_meet/create_space.ts | 92 +++++++++ apps/sim/tools/google_meet/end_conference.ts | 69 +++++++ .../google_meet/get_conference_record.ts | 78 ++++++++ apps/sim/tools/google_meet/get_space.ts | 77 ++++++++ apps/sim/tools/google_meet/index.ts | 13 ++ .../google_meet/list_conference_records.ts | 97 ++++++++++ .../tools/google_meet/list_participants.ts | 123 ++++++++++++ apps/sim/tools/google_meet/types.ts | 165 ++++++++++++++++ apps/sim/tools/registry.ts | 14 ++ 20 files changed, 1169 insertions(+), 7 deletions(-) create mode 100644 apps/docs/content/docs/en/tools/google_meet.mdx create mode 100644 apps/sim/blocks/blocks/google_meet.ts create mode 100644 apps/sim/tools/google_meet/create_space.ts create mode 100644 apps/sim/tools/google_meet/end_conference.ts create mode 100644 apps/sim/tools/google_meet/get_conference_record.ts create mode 100644 apps/sim/tools/google_meet/get_space.ts create mode 100644 apps/sim/tools/google_meet/index.ts create mode 100644 apps/sim/tools/google_meet/list_conference_records.ts create mode 100644 apps/sim/tools/google_meet/list_participants.ts create mode 100644 apps/sim/tools/google_meet/types.ts diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index bacfe1e7fcc..6e8d1b46508 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -4796,6 +4796,22 @@ export function GoogleGroupsIcon(props: SVGProps) { ) } +export function GoogleMeetIcon(props: SVGProps) { + return ( + + + + + + + + + ) +} + export function CursorIcon(props: SVGProps) { return ( diff --git a/apps/docs/components/ui/icon-mapping.ts b/apps/docs/components/ui/icon-mapping.ts index 1e373d07d3e..0db6bac0711 100644 --- a/apps/docs/components/ui/icon-mapping.ts +++ b/apps/docs/components/ui/icon-mapping.ts @@ -44,8 +44,8 @@ import { FirecrawlIcon, FirefliesIcon, GammaIcon, - GithubIcon, GitLabIcon, + GithubIcon, GmailIcon, GongIcon, GoogleBigQueryIcon, @@ -58,6 +58,7 @@ import { GoogleGroupsIcon, GoogleIcon, GoogleMapsIcon, + GoogleMeetIcon, GooglePagespeedIcon, GoogleSheetsIcon, GoogleSlidesIcon, @@ -86,9 +87,9 @@ import { LinkupIcon, LoopsIcon, LumaIcon, + MailServerIcon, MailchimpIcon, MailgunIcon, - MailServerIcon, Mem0Icon, MicrosoftDataverseIcon, MicrosoftExcelIcon, @@ -122,6 +123,8 @@ import { ResendIcon, RevenueCatIcon, S3Icon, + SQSIcon, + STTIcon, SalesforceIcon, SearchIcon, SendgridIcon, @@ -133,19 +136,17 @@ import { SimilarwebIcon, SlackIcon, SmtpIcon, - SQSIcon, SshIcon, - STTIcon, StagehandIcon, StripeIcon, SupabaseIcon, + TTSIcon, TavilyIcon, TelegramIcon, TextractIcon, TinybirdIcon, TranslateIcon, TrelloIcon, - TTSIcon, TwilioIcon, TypeformIcon, UpstashIcon, @@ -156,11 +157,11 @@ import { WhatsAppIcon, WikipediaIcon, WordpressIcon, - xIcon, YouTubeIcon, ZendeskIcon, ZepIcon, ZoomIcon, + xIcon, } from '@/components/icons' type IconComponent = ComponentType> @@ -217,6 +218,7 @@ export const blockTypeToIconMap: Record = { google_forms: GoogleFormsIcon, google_groups: GoogleGroupsIcon, google_maps: GoogleMapsIcon, + google_meet: GoogleMeetIcon, google_pagespeed: GooglePagespeedIcon, google_search: GoogleIcon, google_sheets_v2: GoogleSheetsIcon, diff --git a/apps/docs/content/docs/en/tools/google_meet.mdx b/apps/docs/content/docs/en/tools/google_meet.mdx new file mode 100644 index 00000000000..e117678f2b0 --- /dev/null +++ b/apps/docs/content/docs/en/tools/google_meet.mdx @@ -0,0 +1,155 @@ +--- +title: Google Meet +description: Create and manage Google Meet meetings +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +{/* MANUAL-CONTENT-START:intro */} +[Google Meet](https://meet.google.com) is Google's video conferencing and online meeting platform, providing secure, high-quality video calls for individuals and teams. As a core component of Google Workspace, Google Meet enables real-time collaboration through video meetings, screen sharing, and integrated chat. + +The Google Meet REST API (v2) allows programmatic management of meeting spaces and conference records, enabling automated workflows to create meetings, track participation, and manage active conferences without manual intervention. + +Key features of the Google Meet API include: + +- **Meeting Space Management**: Create, retrieve, and configure meeting spaces with customizable access controls. +- **Conference Records**: Access historical conference data including start/end times and associated spaces. +- **Participant Tracking**: View participant details for any conference including join/leave times and user types. +- **Access Controls**: Configure who can join meetings (open, trusted, or restricted) and which entry points are allowed. +- **Active Conference Management**: Programmatically end active conferences in meeting spaces. + +In Sim, the Google Meet integration allows your agents to create meeting spaces on demand, monitor conference activity, track participation across meetings, and manage active conferences as part of automated workflows. This enables scenarios such as automatically provisioning meeting rooms for scheduled events, generating attendance reports, ending stale conferences, and building meeting analytics dashboards. +{/* MANUAL-CONTENT-END */} + +## Usage Instructions + +Integrate Google Meet into your workflow. Create meeting spaces, get space details, end conferences, list conference records, and view participants. + + + +## Tools + +### `google_meet_create_space` + +Create a new Google Meet meeting space + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accessType` | string | No | Who can join the meeting without knocking: OPEN \(anyone with link\), TRUSTED \(org members\), RESTRICTED \(only invited\) | +| `entryPointAccess` | string | No | Entry points allowed: ALL \(all entry points\) or CREATOR_APP_ONLY \(only via app\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `name` | string | Resource name of the space \(e.g., spaces/abc123\) | +| `meetingUri` | string | Meeting URL \(e.g., https://meet.google.com/abc-defg-hij\) | +| `meetingCode` | string | Meeting code \(e.g., abc-defg-hij\) | +| `accessType` | string | Access type configuration | +| `entryPointAccess` | string | Entry point access configuration | + +### `google_meet_get_space` + +Get details of a Google Meet meeting space by name or meeting code + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `spaceName` | string | Yes | Space resource name \(spaces/abc123\) or meeting code \(abc-defg-hij\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `name` | string | Resource name of the space | +| `meetingUri` | string | Meeting URL | +| `meetingCode` | string | Meeting code | +| `accessType` | string | Access type configuration | +| `entryPointAccess` | string | Entry point access configuration | +| `activeConference` | string | Active conference record name | + +### `google_meet_end_conference` + +End the active conference in a Google Meet space + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `spaceName` | string | Yes | Space resource name \(e.g., spaces/abc123\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `ended` | boolean | Whether the conference was ended successfully | + +### `google_meet_list_conference_records` + +List conference records for meetings you organized + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `filter` | string | No | Filter by space name \(e.g., space.name = "spaces/abc123"\) or time range \(e.g., start_time > "2024-01-01T00:00:00Z"\) | +| `pageSize` | number | No | Maximum number of conference records to return \(max 100\) | +| `pageToken` | string | No | Page token from a previous list request | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `conferenceRecords` | json | List of conference records with name, start/end times, and space | +| `nextPageToken` | string | Token for next page of results | + +### `google_meet_get_conference_record` + +Get details of a specific conference record + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `conferenceName` | string | Yes | Conference record resource name \(e.g., conferenceRecords/abc123\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `name` | string | Conference record resource name | +| `startTime` | string | Conference start time | +| `endTime` | string | Conference end time | +| `expireTime` | string | Conference record expiration time | +| `space` | string | Associated space resource name | + +### `google_meet_list_participants` + +List participants of a conference record + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `conferenceName` | string | Yes | Conference record resource name \(e.g., conferenceRecords/abc123\) | +| `filter` | string | No | Filter participants \(e.g., earliest_start_time > "2024-01-01T00:00:00Z"\) | +| `pageSize` | number | No | Maximum number of participants to return \(default 100, max 250\) | +| `pageToken` | string | No | Page token from a previous list request | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `participants` | json | List of participants with name, times, display name, and user type | +| `nextPageToken` | string | Token for next page of results | +| `totalSize` | number | Total number of participants | + + diff --git a/apps/docs/content/docs/en/tools/meta.json b/apps/docs/content/docs/en/tools/meta.json index ff5cd4247cf..92ac008c319 100644 --- a/apps/docs/content/docs/en/tools/meta.json +++ b/apps/docs/content/docs/en/tools/meta.json @@ -52,6 +52,7 @@ "google_forms", "google_groups", "google_maps", + "google_meet", "google_pagespeed", "google_search", "google_sheets", @@ -161,4 +162,4 @@ "zep", "zoom" ] -} +} \ No newline at end of file diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/components/oauth-required-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/components/oauth-required-modal.tsx index c2ebf9b68be..9aa2451e37b 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/components/oauth-required-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/components/oauth-required-modal.tsx @@ -55,6 +55,10 @@ const SCOPE_DESCRIPTIONS: Record = { 'https://www.googleapis.com/auth/admin.directory.group.readonly': 'View Google Workspace groups', 'https://www.googleapis.com/auth/admin.directory.group.member.readonly': 'View Google Workspace group memberships', + 'https://www.googleapis.com/auth/meetings.space.created': + 'Create and manage Google Meet meeting spaces', + 'https://www.googleapis.com/auth/meetings.space.readonly': + 'View Google Meet meeting space details', 'https://www.googleapis.com/auth/cloud-platform': 'Full access to Google Cloud resources for Vertex AI', 'read:confluence-content.all': 'Read all Confluence content', diff --git a/apps/sim/blocks/blocks/google_meet.ts b/apps/sim/blocks/blocks/google_meet.ts new file mode 100644 index 00000000000..b0524788dc8 --- /dev/null +++ b/apps/sim/blocks/blocks/google_meet.ts @@ -0,0 +1,182 @@ +import { GoogleMeetIcon } from '@/components/icons' +import type { BlockConfig } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' +import type { GoogleMeetResponse } from '@/tools/google_meet/types' + +export const GoogleMeetBlock: BlockConfig = { + type: 'google_meet', + name: 'Google Meet', + description: 'Create and manage Google Meet meetings', + longDescription: + 'Integrate Google Meet into your workflow. Create meeting spaces, get space details, end conferences, list conference records, and view participants.', + docsLink: 'https://docs.sim.ai/tools/google_meet', + category: 'tools', + bgColor: '#E0E0E0', + icon: GoogleMeetIcon, + authMode: AuthMode.OAuth, + subBlocks: [ + { + id: 'operation', + title: 'Operation', + type: 'dropdown', + options: [ + { label: 'Create Space', id: 'create_space' }, + { label: 'Get Space', id: 'get_space' }, + { label: 'End Conference', id: 'end_conference' }, + { label: 'List Conference Records', id: 'list_conference_records' }, + { label: 'Get Conference Record', id: 'get_conference_record' }, + { label: 'List Participants', id: 'list_participants' }, + ], + value: () => 'create_space', + }, + { + id: 'credential', + title: 'Google Meet Account', + type: 'oauth-input', + canonicalParamId: 'oauthCredential', + mode: 'basic', + required: true, + serviceId: 'google-meet', + requiredScopes: [ + 'https://www.googleapis.com/auth/meetings.space.created', + 'https://www.googleapis.com/auth/meetings.space.readonly', + ], + placeholder: 'Select Google Meet account', + }, + { + id: 'manualCredential', + title: 'Google Meet Account', + type: 'short-input', + canonicalParamId: 'oauthCredential', + mode: 'advanced', + placeholder: 'Enter credential ID', + required: true, + }, + + // Create Space Fields + { + id: 'accessType', + title: 'Access Type', + type: 'dropdown', + condition: { field: 'operation', value: 'create_space' }, + options: [ + { label: 'Open (anyone with link)', id: 'OPEN' }, + { label: 'Trusted (organization members)', id: 'TRUSTED' }, + { label: 'Restricted (invited only)', id: 'RESTRICTED' }, + ], + }, + { + id: 'entryPointAccess', + title: 'Entry Point Access', + type: 'dropdown', + condition: { field: 'operation', value: 'create_space' }, + mode: 'advanced', + options: [ + { label: 'All entry points', id: 'ALL' }, + { label: 'Creator app only', id: 'CREATOR_APP_ONLY' }, + ], + }, + + // Get Space / End Conference Fields + { + id: 'spaceName', + title: 'Space Name or Meeting Code', + type: 'short-input', + placeholder: 'spaces/abc123 or abc-defg-hij', + condition: { field: 'operation', value: ['get_space', 'end_conference'] }, + required: { field: 'operation', value: ['get_space', 'end_conference'] }, + }, + + // Conference Record Fields + { + id: 'conferenceName', + title: 'Conference Record Name', + type: 'short-input', + placeholder: 'conferenceRecords/abc123', + condition: { field: 'operation', value: ['get_conference_record', 'list_participants'] }, + required: { field: 'operation', value: ['get_conference_record', 'list_participants'] }, + }, + + // List Conference Records Fields + { + id: 'filter', + title: 'Filter', + type: 'short-input', + placeholder: 'space.name = "spaces/abc123"', + condition: { field: 'operation', value: ['list_conference_records', 'list_participants'] }, + mode: 'advanced', + }, + { + id: 'pageSize', + title: 'Page Size', + type: 'short-input', + placeholder: '25', + condition: { field: 'operation', value: ['list_conference_records', 'list_participants'] }, + mode: 'advanced', + }, + { + id: 'pageToken', + title: 'Page Token', + type: 'short-input', + placeholder: 'Token from previous request', + condition: { field: 'operation', value: ['list_conference_records', 'list_participants'] }, + mode: 'advanced', + }, + ], + tools: { + access: [ + 'google_meet_create_space', + 'google_meet_get_space', + 'google_meet_end_conference', + 'google_meet_list_conference_records', + 'google_meet_get_conference_record', + 'google_meet_list_participants', + ], + config: { + tool: (params) => `google_meet_${params.operation}`, + params: (params) => { + const { oauthCredential, operation, pageSize, ...rest } = params + + const processedParams: Record = { ...rest } + + if (pageSize) { + processedParams.pageSize = + typeof pageSize === 'string' ? Number.parseInt(pageSize, 10) : pageSize + } + + return { + oauthCredential, + ...processedParams, + } + }, + }, + }, + inputs: { + operation: { type: 'string', description: 'Operation to perform' }, + oauthCredential: { type: 'string', description: 'Google Meet access token' }, + accessType: { type: 'string', description: 'Access type for meeting space' }, + entryPointAccess: { type: 'string', description: 'Entry point access setting' }, + spaceName: { type: 'string', description: 'Space resource name or meeting code' }, + conferenceName: { type: 'string', description: 'Conference record resource name' }, + filter: { type: 'string', description: 'Filter expression' }, + pageSize: { type: 'string', description: 'Maximum results per page' }, + pageToken: { type: 'string', description: 'Pagination token' }, + }, + outputs: { + name: { type: 'string', description: 'Resource name' }, + meetingUri: { type: 'string', description: 'Meeting URL' }, + meetingCode: { type: 'string', description: 'Meeting code' }, + accessType: { type: 'string', description: 'Access type' }, + entryPointAccess: { type: 'string', description: 'Entry point access' }, + activeConference: { type: 'string', description: 'Active conference record' }, + ended: { type: 'boolean', description: 'Whether conference was ended' }, + conferenceRecords: { type: 'json', description: 'List of conference records' }, + startTime: { type: 'string', description: 'Conference start time' }, + endTime: { type: 'string', description: 'Conference end time' }, + expireTime: { type: 'string', description: 'Record expiration time' }, + space: { type: 'string', description: 'Associated space name' }, + participants: { type: 'json', description: 'List of participants' }, + nextPageToken: { type: 'string', description: 'Next page token' }, + totalSize: { type: 'number', description: 'Total participant count' }, + }, +} diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index 1794fb5afcc..fd3103e7fd8 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -57,6 +57,7 @@ import { GoogleDocsBlock } from '@/blocks/blocks/google_docs' import { GoogleDriveBlock } from '@/blocks/blocks/google_drive' import { GoogleFormsBlock } from '@/blocks/blocks/google_forms' import { GoogleGroupsBlock } from '@/blocks/blocks/google_groups' +import { GoogleMeetBlock } from '@/blocks/blocks/google_meet' import { GoogleMapsBlock } from '@/blocks/blocks/google_maps' import { GooglePagespeedBlock } from '@/blocks/blocks/google_pagespeed' import { GoogleSheetsBlock, GoogleSheetsV2Block } from '@/blocks/blocks/google_sheets' @@ -255,6 +256,7 @@ export const registry: Record = { google_drive: GoogleDriveBlock, google_forms: GoogleFormsBlock, google_groups: GoogleGroupsBlock, + google_meet: GoogleMeetBlock, google_maps: GoogleMapsBlock, google_pagespeed: GooglePagespeedBlock, google_tasks: GoogleTasksBlock, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index bacfe1e7fcc..6e8d1b46508 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -4796,6 +4796,22 @@ export function GoogleGroupsIcon(props: SVGProps) { ) } +export function GoogleMeetIcon(props: SVGProps) { + return ( + + + + + + + + + ) +} + export function CursorIcon(props: SVGProps) { return ( diff --git a/apps/sim/lib/auth/auth.ts b/apps/sim/lib/auth/auth.ts index 87beefef88b..17fa684c324 100644 --- a/apps/sim/lib/auth/auth.ts +++ b/apps/sim/lib/auth/auth.ts @@ -488,6 +488,7 @@ export const auth = betterAuth({ 'google-bigquery', 'google-vault', 'google-groups', + 'google-meet', 'google-tasks', 'vertex-ai', 'github-repo', @@ -1243,6 +1244,47 @@ export const auth = betterAuth({ }, }, + { + providerId: 'google-meet', + clientId: env.GOOGLE_CLIENT_ID as string, + clientSecret: env.GOOGLE_CLIENT_SECRET as string, + discoveryUrl: 'https://accounts.google.com/.well-known/openid-configuration', + accessType: 'offline', + scopes: [ + 'https://www.googleapis.com/auth/userinfo.email', + 'https://www.googleapis.com/auth/userinfo.profile', + 'https://www.googleapis.com/auth/meetings.space.created', + 'https://www.googleapis.com/auth/meetings.space.readonly', + ], + prompt: 'consent', + redirectURI: `${getBaseUrl()}/api/auth/oauth2/callback/google-meet`, + getUserInfo: async (tokens) => { + try { + const response = await fetch('https://openidconnect.googleapis.com/v1/userinfo', { + headers: { Authorization: `Bearer ${tokens.accessToken}` }, + }) + if (!response.ok) { + await response.text().catch(() => {}) + logger.error('Failed to fetch Google user info', { status: response.status }) + throw new Error(`Failed to fetch Google user info: ${response.statusText}`) + } + const profile = await response.json() + const now = new Date() + return { + id: `${profile.sub}-${crypto.randomUUID()}`, + name: profile.name || 'Google User', + email: profile.email, + image: profile.picture || undefined, + emailVerified: profile.email_verified || false, + createdAt: now, + updatedAt: now, + } + } catch (error) { + logger.error('Error in Google getUserInfo', { error }) + throw error + } + }, + }, { providerId: 'google-tasks', clientId: env.GOOGLE_CLIENT_ID as string, diff --git a/apps/sim/lib/oauth/oauth.ts b/apps/sim/lib/oauth/oauth.ts index 652269afcba..2cb5f1f1156 100644 --- a/apps/sim/lib/oauth/oauth.ts +++ b/apps/sim/lib/oauth/oauth.ts @@ -16,6 +16,7 @@ import { GoogleFormsIcon, GoogleGroupsIcon, GoogleIcon, + GoogleMeetIcon, GoogleSheetsIcon, GoogleTasksIcon, HubspotIcon, @@ -168,6 +169,17 @@ export const OAUTH_PROVIDERS: Record = { 'https://www.googleapis.com/auth/admin.directory.group.member', ], }, + 'google-meet': { + name: 'Google Meet', + description: 'Create and manage Google Meet meeting spaces and conferences.', + providerId: 'google-meet', + icon: GoogleMeetIcon, + baseProviderIcon: GoogleIcon, + scopes: [ + 'https://www.googleapis.com/auth/meetings.space.created', + 'https://www.googleapis.com/auth/meetings.space.readonly', + ], + }, 'vertex-ai': { name: 'Vertex AI', description: 'Access Google Cloud Vertex AI for Gemini models with OAuth.', diff --git a/apps/sim/lib/oauth/types.ts b/apps/sim/lib/oauth/types.ts index 2297c5df300..23cfb721630 100644 --- a/apps/sim/lib/oauth/types.ts +++ b/apps/sim/lib/oauth/types.ts @@ -13,6 +13,7 @@ export type OAuthProvider = | 'google-vault' | 'google-forms' | 'google-groups' + | 'google-meet' | 'vertex-ai' | 'github' | 'github-repo' @@ -61,6 +62,7 @@ export type OAuthService = | 'google-vault' | 'google-forms' | 'google-groups' + | 'google-meet' | 'vertex-ai' | 'github' | 'x' diff --git a/apps/sim/tools/google_meet/create_space.ts b/apps/sim/tools/google_meet/create_space.ts new file mode 100644 index 00000000000..48b36d7680d --- /dev/null +++ b/apps/sim/tools/google_meet/create_space.ts @@ -0,0 +1,92 @@ +import { + MEET_API_BASE, + type GoogleMeetApiSpaceResponse, + type GoogleMeetCreateSpaceParams, + type GoogleMeetCreateSpaceResponse, +} from '@/tools/google_meet/types' +import type { ToolConfig } from '@/tools/types' + +export const createSpaceTool: ToolConfig< + GoogleMeetCreateSpaceParams, + GoogleMeetCreateSpaceResponse +> = { + id: 'google_meet_create_space', + name: 'Google Meet Create Space', + description: 'Create a new Google Meet meeting space', + version: '1.0.0', + + oauth: { + required: true, + provider: 'google-meet', + }, + + params: { + accessToken: { + type: 'string', + required: true, + visibility: 'hidden', + description: 'Access token for Google Meet API', + }, + accessType: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Who can join the meeting without knocking: OPEN (anyone with link), TRUSTED (org members), RESTRICTED (only invited)', + }, + entryPointAccess: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Entry points allowed: ALL (all entry points) or CREATOR_APP_ONLY (only via app)', + }, + }, + + request: { + url: () => `${MEET_API_BASE}/spaces`, + method: 'POST', + headers: (params: GoogleMeetCreateSpaceParams) => ({ + Authorization: `Bearer ${params.accessToken}`, + 'Content-Type': 'application/json', + }), + body: (params: GoogleMeetCreateSpaceParams) => { + const body: Record = {} + + if (params.accessType || params.entryPointAccess) { + const config: Record = {} + if (params.accessType) config.accessType = params.accessType + if (params.entryPointAccess) config.entryPointAccess = params.entryPointAccess + body.config = config + } + + return body + }, + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const error = await response.text().catch(() => 'Unknown error') + throw new Error(`Google Meet API error (${response.status}): ${error}`) + } + const data: GoogleMeetApiSpaceResponse = await response.json() + + return { + success: true, + output: { + name: data.name, + meetingUri: data.meetingUri, + meetingCode: data.meetingCode, + accessType: data.config?.accessType ?? null, + entryPointAccess: data.config?.entryPointAccess ?? null, + }, + } + }, + + outputs: { + name: { type: 'string', description: 'Resource name of the space (e.g., spaces/abc123)' }, + meetingUri: { type: 'string', description: 'Meeting URL (e.g., https://meet.google.com/abc-defg-hij)' }, + meetingCode: { type: 'string', description: 'Meeting code (e.g., abc-defg-hij)' }, + accessType: { type: 'string', description: 'Access type configuration', optional: true }, + entryPointAccess: { type: 'string', description: 'Entry point access configuration', optional: true }, + }, +} diff --git a/apps/sim/tools/google_meet/end_conference.ts b/apps/sim/tools/google_meet/end_conference.ts new file mode 100644 index 00000000000..d7d38f9e6af --- /dev/null +++ b/apps/sim/tools/google_meet/end_conference.ts @@ -0,0 +1,69 @@ +import { + MEET_API_BASE, + type GoogleMeetEndConferenceParams, + type GoogleMeetEndConferenceResponse, +} from '@/tools/google_meet/types' +import type { ToolConfig } from '@/tools/types' + +export const endConferenceTool: ToolConfig< + GoogleMeetEndConferenceParams, + GoogleMeetEndConferenceResponse +> = { + id: 'google_meet_end_conference', + name: 'Google Meet End Conference', + description: 'End the active conference in a Google Meet space', + version: '1.0.0', + + oauth: { + required: true, + provider: 'google-meet', + }, + + params: { + accessToken: { + type: 'string', + required: true, + visibility: 'hidden', + description: 'Access token for Google Meet API', + }, + spaceName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Space resource name (e.g., spaces/abc123)', + }, + }, + + request: { + url: (params: GoogleMeetEndConferenceParams) => { + const trimmed = params.spaceName.trim() + const name = trimmed.startsWith('spaces/') + ? trimmed + : `spaces/${trimmed}` + return `${MEET_API_BASE}/${name}:endActiveConference` + }, + method: 'POST', + headers: (params: GoogleMeetEndConferenceParams) => ({ + Authorization: `Bearer ${params.accessToken}`, + 'Content-Type': 'application/json', + }), + body: () => ({}), + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const error = await response.text().catch(() => 'Unknown error') + throw new Error(`Google Meet API error (${response.status}): ${error}`) + } + return { + success: true, + output: { + ended: true, + }, + } + }, + + outputs: { + ended: { type: 'boolean', description: 'Whether the conference was ended successfully' }, + }, +} diff --git a/apps/sim/tools/google_meet/get_conference_record.ts b/apps/sim/tools/google_meet/get_conference_record.ts new file mode 100644 index 00000000000..24a81431a05 --- /dev/null +++ b/apps/sim/tools/google_meet/get_conference_record.ts @@ -0,0 +1,78 @@ +import { + MEET_API_BASE, + type GoogleMeetApiConferenceRecordResponse, + type GoogleMeetGetConferenceRecordParams, + type GoogleMeetGetConferenceRecordResponse, +} from '@/tools/google_meet/types' +import type { ToolConfig } from '@/tools/types' + +export const getConferenceRecordTool: ToolConfig< + GoogleMeetGetConferenceRecordParams, + GoogleMeetGetConferenceRecordResponse +> = { + id: 'google_meet_get_conference_record', + name: 'Google Meet Get Conference Record', + description: 'Get details of a specific conference record', + version: '1.0.0', + + oauth: { + required: true, + provider: 'google-meet', + }, + + params: { + accessToken: { + type: 'string', + required: true, + visibility: 'hidden', + description: 'Access token for Google Meet API', + }, + conferenceName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Conference record resource name (e.g., conferenceRecords/abc123)', + }, + }, + + request: { + url: (params: GoogleMeetGetConferenceRecordParams) => { + const trimmed = params.conferenceName.trim() + const name = trimmed.startsWith('conferenceRecords/') + ? trimmed + : `conferenceRecords/${trimmed}` + return `${MEET_API_BASE}/${name}` + }, + method: 'GET', + headers: (params: GoogleMeetGetConferenceRecordParams) => ({ + Authorization: `Bearer ${params.accessToken}`, + }), + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const error = await response.text().catch(() => 'Unknown error') + throw new Error(`Google Meet API error (${response.status}): ${error}`) + } + const data: GoogleMeetApiConferenceRecordResponse = await response.json() + + return { + success: true, + output: { + name: data.name, + startTime: data.startTime, + endTime: data.endTime ?? null, + expireTime: data.expireTime, + space: data.space, + }, + } + }, + + outputs: { + name: { type: 'string', description: 'Conference record resource name' }, + startTime: { type: 'string', description: 'Conference start time' }, + endTime: { type: 'string', description: 'Conference end time', optional: true }, + expireTime: { type: 'string', description: 'Conference record expiration time' }, + space: { type: 'string', description: 'Associated space resource name' }, + }, +} diff --git a/apps/sim/tools/google_meet/get_space.ts b/apps/sim/tools/google_meet/get_space.ts new file mode 100644 index 00000000000..559dae5c65b --- /dev/null +++ b/apps/sim/tools/google_meet/get_space.ts @@ -0,0 +1,77 @@ +import { + MEET_API_BASE, + type GoogleMeetApiSpaceResponse, + type GoogleMeetGetSpaceParams, + type GoogleMeetGetSpaceResponse, +} from '@/tools/google_meet/types' +import type { ToolConfig } from '@/tools/types' + +export const getSpaceTool: ToolConfig = { + id: 'google_meet_get_space', + name: 'Google Meet Get Space', + description: 'Get details of a Google Meet meeting space by name or meeting code', + version: '1.0.0', + + oauth: { + required: true, + provider: 'google-meet', + }, + + params: { + accessToken: { + type: 'string', + required: true, + visibility: 'hidden', + description: 'Access token for Google Meet API', + }, + spaceName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Space resource name (spaces/abc123) or meeting code (abc-defg-hij)', + }, + }, + + request: { + url: (params: GoogleMeetGetSpaceParams) => { + const trimmed = params.spaceName.trim() + const name = trimmed.startsWith('spaces/') + ? trimmed + : `spaces/${trimmed}` + return `${MEET_API_BASE}/${name}` + }, + method: 'GET', + headers: (params: GoogleMeetGetSpaceParams) => ({ + Authorization: `Bearer ${params.accessToken}`, + }), + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const error = await response.text().catch(() => 'Unknown error') + throw new Error(`Google Meet API error (${response.status}): ${error}`) + } + const data: GoogleMeetApiSpaceResponse = await response.json() + + return { + success: true, + output: { + name: data.name, + meetingUri: data.meetingUri, + meetingCode: data.meetingCode, + accessType: data.config?.accessType ?? null, + entryPointAccess: data.config?.entryPointAccess ?? null, + activeConference: data.activeConference?.conferenceRecord ?? null, + }, + } + }, + + outputs: { + name: { type: 'string', description: 'Resource name of the space' }, + meetingUri: { type: 'string', description: 'Meeting URL' }, + meetingCode: { type: 'string', description: 'Meeting code' }, + accessType: { type: 'string', description: 'Access type configuration', optional: true }, + entryPointAccess: { type: 'string', description: 'Entry point access configuration', optional: true }, + activeConference: { type: 'string', description: 'Active conference record name', optional: true }, + }, +} diff --git a/apps/sim/tools/google_meet/index.ts b/apps/sim/tools/google_meet/index.ts new file mode 100644 index 00000000000..cb091cfd40b --- /dev/null +++ b/apps/sim/tools/google_meet/index.ts @@ -0,0 +1,13 @@ +import { createSpaceTool } from '@/tools/google_meet/create_space' +import { endConferenceTool } from '@/tools/google_meet/end_conference' +import { getConferenceRecordTool } from '@/tools/google_meet/get_conference_record' +import { getSpaceTool } from '@/tools/google_meet/get_space' +import { listConferenceRecordsTool } from '@/tools/google_meet/list_conference_records' +import { listParticipantsTool } from '@/tools/google_meet/list_participants' + +export const googleMeetCreateSpaceTool = createSpaceTool +export const googleMeetGetSpaceTool = getSpaceTool +export const googleMeetEndConferenceTool = endConferenceTool +export const googleMeetListConferenceRecordsTool = listConferenceRecordsTool +export const googleMeetGetConferenceRecordTool = getConferenceRecordTool +export const googleMeetListParticipantsTool = listParticipantsTool diff --git a/apps/sim/tools/google_meet/list_conference_records.ts b/apps/sim/tools/google_meet/list_conference_records.ts new file mode 100644 index 00000000000..1bb0f7ed236 --- /dev/null +++ b/apps/sim/tools/google_meet/list_conference_records.ts @@ -0,0 +1,97 @@ +import { + MEET_API_BASE, + type GoogleMeetApiConferenceRecordListResponse, + type GoogleMeetListConferenceRecordsParams, + type GoogleMeetListConferenceRecordsResponse, +} from '@/tools/google_meet/types' +import type { ToolConfig } from '@/tools/types' + +export const listConferenceRecordsTool: ToolConfig< + GoogleMeetListConferenceRecordsParams, + GoogleMeetListConferenceRecordsResponse +> = { + id: 'google_meet_list_conference_records', + name: 'Google Meet List Conference Records', + description: 'List conference records for meetings you organized', + version: '1.0.0', + + oauth: { + required: true, + provider: 'google-meet', + }, + + params: { + accessToken: { + type: 'string', + required: true, + visibility: 'hidden', + description: 'Access token for Google Meet API', + }, + filter: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Filter by space name (e.g., space.name = "spaces/abc123") or time range (e.g., start_time > "2024-01-01T00:00:00Z")', + }, + pageSize: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of conference records to return (max 100)', + }, + pageToken: { + type: 'string', + required: false, + visibility: 'hidden', + description: 'Page token from a previous list request', + }, + }, + + request: { + url: (params: GoogleMeetListConferenceRecordsParams) => { + const queryParams = new URLSearchParams() + if (params.filter) queryParams.append('filter', params.filter) + if (params.pageSize) queryParams.append('pageSize', params.pageSize.toString()) + if (params.pageToken) queryParams.append('pageToken', params.pageToken) + + const queryString = queryParams.toString() + return `${MEET_API_BASE}/conferenceRecords${queryString ? `?${queryString}` : ''}` + }, + method: 'GET', + headers: (params: GoogleMeetListConferenceRecordsParams) => ({ + Authorization: `Bearer ${params.accessToken}`, + }), + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const error = await response.text().catch(() => 'Unknown error') + throw new Error(`Google Meet API error (${response.status}): ${error}`) + } + const data: GoogleMeetApiConferenceRecordListResponse = await response.json() + const records = data.conferenceRecords ?? [] + + return { + success: true, + output: { + conferenceRecords: records.map((record) => ({ + name: record.name, + startTime: record.startTime, + endTime: record.endTime ?? null, + expireTime: record.expireTime, + space: record.space, + })), + nextPageToken: data.nextPageToken ?? null, + }, + } + }, + + outputs: { + conferenceRecords: { + type: 'json', + description: 'List of conference records with name, start/end times, and space', + }, + nextPageToken: { type: 'string', description: 'Token for next page of results', optional: true }, + }, +} diff --git a/apps/sim/tools/google_meet/list_participants.ts b/apps/sim/tools/google_meet/list_participants.ts new file mode 100644 index 00000000000..f8a990d2f61 --- /dev/null +++ b/apps/sim/tools/google_meet/list_participants.ts @@ -0,0 +1,123 @@ +import { + MEET_API_BASE, + type GoogleMeetApiParticipantListResponse, + type GoogleMeetApiParticipantResponse, + type GoogleMeetListParticipantsParams, + type GoogleMeetListParticipantsResponse, +} from '@/tools/google_meet/types' +import type { ToolConfig } from '@/tools/types' + +export const listParticipantsTool: ToolConfig< + GoogleMeetListParticipantsParams, + GoogleMeetListParticipantsResponse +> = { + id: 'google_meet_list_participants', + name: 'Google Meet List Participants', + description: 'List participants of a conference record', + version: '1.0.0', + + oauth: { + required: true, + provider: 'google-meet', + }, + + params: { + accessToken: { + type: 'string', + required: true, + visibility: 'hidden', + description: 'Access token for Google Meet API', + }, + conferenceName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Conference record resource name (e.g., conferenceRecords/abc123)', + }, + filter: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Filter participants (e.g., earliest_start_time > "2024-01-01T00:00:00Z")', + }, + pageSize: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of participants to return (default 100, max 250)', + }, + pageToken: { + type: 'string', + required: false, + visibility: 'hidden', + description: 'Page token from a previous list request', + }, + }, + + request: { + url: (params: GoogleMeetListParticipantsParams) => { + const trimmed = params.conferenceName.trim() + const name = trimmed.startsWith('conferenceRecords/') + ? trimmed + : `conferenceRecords/${trimmed}` + + const queryParams = new URLSearchParams() + if (params.filter) queryParams.append('filter', params.filter) + if (params.pageSize) queryParams.append('pageSize', params.pageSize.toString()) + if (params.pageToken) queryParams.append('pageToken', params.pageToken) + + const queryString = queryParams.toString() + return `${MEET_API_BASE}/${name}/participants${queryString ? `?${queryString}` : ''}` + }, + method: 'GET', + headers: (params: GoogleMeetListParticipantsParams) => ({ + Authorization: `Bearer ${params.accessToken}`, + }), + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const error = await response.text().catch(() => 'Unknown error') + throw new Error(`Google Meet API error (${response.status}): ${error}`) + } + const data: GoogleMeetApiParticipantListResponse = await response.json() + const participants = data.participants ?? [] + + const getDisplayName = (p: GoogleMeetApiParticipantResponse): string | null => { + return ( + p.signedinUser?.displayName ?? p.anonymousUser?.displayName ?? p.phoneUser?.displayName ?? null + ) + } + + const getUserType = (p: GoogleMeetApiParticipantResponse): string => { + if (p.signedinUser) return 'signed_in' + if (p.anonymousUser) return 'anonymous' + if (p.phoneUser) return 'phone' + return 'unknown' + } + + return { + success: true, + output: { + participants: participants.map((p) => ({ + name: p.name, + earliestStartTime: p.earliestStartTime, + latestEndTime: p.latestEndTime ?? null, + displayName: getDisplayName(p), + userType: getUserType(p), + })), + nextPageToken: data.nextPageToken ?? null, + totalSize: data.totalSize ?? null, + }, + } + }, + + outputs: { + participants: { + type: 'json', + description: 'List of participants with name, times, display name, and user type', + }, + nextPageToken: { type: 'string', description: 'Token for next page of results', optional: true }, + totalSize: { type: 'number', description: 'Total number of participants', optional: true }, + }, +} diff --git a/apps/sim/tools/google_meet/types.ts b/apps/sim/tools/google_meet/types.ts new file mode 100644 index 00000000000..4f7630c2614 --- /dev/null +++ b/apps/sim/tools/google_meet/types.ts @@ -0,0 +1,165 @@ +import type { ToolResponse } from '@/tools/types' + +export const MEET_API_BASE = 'https://meet.googleapis.com/v2' + +interface BaseGoogleMeetParams { + accessToken: string +} + +export interface GoogleMeetCreateSpaceParams extends BaseGoogleMeetParams { + accessType?: 'OPEN' | 'TRUSTED' | 'RESTRICTED' + entryPointAccess?: 'ALL' | 'CREATOR_APP_ONLY' +} + +export interface GoogleMeetGetSpaceParams extends BaseGoogleMeetParams { + spaceName: string +} + +export interface GoogleMeetEndConferenceParams extends BaseGoogleMeetParams { + spaceName: string +} + +export interface GoogleMeetListConferenceRecordsParams extends BaseGoogleMeetParams { + filter?: string + pageSize?: number + pageToken?: string +} + +export interface GoogleMeetGetConferenceRecordParams extends BaseGoogleMeetParams { + conferenceName: string +} + +export interface GoogleMeetListParticipantsParams extends BaseGoogleMeetParams { + conferenceName: string + filter?: string + pageSize?: number + pageToken?: string +} + +export type GoogleMeetToolParams = + | GoogleMeetCreateSpaceParams + | GoogleMeetGetSpaceParams + | GoogleMeetEndConferenceParams + | GoogleMeetListConferenceRecordsParams + | GoogleMeetGetConferenceRecordParams + | GoogleMeetListParticipantsParams + +export interface GoogleMeetApiSpaceResponse { + name: string + meetingUri: string + meetingCode: string + config?: { + accessType?: string + entryPointAccess?: string + } + activeConference?: { + conferenceRecord: string + } +} + +export interface GoogleMeetApiConferenceRecordResponse { + name: string + startTime: string + endTime?: string + expireTime: string + space: string +} + +export interface GoogleMeetApiConferenceRecordListResponse { + conferenceRecords: GoogleMeetApiConferenceRecordResponse[] + nextPageToken?: string +} + +export interface GoogleMeetApiParticipantResponse { + name: string + earliestStartTime: string + latestEndTime?: string + signedinUser?: { + user: string + displayName: string + } + anonymousUser?: { + displayName: string + } + phoneUser?: { + displayName: string + } +} + +export interface GoogleMeetApiParticipantListResponse { + participants: GoogleMeetApiParticipantResponse[] + nextPageToken?: string + totalSize?: number +} + +export interface GoogleMeetCreateSpaceResponse extends ToolResponse { + output: { + name: string + meetingUri: string + meetingCode: string + accessType: string | null + entryPointAccess: string | null + } +} + +export interface GoogleMeetGetSpaceResponse extends ToolResponse { + output: { + name: string + meetingUri: string + meetingCode: string + accessType: string | null + entryPointAccess: string | null + activeConference: string | null + } +} + +export interface GoogleMeetEndConferenceResponse extends ToolResponse { + output: { + ended: boolean + } +} + +export interface GoogleMeetListConferenceRecordsResponse extends ToolResponse { + output: { + conferenceRecords: Array<{ + name: string + startTime: string + endTime: string | null + expireTime: string + space: string + }> + nextPageToken: string | null + } +} + +export interface GoogleMeetGetConferenceRecordResponse extends ToolResponse { + output: { + name: string + startTime: string + endTime: string | null + expireTime: string + space: string + } +} + +export interface GoogleMeetListParticipantsResponse extends ToolResponse { + output: { + participants: Array<{ + name: string + earliestStartTime: string + latestEndTime: string | null + displayName: string | null + userType: string + }> + nextPageToken: string | null + totalSize: number | null + } +} + +export type GoogleMeetResponse = + | GoogleMeetCreateSpaceResponse + | GoogleMeetGetSpaceResponse + | GoogleMeetEndConferenceResponse + | GoogleMeetListConferenceRecordsResponse + | GoogleMeetGetConferenceRecordResponse + | GoogleMeetListParticipantsResponse diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index 26458f94f93..c92fc151295 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -748,6 +748,14 @@ import { googleContactsUpdateTool, } from '@/tools/google_contacts' import { googleDocsCreateTool, googleDocsReadTool, googleDocsWriteTool } from '@/tools/google_docs' +import { + googleMeetCreateSpaceTool, + googleMeetEndConferenceTool, + googleMeetGetConferenceRecordTool, + googleMeetGetSpaceTool, + googleMeetListConferenceRecordsTool, + googleMeetListParticipantsTool, +} from '@/tools/google_meet' import { googleDriveCopyTool, googleDriveCreateFolderTool, @@ -3215,6 +3223,12 @@ export const tools: Record = { google_maps_speed_limits: googleMapsSpeedLimitsTool, google_maps_timezone: googleMapsTimezoneTool, google_maps_validate_address: googleMapsValidateAddressTool, + google_meet_create_space: googleMeetCreateSpaceTool, + google_meet_end_conference: googleMeetEndConferenceTool, + google_meet_get_conference_record: googleMeetGetConferenceRecordTool, + google_meet_get_space: googleMeetGetSpaceTool, + google_meet_list_conference_records: googleMeetListConferenceRecordsTool, + google_meet_list_participants: googleMeetListParticipantsTool, google_pagespeed_analyze: googlePagespeedAnalyzeTool, google_tasks_create: googleTasksCreateTool, google_tasks_delete: googleTasksDeleteTool, From bd544a007c59336fe6e3191bcaf4ca7b6f1a06b8 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 2 Mar 2026 20:00:23 -0800 Subject: [PATCH 2/3] lint --- apps/docs/components/ui/icon-mapping.ts | 12 ++++++------ .../docs/content/docs/en/tools/google_meet.mdx | 1 + apps/docs/content/docs/en/tools/meta.json | 2 +- apps/sim/blocks/registry.ts | 2 +- apps/sim/tools/google_meet/create_space.ts | 16 ++++++++++++---- apps/sim/tools/google_meet/end_conference.ts | 6 ++---- .../tools/google_meet/get_conference_record.ts | 2 +- apps/sim/tools/google_meet/get_space.ts | 18 ++++++++++++------ .../google_meet/list_conference_records.ts | 8 ++++++-- .../sim/tools/google_meet/list_participants.ts | 13 ++++++++++--- apps/sim/tools/registry.ts | 16 ++++++++-------- 11 files changed, 60 insertions(+), 36 deletions(-) diff --git a/apps/docs/components/ui/icon-mapping.ts b/apps/docs/components/ui/icon-mapping.ts index 0db6bac0711..c4bada328a4 100644 --- a/apps/docs/components/ui/icon-mapping.ts +++ b/apps/docs/components/ui/icon-mapping.ts @@ -44,8 +44,8 @@ import { FirecrawlIcon, FirefliesIcon, GammaIcon, - GitLabIcon, GithubIcon, + GitLabIcon, GmailIcon, GongIcon, GoogleBigQueryIcon, @@ -87,9 +87,9 @@ import { LinkupIcon, LoopsIcon, LumaIcon, - MailServerIcon, MailchimpIcon, MailgunIcon, + MailServerIcon, Mem0Icon, MicrosoftDataverseIcon, MicrosoftExcelIcon, @@ -123,8 +123,6 @@ import { ResendIcon, RevenueCatIcon, S3Icon, - SQSIcon, - STTIcon, SalesforceIcon, SearchIcon, SendgridIcon, @@ -136,17 +134,19 @@ import { SimilarwebIcon, SlackIcon, SmtpIcon, + SQSIcon, SshIcon, + STTIcon, StagehandIcon, StripeIcon, SupabaseIcon, - TTSIcon, TavilyIcon, TelegramIcon, TextractIcon, TinybirdIcon, TranslateIcon, TrelloIcon, + TTSIcon, TwilioIcon, TypeformIcon, UpstashIcon, @@ -157,11 +157,11 @@ import { WhatsAppIcon, WikipediaIcon, WordpressIcon, + xIcon, YouTubeIcon, ZendeskIcon, ZepIcon, ZoomIcon, - xIcon, } from '@/components/icons' type IconComponent = ComponentType> diff --git a/apps/docs/content/docs/en/tools/google_meet.mdx b/apps/docs/content/docs/en/tools/google_meet.mdx index e117678f2b0..f7b94f5db60 100644 --- a/apps/docs/content/docs/en/tools/google_meet.mdx +++ b/apps/docs/content/docs/en/tools/google_meet.mdx @@ -26,6 +26,7 @@ Key features of the Google Meet API include: In Sim, the Google Meet integration allows your agents to create meeting spaces on demand, monitor conference activity, track participation across meetings, and manage active conferences as part of automated workflows. This enables scenarios such as automatically provisioning meeting rooms for scheduled events, generating attendance reports, ending stale conferences, and building meeting analytics dashboards. {/* MANUAL-CONTENT-END */} + ## Usage Instructions Integrate Google Meet into your workflow. Create meeting spaces, get space details, end conferences, list conference records, and view participants. diff --git a/apps/docs/content/docs/en/tools/meta.json b/apps/docs/content/docs/en/tools/meta.json index 92ac008c319..7bc7b9ecc81 100644 --- a/apps/docs/content/docs/en/tools/meta.json +++ b/apps/docs/content/docs/en/tools/meta.json @@ -162,4 +162,4 @@ "zep", "zoom" ] -} \ No newline at end of file +} diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index fd3103e7fd8..1ce70983fcc 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -57,8 +57,8 @@ import { GoogleDocsBlock } from '@/blocks/blocks/google_docs' import { GoogleDriveBlock } from '@/blocks/blocks/google_drive' import { GoogleFormsBlock } from '@/blocks/blocks/google_forms' import { GoogleGroupsBlock } from '@/blocks/blocks/google_groups' -import { GoogleMeetBlock } from '@/blocks/blocks/google_meet' import { GoogleMapsBlock } from '@/blocks/blocks/google_maps' +import { GoogleMeetBlock } from '@/blocks/blocks/google_meet' import { GooglePagespeedBlock } from '@/blocks/blocks/google_pagespeed' import { GoogleSheetsBlock, GoogleSheetsV2Block } from '@/blocks/blocks/google_sheets' import { GoogleSlidesBlock, GoogleSlidesV2Block } from '@/blocks/blocks/google_slides' diff --git a/apps/sim/tools/google_meet/create_space.ts b/apps/sim/tools/google_meet/create_space.ts index 48b36d7680d..6bbd350a5fe 100644 --- a/apps/sim/tools/google_meet/create_space.ts +++ b/apps/sim/tools/google_meet/create_space.ts @@ -1,8 +1,8 @@ import { - MEET_API_BASE, type GoogleMeetApiSpaceResponse, type GoogleMeetCreateSpaceParams, type GoogleMeetCreateSpaceResponse, + MEET_API_BASE, } from '@/tools/google_meet/types' import type { ToolConfig } from '@/tools/types' @@ -38,7 +38,8 @@ export const createSpaceTool: ToolConfig< type: 'string', required: false, visibility: 'user-or-llm', - description: 'Entry points allowed: ALL (all entry points) or CREATOR_APP_ONLY (only via app)', + description: + 'Entry points allowed: ALL (all entry points) or CREATOR_APP_ONLY (only via app)', }, }, @@ -84,9 +85,16 @@ export const createSpaceTool: ToolConfig< outputs: { name: { type: 'string', description: 'Resource name of the space (e.g., spaces/abc123)' }, - meetingUri: { type: 'string', description: 'Meeting URL (e.g., https://meet.google.com/abc-defg-hij)' }, + meetingUri: { + type: 'string', + description: 'Meeting URL (e.g., https://meet.google.com/abc-defg-hij)', + }, meetingCode: { type: 'string', description: 'Meeting code (e.g., abc-defg-hij)' }, accessType: { type: 'string', description: 'Access type configuration', optional: true }, - entryPointAccess: { type: 'string', description: 'Entry point access configuration', optional: true }, + entryPointAccess: { + type: 'string', + description: 'Entry point access configuration', + optional: true, + }, }, } diff --git a/apps/sim/tools/google_meet/end_conference.ts b/apps/sim/tools/google_meet/end_conference.ts index d7d38f9e6af..355f1025174 100644 --- a/apps/sim/tools/google_meet/end_conference.ts +++ b/apps/sim/tools/google_meet/end_conference.ts @@ -1,7 +1,7 @@ import { - MEET_API_BASE, type GoogleMeetEndConferenceParams, type GoogleMeetEndConferenceResponse, + MEET_API_BASE, } from '@/tools/google_meet/types' import type { ToolConfig } from '@/tools/types' @@ -37,9 +37,7 @@ export const endConferenceTool: ToolConfig< request: { url: (params: GoogleMeetEndConferenceParams) => { const trimmed = params.spaceName.trim() - const name = trimmed.startsWith('spaces/') - ? trimmed - : `spaces/${trimmed}` + const name = trimmed.startsWith('spaces/') ? trimmed : `spaces/${trimmed}` return `${MEET_API_BASE}/${name}:endActiveConference` }, method: 'POST', diff --git a/apps/sim/tools/google_meet/get_conference_record.ts b/apps/sim/tools/google_meet/get_conference_record.ts index 24a81431a05..6f8e39f0abc 100644 --- a/apps/sim/tools/google_meet/get_conference_record.ts +++ b/apps/sim/tools/google_meet/get_conference_record.ts @@ -1,8 +1,8 @@ import { - MEET_API_BASE, type GoogleMeetApiConferenceRecordResponse, type GoogleMeetGetConferenceRecordParams, type GoogleMeetGetConferenceRecordResponse, + MEET_API_BASE, } from '@/tools/google_meet/types' import type { ToolConfig } from '@/tools/types' diff --git a/apps/sim/tools/google_meet/get_space.ts b/apps/sim/tools/google_meet/get_space.ts index 559dae5c65b..479e16ac3a7 100644 --- a/apps/sim/tools/google_meet/get_space.ts +++ b/apps/sim/tools/google_meet/get_space.ts @@ -1,8 +1,8 @@ import { - MEET_API_BASE, type GoogleMeetApiSpaceResponse, type GoogleMeetGetSpaceParams, type GoogleMeetGetSpaceResponse, + MEET_API_BASE, } from '@/tools/google_meet/types' import type { ToolConfig } from '@/tools/types' @@ -35,9 +35,7 @@ export const getSpaceTool: ToolConfig { const trimmed = params.spaceName.trim() - const name = trimmed.startsWith('spaces/') - ? trimmed - : `spaces/${trimmed}` + const name = trimmed.startsWith('spaces/') ? trimmed : `spaces/${trimmed}` return `${MEET_API_BASE}/${name}` }, method: 'GET', @@ -71,7 +69,15 @@ export const getSpaceTool: ToolConfig { return ( - p.signedinUser?.displayName ?? p.anonymousUser?.displayName ?? p.phoneUser?.displayName ?? null + p.signedinUser?.displayName ?? + p.anonymousUser?.displayName ?? + p.phoneUser?.displayName ?? + null ) } @@ -117,7 +120,11 @@ export const listParticipantsTool: ToolConfig< type: 'json', description: 'List of participants with name, times, display name, and user type', }, - nextPageToken: { type: 'string', description: 'Token for next page of results', optional: true }, + nextPageToken: { + type: 'string', + description: 'Token for next page of results', + optional: true, + }, totalSize: { type: 'number', description: 'Total number of participants', optional: true }, }, } diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index c92fc151295..3cae7142412 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -748,14 +748,6 @@ import { googleContactsUpdateTool, } from '@/tools/google_contacts' import { googleDocsCreateTool, googleDocsReadTool, googleDocsWriteTool } from '@/tools/google_docs' -import { - googleMeetCreateSpaceTool, - googleMeetEndConferenceTool, - googleMeetGetConferenceRecordTool, - googleMeetGetSpaceTool, - googleMeetListConferenceRecordsTool, - googleMeetListParticipantsTool, -} from '@/tools/google_meet' import { googleDriveCopyTool, googleDriveCreateFolderTool, @@ -819,6 +811,14 @@ import { googleMapsTimezoneTool, googleMapsValidateAddressTool, } from '@/tools/google_maps' +import { + googleMeetCreateSpaceTool, + googleMeetEndConferenceTool, + googleMeetGetConferenceRecordTool, + googleMeetGetSpaceTool, + googleMeetListConferenceRecordsTool, + googleMeetListParticipantsTool, +} from '@/tools/google_meet' import { googlePagespeedAnalyzeTool } from '@/tools/google_pagespeed' import { googleSheetsAppendTool, From 23781112d5cdd9fe828cf02b8aefd50521a27d1e Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 2 Mar 2026 21:48:04 -0800 Subject: [PATCH 3/3] ack comments --- apps/sim/tools/google_meet/list_conference_records.ts | 2 +- apps/sim/tools/google_meet/list_participants.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/sim/tools/google_meet/list_conference_records.ts b/apps/sim/tools/google_meet/list_conference_records.ts index 480823a7014..cdf1eb933fa 100644 --- a/apps/sim/tools/google_meet/list_conference_records.ts +++ b/apps/sim/tools/google_meet/list_conference_records.ts @@ -43,7 +43,7 @@ export const listConferenceRecordsTool: ToolConfig< pageToken: { type: 'string', required: false, - visibility: 'hidden', + visibility: 'user-or-llm', description: 'Page token from a previous list request', }, }, diff --git a/apps/sim/tools/google_meet/list_participants.ts b/apps/sim/tools/google_meet/list_participants.ts index 5d5e1a06f11..debcf530ddb 100644 --- a/apps/sim/tools/google_meet/list_participants.ts +++ b/apps/sim/tools/google_meet/list_participants.ts @@ -49,7 +49,7 @@ export const listParticipantsTool: ToolConfig< pageToken: { type: 'string', required: false, - visibility: 'hidden', + visibility: 'user-or-llm', description: 'Page token from a previous list request', }, },