@openclaw/google-meet 2026.9.5 → 2026.9.7
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/assets/icon.png +0 -0
- package/dist/.setup/{chrome-create-BZRBHJp9.mjs → chrome-create-wuAK5Pnq.mjs} +14 -19
- package/dist/.setup/{cli-MJjnaxoP.mjs → cli-DVDq0TFu.mjs} +27 -695
- package/dist/.setup/cli-export-D4IM6KLJ.mjs +632 -0
- package/dist/.setup/config-BXGAMntj.mjs +240 -0
- package/dist/.setup/{create-sGWmlpgC.mjs → create-UrHOmnWb.mjs} +4 -17
- package/dist/.setup/{google-meet-platform-adapter-DQZ74Kd5.mjs → google-meet-platform-adapter-gosgbMIM.mjs} +337 -228
- package/dist/.setup/{google-meet-platform-constants-Bs5iAg3E.mjs → google-meet-platform-constants-CnRfrYX7.mjs} +1 -4
- package/dist/.setup/{node-host-BOzEP_Us.mjs → node-host-Tr7Mx3da.mjs} +4 -7
- package/dist/.setup/{node-invoke-policy-hwXq9MfV.mjs → node-invoke-policy-Dd3krTYV.mjs} +2 -2
- package/dist/.setup/{oauth-22Ey-zCb.mjs → oauth-BoyruWcS.mjs} +2 -2
- package/dist/.setup/{plugin-helpers-rGjL9QFK.mjs → plugin-helpers-CdQ_YNA7.mjs} +147 -236
- package/dist/.setup/{plugin-registration-CfZbUMDY.mjs → plugin-registration-aCEuCerg.mjs} +59 -16
- package/dist/.setup/{runtime-D_C0dFI1.mjs → runtime-BdiF53A2.mjs} +89 -41
- package/dist/doctor-contract-api.js +3 -6
- package/dist/index.js +54 -13
- package/node_modules/typebox/build/compile/code.mjs +1 -2
- package/node_modules/typebox/build/compile/validator.mjs +5 -1
- package/node_modules/typebox/build/format/iri.mjs +16 -9
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +7 -5
- package/node_modules/typebox/build/guard/guard.mjs +14 -9
- package/node_modules/typebox/build/guard/index.mjs +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
- package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
- package/node_modules/typebox/build/schema/build.mjs +2 -3
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
- package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
- package/node_modules/typebox/build/schema/parse.mjs +3 -0
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
- package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
- package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
- package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
- package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
- package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
- package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +3 -1
- package/package.json +5 -5
- package/dist/.setup/config-C-6enWkx.mjs +0 -328
- package/dist/.setup/google-api-errors-BDYXfKRa.mjs +0 -17
- /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as googleApiError } from "./google-api-errors-BDYXfKRa.mjs";
|
|
1
|
+
import { p as resolveMeetingInput } from "./plugin-registration-aCEuCerg.mjs";
|
|
3
2
|
import { t as normalizeMeetUrl } from "./meet-url-BP2Jlvjs.mjs";
|
|
4
3
|
import { normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
4
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
6
5
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
7
|
-
import { parseDateStringTimestampMs } from "openclaw/plugin-sdk/number-runtime";
|
|
6
|
+
import { parseDateStringTimestampMs, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
8
7
|
import { readPositiveIntegerParam } from "openclaw/plugin-sdk/channel-actions";
|
|
9
|
-
import { readProviderJsonResponse, readProviderTextResponse } from "openclaw/plugin-sdk/provider-http";
|
|
8
|
+
import { readProviderJsonResponse, readProviderTextResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
|
|
10
9
|
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
11
10
|
//#region \0rolldown/runtime.js
|
|
12
11
|
var __defProp = Object.defineProperty;
|
|
@@ -20,6 +19,21 @@ var __exportAll = (all, no_symbols) => {
|
|
|
20
19
|
return target;
|
|
21
20
|
};
|
|
22
21
|
//#endregion
|
|
22
|
+
//#region extensions/google-meet/src/google-api-errors.ts
|
|
23
|
+
const REAUTH_HINT = "Re-run `openclaw googlemeet auth login` and store the refreshed oauth block.";
|
|
24
|
+
const GOOGLE_API_ERROR_BODY_LIMIT_BYTES = 8192;
|
|
25
|
+
function scopeText(scopes) {
|
|
26
|
+
return scopes.map((scope) => `\`${scope}\``).join(", ");
|
|
27
|
+
}
|
|
28
|
+
async function readGoogleApiErrorDetail(response) {
|
|
29
|
+
return await readResponseTextLimited(response, GOOGLE_API_ERROR_BODY_LIMIT_BYTES);
|
|
30
|
+
}
|
|
31
|
+
async function googleApiError(params) {
|
|
32
|
+
const detail = await readGoogleApiErrorDetail(params.response);
|
|
33
|
+
const scopeHint = params.scopes && params.scopes.length > 0 ? ` Required OAuth scope: ${scopeText(params.scopes)}. ${REAUTH_HINT}` : "";
|
|
34
|
+
return /* @__PURE__ */ new Error(`${params.prefix} failed (${params.response.status}): ${detail}${scopeHint}`);
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
23
37
|
//#region extensions/google-meet/src/calendar.ts
|
|
24
38
|
const GOOGLE_CALENDAR_API_BASE_URL = "https://www.googleapis.com/calendar/v3";
|
|
25
39
|
const GOOGLE_CALENDAR_API_HOST = "www.googleapis.com";
|
|
@@ -76,15 +90,9 @@ function buildGoogleMeetCalendarDayWindow(now = /* @__PURE__ */ new Date()) {
|
|
|
76
90
|
timeMax: end.toISOString()
|
|
77
91
|
};
|
|
78
92
|
}
|
|
79
|
-
function parseCalendarEventTime(value) {
|
|
80
|
-
const raw = value?.dateTime ?? value?.date;
|
|
81
|
-
if (!raw) return;
|
|
82
|
-
const parsed = Date.parse(raw);
|
|
83
|
-
return Number.isFinite(parsed) ? parsed : void 0;
|
|
84
|
-
}
|
|
85
93
|
function rankCalendarEvent(event, nowMs) {
|
|
86
|
-
const startMs =
|
|
87
|
-
const endMs =
|
|
94
|
+
const startMs = parseDateStringTimestampMs(event.start?.dateTime ?? event.start?.date) ?? Number.POSITIVE_INFINITY;
|
|
95
|
+
const endMs = parseDateStringTimestampMs(event.end?.dateTime ?? event.end?.date) ?? startMs;
|
|
88
96
|
if (startMs <= nowMs && endMs >= nowMs) return 0;
|
|
89
97
|
if (startMs > nowMs) return startMs - nowMs;
|
|
90
98
|
return nowMs - startMs + 2592e6;
|
|
@@ -169,51 +177,6 @@ async function findGoogleMeetCalendarEvent(params) {
|
|
|
169
177
|
};
|
|
170
178
|
}
|
|
171
179
|
//#endregion
|
|
172
|
-
//#region extensions/google-meet/src/drive.ts
|
|
173
|
-
const GOOGLE_DRIVE_API_BASE_URL = "https://www.googleapis.com/drive/v3";
|
|
174
|
-
const GOOGLE_DRIVE_API_HOST = "www.googleapis.com";
|
|
175
|
-
const GOOGLE_DRIVE_MEET_SCOPE = "https://www.googleapis.com/auth/drive.meet.readonly";
|
|
176
|
-
const GOOGLE_DRIVE_REQUEST_TIMEOUT_MS = 3e4;
|
|
177
|
-
const TEXT_PLAIN_MIME = "text/plain";
|
|
178
|
-
function appendQuery$1(url, query) {
|
|
179
|
-
const parsed = new URL(url);
|
|
180
|
-
for (const [key, value] of Object.entries(query)) if (value !== void 0) parsed.searchParams.set(key, value);
|
|
181
|
-
return parsed.toString();
|
|
182
|
-
}
|
|
183
|
-
function extractGoogleDriveDocumentId(value) {
|
|
184
|
-
if (typeof value !== "string") return;
|
|
185
|
-
const trimmed = value.trim();
|
|
186
|
-
if (!trimmed) return;
|
|
187
|
-
if (/^https?:\/\//i.test(trimmed)) try {
|
|
188
|
-
return new URL(trimmed).pathname.match(/\/document\/d\/([^/]+)/)?.[1];
|
|
189
|
-
} catch {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
return trimmed.split("/").filter(Boolean).at(-1);
|
|
193
|
-
}
|
|
194
|
-
async function exportGoogleDriveDocumentText(params) {
|
|
195
|
-
const { response, release } = await fetchWithSsrFGuard({
|
|
196
|
-
url: appendQuery$1(`${GOOGLE_DRIVE_API_BASE_URL}/files/${encodeURIComponent(params.documentId)}/export`, { mimeType: TEXT_PLAIN_MIME }),
|
|
197
|
-
init: { headers: {
|
|
198
|
-
Authorization: `Bearer ${params.accessToken}`,
|
|
199
|
-
Accept: TEXT_PLAIN_MIME
|
|
200
|
-
} },
|
|
201
|
-
policy: { allowedHostnames: [GOOGLE_DRIVE_API_HOST] },
|
|
202
|
-
auditContext: "google-meet.drive.files.export",
|
|
203
|
-
timeoutMs: GOOGLE_DRIVE_REQUEST_TIMEOUT_MS
|
|
204
|
-
});
|
|
205
|
-
try {
|
|
206
|
-
if (!response.ok) throw await googleApiError({
|
|
207
|
-
response,
|
|
208
|
-
prefix: "Google Drive files.export",
|
|
209
|
-
scopes: [GOOGLE_DRIVE_MEET_SCOPE]
|
|
210
|
-
});
|
|
211
|
-
return await readProviderTextResponse(response, "Google Drive files.export");
|
|
212
|
-
} finally {
|
|
213
|
-
await release();
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
//#endregion
|
|
217
180
|
//#region extensions/google-meet/src/meet-api.ts
|
|
218
181
|
const GOOGLE_MEET_API_BASE_URL = `https://meet.googleapis.com/v2`;
|
|
219
182
|
const GOOGLE_MEET_URL_HOST = "meet.google.com";
|
|
@@ -253,7 +216,7 @@ function normalizeConferenceRecordName(input) {
|
|
|
253
216
|
if (!trimmed) throw new Error("Conference record is required");
|
|
254
217
|
return trimmed.startsWith("conferenceRecords/") ? trimmed : `conferenceRecords/${trimmed}`;
|
|
255
218
|
}
|
|
256
|
-
function appendQuery(url, query) {
|
|
219
|
+
function appendQuery$1(url, query) {
|
|
257
220
|
if (!query) return url;
|
|
258
221
|
const parsed = new URL(url);
|
|
259
222
|
for (const [key, value] of Object.entries(query)) if (value !== void 0) parsed.searchParams.set(key, String(value));
|
|
@@ -266,9 +229,9 @@ function assertResourceArray(value, key, context) {
|
|
|
266
229
|
for (const resource of resources) if (!resource.name?.trim()) throw new Error(`Google Meet ${context} response included a resource without name`);
|
|
267
230
|
return resources;
|
|
268
231
|
}
|
|
269
|
-
async function requestGoogleMeetApi(params) {
|
|
270
|
-
|
|
271
|
-
url: appendQuery(`${GOOGLE_MEET_API_BASE_URL}/${params.path}`, params.query),
|
|
232
|
+
async function requestGoogleMeetApi(params, read) {
|
|
233
|
+
const { response, release } = await fetchWithSsrFGuard({
|
|
234
|
+
url: appendQuery$1(`${GOOGLE_MEET_API_BASE_URL}/${params.path}`, params.query),
|
|
272
235
|
init: {
|
|
273
236
|
method: params.method,
|
|
274
237
|
headers: {
|
|
@@ -282,25 +245,20 @@ async function requestGoogleMeetApi(params) {
|
|
|
282
245
|
auditContext: params.auditContext,
|
|
283
246
|
timeoutMs: GOOGLE_MEET_REQUEST_TIMEOUT_MS
|
|
284
247
|
});
|
|
285
|
-
}
|
|
286
|
-
async function fetchGoogleMeetJson(params) {
|
|
287
|
-
const { response, release } = await requestGoogleMeetApi({
|
|
288
|
-
accessToken: params.accessToken,
|
|
289
|
-
path: params.path,
|
|
290
|
-
query: params.query,
|
|
291
|
-
auditContext: params.auditContext
|
|
292
|
-
});
|
|
293
248
|
try {
|
|
294
249
|
if (!response.ok) throw await googleApiError({
|
|
295
250
|
response,
|
|
296
251
|
prefix: params.errorPrefix,
|
|
297
|
-
scopes: [GOOGLE_MEET_MEDIA_SCOPE]
|
|
252
|
+
scopes: params.scopes ?? [GOOGLE_MEET_MEDIA_SCOPE]
|
|
298
253
|
});
|
|
299
|
-
return await
|
|
254
|
+
return await read(response);
|
|
300
255
|
} finally {
|
|
301
256
|
await release();
|
|
302
257
|
}
|
|
303
258
|
}
|
|
259
|
+
function fetchGoogleMeetJson(params) {
|
|
260
|
+
return requestGoogleMeetApi(params, (response) => readProviderJsonResponse(response, params.errorPrefix));
|
|
261
|
+
}
|
|
304
262
|
async function listGoogleMeetCollection(params) {
|
|
305
263
|
const items = [];
|
|
306
264
|
let pageToken;
|
|
@@ -325,76 +283,53 @@ async function listGoogleMeetCollection(params) {
|
|
|
325
283
|
}
|
|
326
284
|
async function fetchGoogleMeetSpace(params) {
|
|
327
285
|
const name = normalizeGoogleMeetSpaceName(params.meeting);
|
|
328
|
-
const
|
|
286
|
+
const payload = await fetchGoogleMeetJson({
|
|
329
287
|
accessToken: params.accessToken,
|
|
330
288
|
path: encodeSpaceNameForPath(name),
|
|
331
|
-
auditContext: "google-meet.spaces.get"
|
|
289
|
+
auditContext: "google-meet.spaces.get",
|
|
290
|
+
errorPrefix: "Google Meet spaces.get",
|
|
291
|
+
scopes: [GOOGLE_MEET_SPACE_SCOPE]
|
|
332
292
|
});
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
response,
|
|
336
|
-
prefix: "Google Meet spaces.get",
|
|
337
|
-
scopes: [GOOGLE_MEET_SPACE_SCOPE]
|
|
338
|
-
});
|
|
339
|
-
const payload = await readProviderJsonResponse(response, "Google Meet spaces.get");
|
|
340
|
-
if (!payload.name?.trim()) throw new Error("Google Meet spaces.get response was missing name");
|
|
341
|
-
return payload;
|
|
342
|
-
} finally {
|
|
343
|
-
await release();
|
|
344
|
-
}
|
|
293
|
+
if (!payload.name?.trim()) throw new Error("Google Meet spaces.get response was missing name");
|
|
294
|
+
return payload;
|
|
345
295
|
}
|
|
346
296
|
async function createGoogleMeetSpace(params) {
|
|
347
|
-
const
|
|
348
|
-
const
|
|
297
|
+
const hasConfig = params.config && Object.keys(params.config).length > 0;
|
|
298
|
+
const payload = await fetchGoogleMeetJson({
|
|
349
299
|
accessToken: params.accessToken,
|
|
350
300
|
path: "spaces",
|
|
351
301
|
method: "POST",
|
|
352
|
-
body,
|
|
353
|
-
auditContext: "google-meet.spaces.create"
|
|
302
|
+
body: hasConfig ? JSON.stringify({ config: params.config }) : "{}",
|
|
303
|
+
auditContext: "google-meet.spaces.create",
|
|
304
|
+
errorPrefix: "Google Meet spaces.create",
|
|
305
|
+
scopes: hasConfig ? [GOOGLE_MEET_SPACE_CREATED_SCOPE, GOOGLE_MEET_SPACE_SETTINGS_SCOPE] : [GOOGLE_MEET_SPACE_CREATED_SCOPE]
|
|
354
306
|
});
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
if (!payload.name?.trim()) throw new Error("Google Meet spaces.create response was missing name");
|
|
363
|
-
const meetingUri = payload.meetingUri?.trim();
|
|
364
|
-
if (!meetingUri) throw new Error("Google Meet spaces.create response was missing meetingUri");
|
|
365
|
-
return {
|
|
366
|
-
space: payload,
|
|
367
|
-
meetingUri
|
|
368
|
-
};
|
|
369
|
-
} finally {
|
|
370
|
-
await release();
|
|
371
|
-
}
|
|
307
|
+
if (!payload.name?.trim()) throw new Error("Google Meet spaces.create response was missing name");
|
|
308
|
+
const meetingUri = payload.meetingUri?.trim();
|
|
309
|
+
if (!meetingUri) throw new Error("Google Meet spaces.create response was missing meetingUri");
|
|
310
|
+
return {
|
|
311
|
+
space: payload,
|
|
312
|
+
meetingUri
|
|
313
|
+
};
|
|
372
314
|
}
|
|
373
315
|
async function endGoogleMeetActiveConference(params) {
|
|
374
316
|
const space = (await fetchGoogleMeetSpace({
|
|
375
317
|
accessToken: params.accessToken,
|
|
376
318
|
meeting: params.meeting
|
|
377
319
|
})).name;
|
|
378
|
-
|
|
320
|
+
await requestGoogleMeetApi({
|
|
379
321
|
accessToken: params.accessToken,
|
|
380
322
|
path: `${encodeSpaceNameForPath(space)}:endActiveConference`,
|
|
381
323
|
method: "POST",
|
|
382
324
|
body: "{}",
|
|
383
|
-
auditContext: "google-meet.spaces.endActiveConference"
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
return {
|
|
392
|
-
space,
|
|
393
|
-
ended: true
|
|
394
|
-
};
|
|
395
|
-
} finally {
|
|
396
|
-
await release();
|
|
397
|
-
}
|
|
325
|
+
auditContext: "google-meet.spaces.endActiveConference",
|
|
326
|
+
errorPrefix: "Google Meet spaces.endActiveConference",
|
|
327
|
+
scopes: [GOOGLE_MEET_SPACE_CREATED_SCOPE]
|
|
328
|
+
}, async () => void 0);
|
|
329
|
+
return {
|
|
330
|
+
space,
|
|
331
|
+
ended: true
|
|
332
|
+
};
|
|
398
333
|
}
|
|
399
334
|
async function fetchGoogleMeetConferenceRecord(params) {
|
|
400
335
|
const name = normalizeConferenceRecordName(params.conferenceRecord);
|
|
@@ -439,15 +374,15 @@ async function fetchLatestGoogleMeetConferenceRecord(params) {
|
|
|
439
374
|
...conferenceRecord ? { conferenceRecord } : {}
|
|
440
375
|
};
|
|
441
376
|
}
|
|
442
|
-
|
|
377
|
+
function listGoogleMeetConferenceResources(collection, params) {
|
|
443
378
|
const parent = normalizeConferenceRecordName(params.conferenceRecord);
|
|
444
379
|
return listGoogleMeetCollection({
|
|
445
380
|
accessToken: params.accessToken,
|
|
446
|
-
path: `${encodeResourceNameForPath(parent)}
|
|
447
|
-
collectionKey:
|
|
381
|
+
path: `${encodeResourceNameForPath(parent)}/${collection}`,
|
|
382
|
+
collectionKey: collection,
|
|
448
383
|
query: { pageSize: params.pageSize },
|
|
449
|
-
auditContext:
|
|
450
|
-
errorPrefix:
|
|
384
|
+
auditContext: `google-meet.conferenceRecords.${collection}.list`,
|
|
385
|
+
errorPrefix: `Google Meet conferenceRecords.${collection}.list`
|
|
451
386
|
});
|
|
452
387
|
}
|
|
453
388
|
async function listGoogleMeetParticipantSessions(params) {
|
|
@@ -460,28 +395,6 @@ async function listGoogleMeetParticipantSessions(params) {
|
|
|
460
395
|
errorPrefix: "Google Meet conferenceRecords.participants.participantSessions.list"
|
|
461
396
|
});
|
|
462
397
|
}
|
|
463
|
-
async function listGoogleMeetRecordings(params) {
|
|
464
|
-
const parent = normalizeConferenceRecordName(params.conferenceRecord);
|
|
465
|
-
return listGoogleMeetCollection({
|
|
466
|
-
accessToken: params.accessToken,
|
|
467
|
-
path: `${encodeResourceNameForPath(parent)}/recordings`,
|
|
468
|
-
collectionKey: "recordings",
|
|
469
|
-
query: { pageSize: params.pageSize },
|
|
470
|
-
auditContext: "google-meet.conferenceRecords.recordings.list",
|
|
471
|
-
errorPrefix: "Google Meet conferenceRecords.recordings.list"
|
|
472
|
-
});
|
|
473
|
-
}
|
|
474
|
-
async function listGoogleMeetTranscripts(params) {
|
|
475
|
-
const parent = normalizeConferenceRecordName(params.conferenceRecord);
|
|
476
|
-
return listGoogleMeetCollection({
|
|
477
|
-
accessToken: params.accessToken,
|
|
478
|
-
path: `${encodeResourceNameForPath(parent)}/transcripts`,
|
|
479
|
-
collectionKey: "transcripts",
|
|
480
|
-
query: { pageSize: params.pageSize },
|
|
481
|
-
auditContext: "google-meet.conferenceRecords.transcripts.list",
|
|
482
|
-
errorPrefix: "Google Meet conferenceRecords.transcripts.list"
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
398
|
async function listGoogleMeetTranscriptEntries(params) {
|
|
486
399
|
return listGoogleMeetCollection({
|
|
487
400
|
accessToken: params.accessToken,
|
|
@@ -492,17 +405,6 @@ async function listGoogleMeetTranscriptEntries(params) {
|
|
|
492
405
|
errorPrefix: "Google Meet conferenceRecords.transcripts.entries.list"
|
|
493
406
|
});
|
|
494
407
|
}
|
|
495
|
-
async function listGoogleMeetSmartNotes(params) {
|
|
496
|
-
const parent = normalizeConferenceRecordName(params.conferenceRecord);
|
|
497
|
-
return listGoogleMeetCollection({
|
|
498
|
-
accessToken: params.accessToken,
|
|
499
|
-
path: `${encodeResourceNameForPath(parent)}/smartNotes`,
|
|
500
|
-
collectionKey: "smartNotes",
|
|
501
|
-
query: { pageSize: params.pageSize },
|
|
502
|
-
auditContext: "google-meet.conferenceRecords.smartNotes.list",
|
|
503
|
-
errorPrefix: "Google Meet conferenceRecords.smartNotes.list"
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
408
|
async function resolveConferenceRecordQuery(params) {
|
|
507
409
|
if (params.conferenceRecord?.trim()) {
|
|
508
410
|
const conferenceRecord = await fetchGoogleMeetConferenceRecord({
|
|
@@ -532,13 +434,55 @@ async function resolveConferenceRecordQuery(params) {
|
|
|
532
434
|
};
|
|
533
435
|
}
|
|
534
436
|
//#endregion
|
|
437
|
+
//#region extensions/google-meet/src/drive.ts
|
|
438
|
+
const GOOGLE_DRIVE_API_BASE_URL = "https://www.googleapis.com/drive/v3";
|
|
439
|
+
const GOOGLE_DRIVE_API_HOST = "www.googleapis.com";
|
|
440
|
+
const GOOGLE_DRIVE_MEET_SCOPE = "https://www.googleapis.com/auth/drive.meet.readonly";
|
|
441
|
+
const GOOGLE_DRIVE_REQUEST_TIMEOUT_MS = 3e4;
|
|
442
|
+
const TEXT_PLAIN_MIME = "text/plain";
|
|
443
|
+
function appendQuery(url, query) {
|
|
444
|
+
const parsed = new URL(url);
|
|
445
|
+
for (const [key, value] of Object.entries(query)) if (value !== void 0) parsed.searchParams.set(key, value);
|
|
446
|
+
return parsed.toString();
|
|
447
|
+
}
|
|
448
|
+
function extractGoogleDriveDocumentId(value) {
|
|
449
|
+
if (typeof value !== "string") return;
|
|
450
|
+
const trimmed = value.trim();
|
|
451
|
+
if (!trimmed) return;
|
|
452
|
+
if (/^https?:\/\//i.test(trimmed)) try {
|
|
453
|
+
return new URL(trimmed).pathname.match(/\/document\/d\/([^/]+)/)?.[1];
|
|
454
|
+
} catch {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
return trimmed.split("/").filter(Boolean).at(-1);
|
|
458
|
+
}
|
|
459
|
+
async function exportGoogleDriveDocumentText(params) {
|
|
460
|
+
const { response, release } = await fetchWithSsrFGuard({
|
|
461
|
+
url: appendQuery(`${GOOGLE_DRIVE_API_BASE_URL}/files/${encodeURIComponent(params.documentId)}/export`, { mimeType: TEXT_PLAIN_MIME }),
|
|
462
|
+
init: { headers: {
|
|
463
|
+
Authorization: `Bearer ${params.accessToken}`,
|
|
464
|
+
Accept: TEXT_PLAIN_MIME
|
|
465
|
+
} },
|
|
466
|
+
policy: { allowedHostnames: [GOOGLE_DRIVE_API_HOST] },
|
|
467
|
+
auditContext: "google-meet.drive.files.export",
|
|
468
|
+
timeoutMs: GOOGLE_DRIVE_REQUEST_TIMEOUT_MS
|
|
469
|
+
});
|
|
470
|
+
try {
|
|
471
|
+
if (!response.ok) throw await googleApiError({
|
|
472
|
+
response,
|
|
473
|
+
prefix: "Google Drive files.export",
|
|
474
|
+
scopes: [GOOGLE_DRIVE_MEET_SCOPE]
|
|
475
|
+
});
|
|
476
|
+
return await readProviderTextResponse(response, "Google Drive files.export");
|
|
477
|
+
} finally {
|
|
478
|
+
await release();
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
//#endregion
|
|
535
482
|
//#region extensions/google-meet/src/meet.ts
|
|
536
483
|
function getParticipantDisplayName(participant) {
|
|
537
484
|
return participant.signedinUser?.displayName ?? participant.anonymousUser?.displayName ?? participant.phoneUser?.displayName;
|
|
538
485
|
}
|
|
539
|
-
function getParticipantUser(participant) {
|
|
540
|
-
return participant.signedinUser?.user;
|
|
541
|
-
}
|
|
542
486
|
function getDocsDestinationDocumentId(destination) {
|
|
543
487
|
return extractGoogleDriveDocumentId(destination?.document) ?? extractGoogleDriveDocumentId(destination?.documentId) ?? extractGoogleDriveDocumentId(destination?.file);
|
|
544
488
|
}
|
|
@@ -560,16 +504,9 @@ async function attachDocumentText(params) {
|
|
|
560
504
|
};
|
|
561
505
|
}
|
|
562
506
|
}
|
|
563
|
-
function
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
function minTimestamp(values) {
|
|
567
|
-
const parsed = values.map(parseDateStringTimestampMs).filter((value) => typeof value === "number");
|
|
568
|
-
return parsed.length > 0 ? isoFromMs(Math.min(...parsed)) : void 0;
|
|
569
|
-
}
|
|
570
|
-
function maxTimestamp(values) {
|
|
571
|
-
const parsed = values.map(parseDateStringTimestampMs).filter((value) => typeof value === "number");
|
|
572
|
-
return parsed.length > 0 ? isoFromMs(Math.max(...parsed)) : void 0;
|
|
507
|
+
function timestampBound(values, bound) {
|
|
508
|
+
const parsed = values.map(parseDateStringTimestampMs).filter((value) => value !== void 0);
|
|
509
|
+
return parsed.length > 0 ? timestampMsToIsoString(bound(...parsed)) : void 0;
|
|
573
510
|
}
|
|
574
511
|
function sumSessionDurationMs(sessions, fallbackStart, fallbackEnd) {
|
|
575
512
|
const sessionTotal = sessions.reduce((total, session) => {
|
|
@@ -590,8 +527,8 @@ function sortSessions(sessions) {
|
|
|
590
527
|
}
|
|
591
528
|
function decorateAttendanceRow(row, conferenceRecord, params) {
|
|
592
529
|
const sessions = sortSessions(row.sessions);
|
|
593
|
-
const firstJoinTime =
|
|
594
|
-
const lastLeaveTime =
|
|
530
|
+
const firstJoinTime = timestampBound([row.earliestStartTime, ...sessions.map((session) => session.startTime)], Math.min);
|
|
531
|
+
const lastLeaveTime = timestampBound([row.latestEndTime, ...sessions.map((session) => session.endTime)], Math.max);
|
|
595
532
|
const durationMs = sumSessionDurationMs(sessions, firstJoinTime, lastLeaveTime);
|
|
596
533
|
const conferenceStartMs = parseDateStringTimestampMs(conferenceRecord.startTime);
|
|
597
534
|
const conferenceEndMs = parseDateStringTimestampMs(conferenceRecord.endTime);
|
|
@@ -638,35 +575,24 @@ function mergeAttendanceRows(rows, conferenceRecord, params) {
|
|
|
638
575
|
existing.sessions.push(...row.sessions);
|
|
639
576
|
existing.displayName ??= row.displayName;
|
|
640
577
|
existing.user ??= row.user;
|
|
641
|
-
existing.earliestStartTime =
|
|
642
|
-
existing.latestEndTime =
|
|
578
|
+
existing.earliestStartTime = timestampBound([existing.earliestStartTime, row.earliestStartTime], Math.min);
|
|
579
|
+
existing.latestEndTime = timestampBound([existing.latestEndTime, row.latestEndTime], Math.max);
|
|
643
580
|
}
|
|
644
581
|
return [...grouped.values()].map((row) => decorateAttendanceRow(row, conferenceRecord, params));
|
|
645
582
|
}
|
|
646
583
|
async function fetchGoogleMeetArtifacts(params) {
|
|
647
584
|
const resolved = await resolveConferenceRecordQuery(params);
|
|
648
585
|
const artifacts = await Promise.all(resolved.conferenceRecords.map(async (conferenceRecord) => {
|
|
586
|
+
const query = {
|
|
587
|
+
accessToken: params.accessToken,
|
|
588
|
+
conferenceRecord: conferenceRecord.name,
|
|
589
|
+
pageSize: params.pageSize
|
|
590
|
+
};
|
|
649
591
|
const [participants, recordings, transcripts, smartNotesResult] = await Promise.all([
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
}),
|
|
655
|
-
listGoogleMeetRecordings({
|
|
656
|
-
accessToken: params.accessToken,
|
|
657
|
-
conferenceRecord: conferenceRecord.name,
|
|
658
|
-
pageSize: params.pageSize
|
|
659
|
-
}),
|
|
660
|
-
listGoogleMeetTranscripts({
|
|
661
|
-
accessToken: params.accessToken,
|
|
662
|
-
conferenceRecord: conferenceRecord.name,
|
|
663
|
-
pageSize: params.pageSize
|
|
664
|
-
}),
|
|
665
|
-
listGoogleMeetSmartNotes({
|
|
666
|
-
accessToken: params.accessToken,
|
|
667
|
-
conferenceRecord: conferenceRecord.name,
|
|
668
|
-
pageSize: params.pageSize
|
|
669
|
-
}).then((smartNotes) => ({ smartNotes })).catch((error) => ({
|
|
592
|
+
listGoogleMeetConferenceResources("participants", query),
|
|
593
|
+
listGoogleMeetConferenceResources("recordings", query),
|
|
594
|
+
listGoogleMeetConferenceResources("transcripts", query),
|
|
595
|
+
listGoogleMeetConferenceResources("smartNotes", query).then((smartNotes) => ({ smartNotes })).catch((error) => ({
|
|
670
596
|
smartNotes: [],
|
|
671
597
|
smartNotesError: formatErrorMessage(error)
|
|
672
598
|
}))
|
|
@@ -715,7 +641,7 @@ async function fetchGoogleMeetArtifacts(params) {
|
|
|
715
641
|
async function fetchGoogleMeetAttendance(params) {
|
|
716
642
|
const resolved = await resolveConferenceRecordQuery(params);
|
|
717
643
|
const nestedRows = await Promise.all(resolved.conferenceRecords.map(async (conferenceRecord) => {
|
|
718
|
-
const participants = await
|
|
644
|
+
const participants = await listGoogleMeetConferenceResources("participants", {
|
|
719
645
|
accessToken: params.accessToken,
|
|
720
646
|
conferenceRecord: conferenceRecord.name,
|
|
721
647
|
pageSize: params.pageSize
|
|
@@ -724,7 +650,7 @@ async function fetchGoogleMeetAttendance(params) {
|
|
|
724
650
|
conferenceRecord: conferenceRecord.name,
|
|
725
651
|
participant: participant.name,
|
|
726
652
|
displayName: getParticipantDisplayName(participant),
|
|
727
|
-
user:
|
|
653
|
+
user: participant.signedinUser?.user,
|
|
728
654
|
earliestStartTime: participant.earliestStartTime,
|
|
729
655
|
latestEndTime: participant.latestEndTime,
|
|
730
656
|
sessions: await listGoogleMeetParticipantSessions({
|
|
@@ -759,6 +685,7 @@ function buildGoogleMeetPreflightReport(params) {
|
|
|
759
685
|
//#region extensions/google-meet/src/plugin-helpers.ts
|
|
760
686
|
var plugin_helpers_exports = /* @__PURE__ */ __exportAll({
|
|
761
687
|
buildGoogleMeetCalendarDayWindow: () => buildGoogleMeetCalendarDayWindow,
|
|
688
|
+
buildGoogleMeetExportRequest: () => buildGoogleMeetExportRequest,
|
|
762
689
|
buildGoogleMeetPreflightReport: () => buildGoogleMeetPreflightReport,
|
|
763
690
|
createAndJoinMeetFromParams: () => createAndJoinMeetFromParams,
|
|
764
691
|
createMeetFromParams: () => createMeetFromParams,
|
|
@@ -773,7 +700,8 @@ var plugin_helpers_exports = /* @__PURE__ */ __exportAll({
|
|
|
773
700
|
resolveMeetingFromParams: () => resolveMeetingFromParams,
|
|
774
701
|
resolveSpaceFromParams: () => resolveSpaceFromParams
|
|
775
702
|
});
|
|
776
|
-
const loadGoogleMeetCreateModule = createLazyRuntimeModule(() => import("./create-
|
|
703
|
+
const loadGoogleMeetCreateModule = createLazyRuntimeModule(() => import("./create-UrHOmnWb.mjs").then((n) => n.t));
|
|
704
|
+
const loadGoogleMeetExportModule = createLazyRuntimeModule(() => import("./cli-export-D4IM6KLJ.mjs").then((n) => n.t));
|
|
777
705
|
async function createMeetFromParams(params) {
|
|
778
706
|
return (await loadGoogleMeetCreateModule()).createMeetFromParams(params);
|
|
779
707
|
}
|
|
@@ -781,7 +709,7 @@ async function createAndJoinMeetFromParams(params) {
|
|
|
781
709
|
return (await loadGoogleMeetCreateModule()).createAndJoinMeetFromParams(params);
|
|
782
710
|
}
|
|
783
711
|
async function resolveGoogleMeetTokenFromParams(config, raw) {
|
|
784
|
-
const { resolveGoogleMeetAccessToken } = await import("./oauth-
|
|
712
|
+
const { resolveGoogleMeetAccessToken } = await import("./oauth-BoyruWcS.mjs");
|
|
785
713
|
return resolveGoogleMeetAccessToken({
|
|
786
714
|
clientId: normalizeOptionalString(raw.clientId) ?? config.oauth.clientId,
|
|
787
715
|
clientSecret: normalizeOptionalString(raw.clientSecret) ?? config.oauth.clientSecret,
|
|
@@ -873,12 +801,8 @@ function fetchResolvedGoogleMeetAttendance(query) {
|
|
|
873
801
|
earlyBeforeMinutes: query.earlyBeforeMinutes
|
|
874
802
|
});
|
|
875
803
|
}
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
const [artifacts, attendance] = await Promise.all([fetchResolvedGoogleMeetArtifacts(resolved), fetchResolvedGoogleMeetAttendance(resolved)]);
|
|
879
|
-
const { buildGoogleMeetExportManifest, googleMeetExportFileNames, writeMeetExportBundle } = await loadGoogleMeetCliModule();
|
|
880
|
-
const calendarId = normalizeOptionalString(raw.calendarId);
|
|
881
|
-
const request = {
|
|
804
|
+
function buildGoogleMeetExportRequest(resolved, calendarId) {
|
|
805
|
+
return {
|
|
882
806
|
...resolved.meeting ? { meeting: resolved.meeting } : {},
|
|
883
807
|
...resolved.conferenceRecord ? { conferenceRecord: resolved.conferenceRecord } : {},
|
|
884
808
|
...resolved.calendarEvent?.event.id ? { calendarEventId: resolved.calendarEvent.event.id } : {},
|
|
@@ -892,34 +816,21 @@ async function exportGoogleMeetBundleFromParams(config, raw) {
|
|
|
892
816
|
...resolved.lateAfterMinutes !== void 0 ? { lateAfterMinutes: resolved.lateAfterMinutes } : {},
|
|
893
817
|
...resolved.earlyBeforeMinutes !== void 0 ? { earlyBeforeMinutes: resolved.earlyBeforeMinutes } : {}
|
|
894
818
|
};
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
return {
|
|
911
|
-
...await writeMeetExportBundle({
|
|
912
|
-
...outputDir ? { outputDir } : {},
|
|
913
|
-
artifacts,
|
|
914
|
-
attendance,
|
|
915
|
-
zip: raw.zip === true,
|
|
916
|
-
request,
|
|
917
|
-
tokenSource,
|
|
918
|
-
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {}
|
|
919
|
-
}),
|
|
920
|
-
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {},
|
|
921
|
-
tokenSource
|
|
922
|
-
};
|
|
819
|
+
}
|
|
820
|
+
async function exportGoogleMeetBundleFromParams(config, raw) {
|
|
821
|
+
const resolved = await resolveArtifactQueryFromParams(config, raw);
|
|
822
|
+
const [artifacts, attendance] = await Promise.all([fetchResolvedGoogleMeetArtifacts(resolved), fetchResolvedGoogleMeetAttendance(resolved)]);
|
|
823
|
+
const { exportGoogleMeetBundle } = await loadGoogleMeetExportModule();
|
|
824
|
+
return exportGoogleMeetBundle({
|
|
825
|
+
artifacts,
|
|
826
|
+
attendance,
|
|
827
|
+
request: buildGoogleMeetExportRequest(resolved, normalizeOptionalString(raw.calendarId)),
|
|
828
|
+
tokenSource: resolved.token.refreshed ? "refresh-token" : "cached-access-token",
|
|
829
|
+
calendarEvent: resolved.calendarEvent,
|
|
830
|
+
outputDir: normalizeOptionalString(raw.outputDir) ?? normalizeOptionalString(raw.output),
|
|
831
|
+
zip: raw.zip === true,
|
|
832
|
+
dryRun: raw.dryRun === true
|
|
833
|
+
});
|
|
923
834
|
}
|
|
924
835
|
//#endregion
|
|
925
|
-
export {
|
|
836
|
+
export { __exportAll as _, resolveArtifactQueryFromParams as a, resolveSpaceFromParams as c, endGoogleMeetActiveConference as d, fetchGoogleMeetSpace as f, readGoogleApiErrorDetail as g, listGoogleMeetCalendarEvents as h, plugin_helpers_exports as i, buildGoogleMeetPreflightReport as l, buildGoogleMeetCalendarDayWindow as m, fetchResolvedGoogleMeetArtifacts as n, resolveGoogleMeetTokenFromParams as o, fetchLatestGoogleMeetConferenceRecord as p, fetchResolvedGoogleMeetAttendance as r, resolveMeetingFromParams as s, buildGoogleMeetExportRequest as t, createGoogleMeetSpace as u };
|