@openclaw/google-meet 2026.5.1-beta.2 → 2026.5.2-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/cli.test.ts CHANGED
@@ -324,6 +324,64 @@ describe("google-meet CLI", () => {
324
324
  }
325
325
  });
326
326
 
327
+ it("ends an active conference for a Meet space", async () => {
328
+ const fetchMock = vi.fn(async (input: RequestInfo | URL, _init?: RequestInit) => {
329
+ const url = requestUrl(input);
330
+ if (url.pathname === "/v2/spaces/abc-defg-hij") {
331
+ return jsonResponse({
332
+ name: "spaces/space-resource-123",
333
+ meetingCode: "abc-defg-hij",
334
+ meetingUri: "https://meet.google.com/abc-defg-hij",
335
+ });
336
+ }
337
+ if (url.pathname === "/v2/spaces/space-resource-123:endActiveConference") {
338
+ return jsonResponse({});
339
+ }
340
+ return new Response("not found", { status: 404 });
341
+ });
342
+ vi.stubGlobal("fetch", fetchMock);
343
+
344
+ const stdout = captureStdout();
345
+ try {
346
+ await setupCli({}).parseAsync(
347
+ [
348
+ "googlemeet",
349
+ "end-active-conference",
350
+ "https://meet.google.com/abc-defg-hij",
351
+ "--access-token",
352
+ "token",
353
+ "--expires-at",
354
+ String(Date.now() + 120_000),
355
+ "--json",
356
+ ],
357
+ { from: "user" },
358
+ );
359
+ expect(JSON.parse(stdout.output())).toMatchObject({
360
+ space: "spaces/space-resource-123",
361
+ ended: true,
362
+ tokenSource: "cached-access-token",
363
+ });
364
+ expect(fetchMock).toHaveBeenCalledWith(
365
+ "https://meet.googleapis.com/v2/spaces/space-resource-123:endActiveConference",
366
+ expect.objectContaining({ method: "POST", body: "{}" }),
367
+ );
368
+ } finally {
369
+ stdout.restore();
370
+ }
371
+ });
372
+
373
+ it("rejects access policy flags when create would use browser fallback", async () => {
374
+ await expect(
375
+ setupCli({
376
+ runtime: {
377
+ createViaBrowser: vi.fn(async () => {
378
+ throw new Error("browser fallback should not run");
379
+ }),
380
+ },
381
+ }).parseAsync(["googlemeet", "create", "--access-type", "OPEN"], { from: "user" }),
382
+ ).rejects.toThrow("access policy options require OAuth/API room creation");
383
+ });
384
+
327
385
  it("prints the latest conference record", async () => {
328
386
  stubMeetArtifactsApi();
329
387
  const stdout = captureStdout();
@@ -631,6 +689,55 @@ describe("google-meet CLI", () => {
631
689
  }
632
690
  });
633
691
 
692
+ it("runs a listen-first health probe", async () => {
693
+ const testListen = vi.fn(async () => ({
694
+ createdSession: true,
695
+ listenVerified: true,
696
+ listenTimedOut: false,
697
+ transcriptLines: 1,
698
+ session: {
699
+ id: "meet_1",
700
+ url: "https://meet.google.com/abc-defg-hij",
701
+ state: "active" as const,
702
+ transport: "chrome-node" as const,
703
+ mode: "transcribe" as const,
704
+ participantIdentity: "signed-in Google Chrome profile on a paired node",
705
+ createdAt: "2026-04-25T00:00:00.000Z",
706
+ updatedAt: "2026-04-25T00:00:01.000Z",
707
+ realtime: { enabled: false, provider: "openai", toolPolicy: "safe-read-only" },
708
+ notes: [],
709
+ },
710
+ }));
711
+ const stdout = captureStdout();
712
+ try {
713
+ await setupCli({
714
+ runtime: { testListen },
715
+ }).parseAsync(
716
+ [
717
+ "googlemeet",
718
+ "test-listen",
719
+ "https://meet.google.com/abc-defg-hij",
720
+ "--transport",
721
+ "chrome-node",
722
+ "--timeout-ms",
723
+ "30000",
724
+ ],
725
+ { from: "user" },
726
+ );
727
+ expect(testListen).toHaveBeenCalledWith({
728
+ url: "https://meet.google.com/abc-defg-hij",
729
+ transport: "chrome-node",
730
+ timeoutMs: 30000,
731
+ });
732
+ expect(JSON.parse(stdout.output())).toMatchObject({
733
+ listenVerified: true,
734
+ transcriptLines: 1,
735
+ });
736
+ } finally {
737
+ stdout.restore();
738
+ }
739
+ });
740
+
634
741
  it("prints a dry-run export manifest without writing files", async () => {
635
742
  stubMeetArtifactsApi();
636
743
  const stdout = captureStdout();
package/src/cli.ts CHANGED
@@ -10,9 +10,11 @@ import {
10
10
  type GoogleMeetCalendarLookupResult,
11
11
  } from "./calendar.js";
12
12
  import type { GoogleMeetConfig, GoogleMeetMode, GoogleMeetTransport } from "./config.js";
13
+ import { hasCreateSpaceConfigInput, resolveCreateSpaceConfig } from "./create.js";
13
14
  import {
14
15
  buildGoogleMeetPreflightReport,
15
16
  createGoogleMeetSpace,
17
+ endGoogleMeetActiveConference,
16
18
  fetchGoogleMeetArtifacts,
17
19
  fetchGoogleMeetAttendance,
18
20
  fetchLatestGoogleMeetConferenceRecord,
@@ -35,6 +37,7 @@ type JoinOptions = {
35
37
  transport?: GoogleMeetTransport;
36
38
  mode?: GoogleMeetMode;
37
39
  message?: string;
40
+ timeoutMs?: string;
38
41
  dialInNumber?: string;
39
42
  pin?: string;
40
43
  dtmfSequence?: string;
@@ -159,6 +162,8 @@ type CreateOptions = {
159
162
  clientId?: string;
160
163
  clientSecret?: string;
161
164
  expiresAt?: string;
165
+ accessType?: string;
166
+ entryPointAccess?: string;
162
167
  join?: boolean;
163
168
  transport?: GoogleMeetTransport;
164
169
  mode?: GoogleMeetMode;
@@ -224,6 +229,17 @@ function formatOptional(value: unknown): string {
224
229
  return typeof value === "string" && value.trim() ? value : "n/a";
225
230
  }
226
231
 
232
+ function parsePositiveNumber(value: string | undefined, label: string): number | undefined {
233
+ if (value === undefined) {
234
+ return undefined;
235
+ }
236
+ const parsed = Number(value);
237
+ if (!Number.isFinite(parsed) || parsed <= 0) {
238
+ throw new Error(`${label} must be a positive number`);
239
+ }
240
+ return parsed;
241
+ }
242
+
227
243
  function formatDuration(value: number | undefined): string {
228
244
  if (value === undefined) {
229
245
  return "n/a";
@@ -1037,7 +1053,7 @@ function renderTranscriptMarkdown(result: GoogleMeetArtifactsResult): string {
1037
1053
  return `${lines.join("\n")}\n`;
1038
1054
  }
1039
1055
 
1040
- export function collectGoogleMeetArtifactWarnings(
1056
+ function collectGoogleMeetArtifactWarnings(
1041
1057
  result: GoogleMeetArtifactsResult,
1042
1058
  ): GoogleMeetExportWarning[] {
1043
1059
  const warnings: GoogleMeetExportWarning[] = [];
@@ -1367,6 +1383,14 @@ export function registerGoogleMeetCli(params: {
1367
1383
  .option("--client-id <id>", "OAuth client id override")
1368
1384
  .option("--client-secret <secret>", "OAuth client secret override")
1369
1385
  .option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds")
1386
+ .option(
1387
+ "--access-type <type>",
1388
+ "Google Meet SpaceConfig accessType for API create: OPEN, TRUSTED, or RESTRICTED",
1389
+ )
1390
+ .option(
1391
+ "--entry-point-access <type>",
1392
+ "Google Meet SpaceConfig entryPointAccess for API create: ALL or CREATOR_APP_ONLY",
1393
+ )
1370
1394
  .option("--no-join", "Only create the meeting URL; do not join it")
1371
1395
  .option("--transport <transport>", "Join transport: chrome, chrome-node, or twilio")
1372
1396
  .option(
@@ -1380,6 +1404,11 @@ export function registerGoogleMeetCli(params: {
1380
1404
  .option("--json", "Print JSON output", false)
1381
1405
  .action(async (options: CreateOptions) => {
1382
1406
  if (!hasCreateOAuth(params.config, options)) {
1407
+ if (hasCreateSpaceConfigInput(options as Record<string, unknown>)) {
1408
+ throw new Error(
1409
+ "Google Meet access policy options require OAuth/API room creation. Configure Google Meet OAuth or remove --access-type/--entry-point-access.",
1410
+ );
1411
+ }
1383
1412
  const rt = await params.ensureRuntime();
1384
1413
  const result = await rt.createViaBrowser();
1385
1414
  const join =
@@ -1423,7 +1452,10 @@ export function registerGoogleMeetCli(params: {
1423
1452
  const token = await resolveGoogleMeetAccessToken(
1424
1453
  resolveCreateTokenOptions(params.config, options),
1425
1454
  );
1426
- const result = await createGoogleMeetSpace({ accessToken: token.accessToken });
1455
+ const result = await createGoogleMeetSpace({
1456
+ accessToken: token.accessToken,
1457
+ config: resolveCreateSpaceConfig(options as Record<string, unknown>),
1458
+ });
1427
1459
  const join =
1428
1460
  options.join !== false
1429
1461
  ? await (
@@ -1463,6 +1495,39 @@ export function registerGoogleMeetCli(params: {
1463
1495
  }
1464
1496
  });
1465
1497
 
1498
+ root
1499
+ .command("end-active-conference")
1500
+ .description("End the active conference for a Google Meet space")
1501
+ .argument("[meeting]", "Meet URL, meeting code, or spaces/{id}")
1502
+ .option("--access-token <token>", "Access token override")
1503
+ .option("--refresh-token <token>", "Refresh token override")
1504
+ .option("--client-id <id>", "OAuth client id override")
1505
+ .option("--client-secret <secret>", "OAuth client secret override")
1506
+ .option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds")
1507
+ .option("--json", "Print JSON output", false)
1508
+ .action(async (meeting: string | undefined, options: ResolveSpaceOptions & JsonOptions) => {
1509
+ const token = await resolveGoogleMeetAccessToken(
1510
+ resolveOAuthTokenOptions(params.config, options),
1511
+ );
1512
+ const result = await endGoogleMeetActiveConference({
1513
+ accessToken: token.accessToken,
1514
+ meeting: resolveMeetingInput(params.config, meeting ?? options.meeting),
1515
+ });
1516
+ if (options.json) {
1517
+ writeStdoutJson({
1518
+ ...result,
1519
+ tokenSource: token.refreshed ? "refresh-token" : "cached-access-token",
1520
+ });
1521
+ return;
1522
+ }
1523
+ writeStdoutLine("space: %s", result.space);
1524
+ writeStdoutLine("ended: yes");
1525
+ writeStdoutLine(
1526
+ "token source: %s",
1527
+ token.refreshed ? "refresh-token" : "cached-access-token",
1528
+ );
1529
+ });
1530
+
1466
1531
  root
1467
1532
  .command("join")
1468
1533
  .argument("[url]", "Explicit https://meet.google.com/... URL")
@@ -1514,6 +1579,22 @@ export function registerGoogleMeetCli(params: {
1514
1579
  );
1515
1580
  });
1516
1581
 
1582
+ root
1583
+ .command("test-listen")
1584
+ .argument("[url]", "Explicit https://meet.google.com/... URL")
1585
+ .option("--transport <transport>", "Transport: chrome or chrome-node")
1586
+ .option("--timeout-ms <ms>", "How long to wait for fresh captions/transcript movement")
1587
+ .action(async (url: string | undefined, options: JoinOptions) => {
1588
+ const rt = await params.ensureRuntime();
1589
+ writeStdoutJson(
1590
+ await rt.testListen({
1591
+ url: resolveMeetingInput(params.config, url),
1592
+ transport: options.transport,
1593
+ timeoutMs: parsePositiveNumber(options.timeoutMs, "timeout-ms"),
1594
+ }),
1595
+ );
1596
+ });
1597
+
1517
1598
  root
1518
1599
  .command("resolve-space")
1519
1600
  .description("Resolve a Meet URL, meeting code, or spaces/{id} to its canonical space")
package/src/create.ts CHANGED
@@ -1,7 +1,12 @@
1
1
  import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
2
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
3
3
  import type { GoogleMeetConfig, GoogleMeetMode, GoogleMeetTransport } from "./config.js";
4
- import { createGoogleMeetSpace } from "./meet.js";
4
+ import {
5
+ createGoogleMeetSpace,
6
+ type GoogleMeetAccessType,
7
+ type GoogleMeetEntryPointAccess,
8
+ type GoogleMeetSpaceConfig,
9
+ } from "./meet.js";
5
10
  import { resolveGoogleMeetAccessToken } from "./oauth.js";
6
11
  import type { GoogleMeetRuntime } from "./runtime.js";
7
12
  import { createMeetWithBrowserProxyOnNode } from "./transports/chrome-create.js";
@@ -14,6 +19,47 @@ function normalizeMode(value: unknown): GoogleMeetMode | undefined {
14
19
  return value === "realtime" || value === "transcribe" ? value : undefined;
15
20
  }
16
21
 
22
+ function normalizeGoogleMeetAccessType(value: unknown): GoogleMeetAccessType | undefined {
23
+ const normalized = normalizeOptionalString(value)?.toUpperCase().replaceAll("-", "_");
24
+ return normalized === "OPEN" || normalized === "TRUSTED" || normalized === "RESTRICTED"
25
+ ? normalized
26
+ : undefined;
27
+ }
28
+
29
+ function normalizeGoogleMeetEntryPointAccess(
30
+ value: unknown,
31
+ ): GoogleMeetEntryPointAccess | undefined {
32
+ const normalized = normalizeOptionalString(value)?.toUpperCase().replaceAll("-", "_");
33
+ return normalized === "ALL" || normalized === "CREATOR_APP_ONLY" ? normalized : undefined;
34
+ }
35
+
36
+ export function resolveCreateSpaceConfig(
37
+ raw: Record<string, unknown>,
38
+ ): GoogleMeetSpaceConfig | undefined {
39
+ const rawAccessType = normalizeOptionalString(raw.accessType);
40
+ const rawEntryPointAccess = normalizeOptionalString(raw.entryPointAccess);
41
+ const accessType = normalizeGoogleMeetAccessType(raw.accessType);
42
+ const entryPointAccess = normalizeGoogleMeetEntryPointAccess(raw.entryPointAccess);
43
+ if (rawAccessType !== undefined && !accessType) {
44
+ throw new Error("Invalid Google Meet accessType. Expected OPEN, TRUSTED, or RESTRICTED.");
45
+ }
46
+ if (rawEntryPointAccess !== undefined && !entryPointAccess) {
47
+ throw new Error("Invalid Google Meet entryPointAccess. Expected ALL or CREATOR_APP_ONLY.");
48
+ }
49
+ const config = {
50
+ ...(accessType ? { accessType } : {}),
51
+ ...(entryPointAccess ? { entryPointAccess } : {}),
52
+ };
53
+ return Object.keys(config).length > 0 ? config : undefined;
54
+ }
55
+
56
+ export function hasCreateSpaceConfigInput(raw: Record<string, unknown>): boolean {
57
+ return (
58
+ normalizeOptionalString(raw.accessType) !== undefined ||
59
+ normalizeOptionalString(raw.entryPointAccess) !== undefined
60
+ );
61
+ }
62
+
17
63
  async function createSpaceFromParams(config: GoogleMeetConfig, raw: Record<string, unknown>) {
18
64
  const token = await resolveGoogleMeetAccessToken({
19
65
  clientId: normalizeOptionalString(raw.clientId) ?? config.oauth.clientId,
@@ -22,7 +68,10 @@ async function createSpaceFromParams(config: GoogleMeetConfig, raw: Record<strin
22
68
  accessToken: normalizeOptionalString(raw.accessToken) ?? config.oauth.accessToken,
23
69
  expiresAt: typeof raw.expiresAt === "number" ? raw.expiresAt : config.oauth.expiresAt,
24
70
  });
25
- const result = await createGoogleMeetSpace({ accessToken: token.accessToken });
71
+ const result = await createGoogleMeetSpace({
72
+ accessToken: token.accessToken,
73
+ config: resolveCreateSpaceConfig(raw),
74
+ });
26
75
  return { source: "api" as const, token, ...result };
27
76
  }
28
77
 
@@ -35,10 +84,6 @@ function hasGoogleMeetOAuth(config: GoogleMeetConfig, raw: Record<string, unknow
35
84
  );
36
85
  }
37
86
 
38
- export function shouldJoinCreatedMeet(raw: Record<string, unknown>): boolean {
39
- return raw.join !== false && raw.join !== "false";
40
- }
41
-
42
87
  export async function createMeetFromParams(params: {
43
88
  config: GoogleMeetConfig;
44
89
  runtime: OpenClawPluginApi["runtime"];
@@ -53,6 +98,11 @@ export async function createMeetFromParams(params: {
53
98
  "URL-only creation was requested. Call google_meet with action=join and url=meetingUri to enter the meeting.",
54
99
  };
55
100
  }
101
+ if (hasCreateSpaceConfigInput(params.raw)) {
102
+ throw new Error(
103
+ "Google Meet access policy options require OAuth/API room creation. Configure Google Meet OAuth or remove accessType/entryPointAccess.",
104
+ );
105
+ }
56
106
  const browser = await createMeetWithBrowserProxyOnNode({
57
107
  runtime: params.runtime,
58
108
  config: params.config,
package/src/meet.ts CHANGED
@@ -9,16 +9,26 @@ const GOOGLE_MEET_API_HOST = "meet.googleapis.com";
9
9
  const GOOGLE_MEET_MEDIA_SCOPE =
10
10
  "https://www.googleapis.com/auth/meetings.conference.media.readonly";
11
11
  const GOOGLE_MEET_SPACE_SCOPE = "https://www.googleapis.com/auth/meetings.space.readonly";
12
+ const GOOGLE_MEET_SPACE_CREATED_SCOPE = "https://www.googleapis.com/auth/meetings.space.created";
13
+ const GOOGLE_MEET_SPACE_SETTINGS_SCOPE = "https://www.googleapis.com/auth/meetings.space.settings";
12
14
 
13
- type GoogleMeetSpace = {
15
+ export type GoogleMeetAccessType = "OPEN" | "TRUSTED" | "RESTRICTED";
16
+ export type GoogleMeetEntryPointAccess = "ALL" | "CREATOR_APP_ONLY";
17
+
18
+ export type GoogleMeetSpaceConfig = {
19
+ accessType?: GoogleMeetAccessType;
20
+ entryPointAccess?: GoogleMeetEntryPointAccess;
21
+ };
22
+
23
+ export type GoogleMeetSpace = {
14
24
  name: string;
15
25
  meetingCode?: string;
16
26
  meetingUri?: string;
17
27
  activeConference?: Record<string, unknown>;
18
- config?: Record<string, unknown>;
28
+ config?: GoogleMeetSpaceConfig & Record<string, unknown>;
19
29
  };
20
30
 
21
- type GoogleMeetPreflightReport = {
31
+ export type GoogleMeetPreflightReport = {
22
32
  input: string;
23
33
  resolvedSpaceName: string;
24
34
  meetingCode?: string;
@@ -29,12 +39,17 @@ type GoogleMeetPreflightReport = {
29
39
  blockers: string[];
30
40
  };
31
41
 
32
- type GoogleMeetCreateSpaceResult = {
42
+ export type GoogleMeetCreateSpaceResult = {
33
43
  space: GoogleMeetSpace;
34
44
  meetingUri: string;
35
45
  };
36
46
 
37
- type GoogleMeetConferenceRecord = {
47
+ export type GoogleMeetEndActiveConferenceResult = {
48
+ space: string;
49
+ ended: true;
50
+ };
51
+
52
+ export type GoogleMeetConferenceRecord = {
38
53
  name: string;
39
54
  space?: string;
40
55
  startTime?: string;
@@ -353,7 +368,12 @@ export async function fetchGoogleMeetSpace(params: {
353
368
 
354
369
  export async function createGoogleMeetSpace(params: {
355
370
  accessToken: string;
371
+ config?: GoogleMeetSpaceConfig;
356
372
  }): Promise<GoogleMeetCreateSpaceResult> {
373
+ const body =
374
+ params.config && Object.keys(params.config).length > 0
375
+ ? JSON.stringify({ config: params.config })
376
+ : "{}";
357
377
  const { response, release } = await fetchWithSsrFGuard({
358
378
  url: `${GOOGLE_MEET_API_BASE_URL}/spaces`,
359
379
  init: {
@@ -363,7 +383,7 @@ export async function createGoogleMeetSpace(params: {
363
383
  Accept: "application/json",
364
384
  "Content-Type": "application/json",
365
385
  },
366
- body: "{}",
386
+ body,
367
387
  },
368
388
  policy: { allowedHostnames: [GOOGLE_MEET_API_HOST] },
369
389
  auditContext: "google-meet.spaces.create",
@@ -375,7 +395,10 @@ export async function createGoogleMeetSpace(params: {
375
395
  response,
376
396
  detail,
377
397
  prefix: "Google Meet spaces.create",
378
- scopes: ["https://www.googleapis.com/auth/meetings.space.created"],
398
+ scopes:
399
+ params.config && Object.keys(params.config).length > 0
400
+ ? [GOOGLE_MEET_SPACE_CREATED_SCOPE, GOOGLE_MEET_SPACE_SETTINGS_SCOPE]
401
+ : [GOOGLE_MEET_SPACE_CREATED_SCOPE],
379
402
  });
380
403
  }
381
404
  const payload = (await response.json()) as GoogleMeetSpace;
@@ -392,6 +415,45 @@ export async function createGoogleMeetSpace(params: {
392
415
  }
393
416
  }
394
417
 
418
+ export async function endGoogleMeetActiveConference(params: {
419
+ accessToken: string;
420
+ meeting: string;
421
+ }): Promise<GoogleMeetEndActiveConferenceResult> {
422
+ const resolved = await fetchGoogleMeetSpace({
423
+ accessToken: params.accessToken,
424
+ meeting: params.meeting,
425
+ });
426
+ const space = resolved.name;
427
+ const { response, release } = await fetchWithSsrFGuard({
428
+ url: `${GOOGLE_MEET_API_BASE_URL}/${encodeSpaceNameForPath(space)}:endActiveConference`,
429
+ init: {
430
+ method: "POST",
431
+ headers: {
432
+ Authorization: `Bearer ${params.accessToken}`,
433
+ Accept: "application/json",
434
+ "Content-Type": "application/json",
435
+ },
436
+ body: "{}",
437
+ },
438
+ policy: { allowedHostnames: [GOOGLE_MEET_API_HOST] },
439
+ auditContext: "google-meet.spaces.endActiveConference",
440
+ });
441
+ try {
442
+ if (!response.ok) {
443
+ const detail = await response.text();
444
+ throw await googleApiError({
445
+ response,
446
+ detail,
447
+ prefix: "Google Meet spaces.endActiveConference",
448
+ scopes: [GOOGLE_MEET_SPACE_CREATED_SCOPE],
449
+ });
450
+ }
451
+ return { space, ended: true };
452
+ } finally {
453
+ await release();
454
+ }
455
+ }
456
+
395
457
  async function fetchGoogleMeetConferenceRecord(params: {
396
458
  accessToken: string;
397
459
  conferenceRecord: string;
package/src/oauth.ts CHANGED
@@ -6,13 +6,14 @@ import {
6
6
  } from "openclaw/plugin-sdk/provider-auth-runtime";
7
7
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
8
8
 
9
- export const GOOGLE_MEET_REDIRECT_URI = "http://localhost:8085/oauth2callback";
10
- export const GOOGLE_MEET_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
11
- export const GOOGLE_MEET_TOKEN_URL = "https://oauth2.googleapis.com/token";
9
+ const GOOGLE_MEET_REDIRECT_URI = "http://localhost:8085/oauth2callback";
10
+ const GOOGLE_MEET_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
11
+ const GOOGLE_MEET_TOKEN_URL = "https://oauth2.googleapis.com/token";
12
12
  const GOOGLE_MEET_TOKEN_HOST = "oauth2.googleapis.com";
13
- export const GOOGLE_MEET_SCOPES = [
13
+ const GOOGLE_MEET_SCOPES = [
14
14
  "https://www.googleapis.com/auth/meetings.space.created",
15
15
  "https://www.googleapis.com/auth/meetings.space.readonly",
16
+ "https://www.googleapis.com/auth/meetings.space.settings",
16
17
  "https://www.googleapis.com/auth/meetings.conference.media.readonly",
17
18
  "https://www.googleapis.com/auth/calendar.events.readonly",
18
19
  "https://www.googleapis.com/auth/drive.meet.readonly",
@@ -137,7 +138,7 @@ export async function refreshGoogleMeetAccessToken(params: {
137
138
  );
138
139
  }
139
140
 
140
- export function shouldUseCachedGoogleMeetAccessToken(params: {
141
+ function shouldUseCachedGoogleMeetAccessToken(params: {
141
142
  accessToken?: string;
142
143
  expiresAt?: number;
143
144
  now?: number;