@openclaw/google-meet 2026.10.1-beta.2 → 2026.10.5-beta.1
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/dist/.setup/{chrome-create-Bh1L33pr.mjs → chrome-create-CW_QQzuj.mjs} +27 -54
- package/dist/.setup/{cli-export-BOebaVFW.mjs → cli-export-DDUSzhh0.mjs} +31 -25
- package/dist/.setup/{cli-Bfm5LpNM.mjs → cli-vTuiXh8U.mjs} +75 -101
- package/dist/.setup/{create-DyYbmN11.mjs → create-0pfsnISA.mjs} +6 -4
- package/dist/.setup/{google-api-DEZ9mWx7.mjs → google-api-KAOF1Wn5.mjs} +5 -13
- package/dist/.setup/{google-meet-platform-adapter-CKXMbP3X.mjs → google-meet-platform-adapter-Bz77Bdt-.mjs} +2 -3
- package/dist/.setup/{meet-url-BP2Jlvjs.mjs → meet-url-i_QvIxnP.mjs} +2 -6
- package/dist/.setup/{node-host-CyFclhO_.mjs → node-host-BP4g4zw3.mjs} +4 -8
- package/dist/.setup/{node-invoke-policy-BnX3PaH7.mjs → node-invoke-policy-67WaZNPN.mjs} +1 -1
- package/dist/.setup/{oauth-XgdPFWEJ.mjs → oauth-pXa-YQ9H.mjs} +5 -6
- package/dist/.setup/{plugin-helpers-D1OyyzEZ.mjs → plugin-helpers-BhofFtQ0.mjs} +8 -12
- package/dist/.setup/{plugin-registration-BP83dqMw.mjs → plugin-registration-B_Ohay99.mjs} +19 -13
- package/dist/.setup/{runtime-DQgxZ2Na.mjs → runtime-B9xiaF9M.mjs} +25 -61
- package/dist/index.js +64 -91
- package/package.json +4 -4
|
@@ -24,25 +24,17 @@ async function callBrowserProxyOnNode(params) {
|
|
|
24
24
|
//#endregion
|
|
25
25
|
//#region extensions/google-meet/src/transports/google-meet-urls.ts
|
|
26
26
|
function forceMeetEnglishUi(url) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} catch {
|
|
32
|
-
return url;
|
|
33
|
-
}
|
|
27
|
+
const parsed = URL.parse(url);
|
|
28
|
+
if (!parsed) return url;
|
|
29
|
+
parsed.searchParams.set("hl", "en");
|
|
30
|
+
return parsed.toString();
|
|
34
31
|
}
|
|
35
32
|
function normalizeMeetUrlForReuse(url) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (!match?.[1]) return;
|
|
42
|
-
return `https://meet.google.com/${match[1].toLowerCase()}`;
|
|
43
|
-
} catch {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
33
|
+
const parsed = URL.parse(url ?? "");
|
|
34
|
+
if (parsed?.protocol !== "https:" || parsed.hostname.toLowerCase() !== "meet.google.com") return;
|
|
35
|
+
const match = parsed.pathname.match(/^\/([a-z]{3}-[a-z]{4}-[a-z]{3})(?:\/)?$/i);
|
|
36
|
+
if (!match?.[1]) return;
|
|
37
|
+
return `https://meet.google.com/${match[1].toLowerCase()}`;
|
|
46
38
|
}
|
|
47
39
|
function isSameMeetUrlForReuse(a, b) {
|
|
48
40
|
const normalizedA = normalizeMeetUrlForReuse(a);
|
|
@@ -50,21 +42,11 @@ function isSameMeetUrlForReuse(a, b) {
|
|
|
50
42
|
return Boolean(normalizedA && normalizedB && normalizedA === normalizedB);
|
|
51
43
|
}
|
|
52
44
|
function isEnglishMeetTab(url) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const parsed = new URL(url);
|
|
56
|
-
return parsed.protocol === "https:" && parsed.hostname.toLowerCase() === "meet.google.com" && parsed.searchParams.get("hl")?.toLowerCase() === "en";
|
|
57
|
-
} catch {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
45
|
+
const parsed = URL.parse(url ?? "");
|
|
46
|
+
return parsed?.protocol === "https:" && parsed.hostname.toLowerCase() === "meet.google.com" && parsed.searchParams.get("hl")?.toLowerCase() === "en";
|
|
60
47
|
}
|
|
61
48
|
function readMeetAuthUser(url) {
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
return new URL(url).searchParams.get("authuser") ?? void 0;
|
|
65
|
-
} catch {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
49
|
+
return URL.parse(url ?? "")?.searchParams.get("authuser") ?? void 0;
|
|
68
50
|
}
|
|
69
51
|
function isRecoverableMeetTab(tab, url) {
|
|
70
52
|
if (url) return isSameMeetUrlForReuse(tab.url, url);
|
|
@@ -189,44 +171,38 @@ async function createMeetWithBrowserProxyOnNode(params) {
|
|
|
189
171
|
});
|
|
190
172
|
const timeoutMs = Math.max(GOOGLE_MEET_BROWSER_CREATE_TIMEOUT_MS, params.config.chrome.joinTimeoutMs);
|
|
191
173
|
const stepTimeoutMs = Math.min(timeoutMs, GOOGLE_MEET_BROWSER_STEP_TIMEOUT_MS);
|
|
192
|
-
|
|
193
|
-
|
|
174
|
+
const callBrowser = (request) => callBrowserProxyOnNode({
|
|
175
|
+
...request,
|
|
194
176
|
runtime: params.runtime,
|
|
195
177
|
nodeId,
|
|
196
|
-
method: "GET",
|
|
197
|
-
path: "/tabs",
|
|
198
178
|
timeoutMs: stepTimeoutMs
|
|
179
|
+
});
|
|
180
|
+
let openedByPlugin = false;
|
|
181
|
+
let tab = asMeetingBrowserTabs(await callBrowser({
|
|
182
|
+
method: "GET",
|
|
183
|
+
path: "/tabs"
|
|
199
184
|
})).find(isGoogleMeetCreateTab);
|
|
200
185
|
if (tab?.targetId) {
|
|
201
|
-
await
|
|
202
|
-
runtime: params.runtime,
|
|
203
|
-
nodeId,
|
|
186
|
+
await callBrowser({
|
|
204
187
|
method: "POST",
|
|
205
188
|
path: "/tabs/focus",
|
|
206
|
-
body: { targetId: tab.targetId }
|
|
207
|
-
timeoutMs: stepTimeoutMs
|
|
189
|
+
body: { targetId: tab.targetId }
|
|
208
190
|
});
|
|
209
191
|
const reusedUrl = tab.url ?? "";
|
|
210
192
|
const englishUrl = (/^https:\/\/meet\.google\.com\/new(?:$|[/?#])/i.test(reusedUrl) || reusedUrl.startsWith("https://accounts.google.com/")) && reusedUrl ? forceMeetEnglishUi(reusedUrl) : void 0;
|
|
211
|
-
if (englishUrl && englishUrl !== reusedUrl) tab = readMeetingBrowserTab(await
|
|
212
|
-
runtime: params.runtime,
|
|
213
|
-
nodeId,
|
|
193
|
+
if (englishUrl && englishUrl !== reusedUrl) tab = readMeetingBrowserTab(await callBrowser({
|
|
214
194
|
method: "POST",
|
|
215
195
|
path: "/navigate",
|
|
216
196
|
body: {
|
|
217
197
|
targetId: tab.targetId,
|
|
218
198
|
url: englishUrl
|
|
219
|
-
}
|
|
220
|
-
timeoutMs: stepTimeoutMs
|
|
199
|
+
}
|
|
221
200
|
})) ?? tab;
|
|
222
201
|
} else {
|
|
223
|
-
tab = readMeetingBrowserTab(await
|
|
224
|
-
runtime: params.runtime,
|
|
225
|
-
nodeId,
|
|
202
|
+
tab = readMeetingBrowserTab(await callBrowser({
|
|
226
203
|
method: "POST",
|
|
227
204
|
path: "/tabs/open",
|
|
228
|
-
body: { url: forceMeetEnglishUi(GOOGLE_MEET_NEW_URL) }
|
|
229
|
-
timeoutMs: stepTimeoutMs
|
|
205
|
+
body: { url: forceMeetEnglishUi(GOOGLE_MEET_NEW_URL) }
|
|
230
206
|
}));
|
|
231
207
|
openedByPlugin = Boolean(tab?.targetId);
|
|
232
208
|
}
|
|
@@ -237,17 +213,14 @@ async function createMeetWithBrowserProxyOnNode(params) {
|
|
|
237
213
|
let lastError;
|
|
238
214
|
const deadline = Date.now() + timeoutMs;
|
|
239
215
|
while (Date.now() <= deadline) try {
|
|
240
|
-
const result = readBrowserCreateResult(await
|
|
241
|
-
runtime: params.runtime,
|
|
242
|
-
nodeId,
|
|
216
|
+
const result = readBrowserCreateResult(await callBrowser({
|
|
243
217
|
method: "POST",
|
|
244
218
|
path: "/act",
|
|
245
219
|
body: {
|
|
246
220
|
kind: "evaluate",
|
|
247
221
|
targetId,
|
|
248
222
|
fn: CREATE_MEET_FROM_BROWSER_SCRIPT
|
|
249
|
-
}
|
|
250
|
-
timeoutMs: stepTimeoutMs
|
|
223
|
+
}
|
|
251
224
|
}));
|
|
252
225
|
lastResult = result;
|
|
253
226
|
for (const note of result.notes ?? []) notes.add(note);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as __exportAll } from "./plugin-helpers-
|
|
1
|
+
import { g as __exportAll } from "./plugin-helpers-BhofFtQ0.mjs";
|
|
2
2
|
import { clampTimerTimeoutMs, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
3
3
|
import fsp, { stat } from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
@@ -6,7 +6,7 @@ import JSZip from "jszip";
|
|
|
6
6
|
import { replaceFileAtomic, writeExternalFileWithinRoot } from "openclaw/plugin-sdk/security-runtime";
|
|
7
7
|
import { createInterface } from "node:readline/promises";
|
|
8
8
|
import { format } from "node:util";
|
|
9
|
-
import { isGatewayClientRequestError, isGatewayTransportError } from "openclaw/plugin-sdk/gateway-runtime";
|
|
9
|
+
import { callGatewayFromCli, isGatewayClientRequestError, isGatewayTransportError } from "openclaw/plugin-sdk/gateway-runtime";
|
|
10
10
|
import { formatDurationCompact } from "openclaw/plugin-sdk/time-runtime";
|
|
11
11
|
//#region extensions/google-meet/src/cli-shared.ts
|
|
12
12
|
const GOOGLE_MEET_GATEWAY_DEFAULT_TIMEOUT_MS = 5e3;
|
|
@@ -116,7 +116,7 @@ async function callGoogleMeetGateway(params) {
|
|
|
116
116
|
const timeoutMs = resolveGoogleMeetGatewayTimeoutMs(params.timeoutMs);
|
|
117
117
|
return {
|
|
118
118
|
ok: true,
|
|
119
|
-
payload: await
|
|
119
|
+
payload: await callGatewayFromCli(params.method, {
|
|
120
120
|
json: true,
|
|
121
121
|
timeout: String(timeoutMs)
|
|
122
122
|
}, params.payload, { progress: false })
|
|
@@ -270,9 +270,9 @@ function appendArtifactSummary(lines, entry) {
|
|
|
270
270
|
if (smartNote.documentTextError) lines.push(`- smart note document body warning: ${smartNote.documentTextError}`);
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
|
-
function
|
|
273
|
+
function createReport(title, result, format) {
|
|
274
274
|
const markdown = format === "markdown";
|
|
275
|
-
const lines = markdown ? [
|
|
275
|
+
const lines = markdown ? [`# Google Meet ${title}`] : [];
|
|
276
276
|
const field = (label, value) => {
|
|
277
277
|
lines.push(`${markdown ? label : label.toLowerCase()}: ${value}`);
|
|
278
278
|
};
|
|
@@ -280,6 +280,14 @@ function renderAttendance(result, format) {
|
|
|
280
280
|
if (result.space) field("Space", result.space.name);
|
|
281
281
|
if (markdown) lines.push("");
|
|
282
282
|
field("Conference records", result.conferenceRecords.length);
|
|
283
|
+
return {
|
|
284
|
+
markdown,
|
|
285
|
+
lines,
|
|
286
|
+
field
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function renderAttendance(result, format) {
|
|
290
|
+
const { markdown, lines, field } = createReport("Attendance", result, format);
|
|
283
291
|
field("Attendance rows", result.attendance.length);
|
|
284
292
|
for (const row of result.attendance) {
|
|
285
293
|
const identity = row.displayName || row.user || row.participant;
|
|
@@ -334,15 +342,7 @@ function appendArtifactDocuments(lines, title, documents) {
|
|
|
334
342
|
}
|
|
335
343
|
}
|
|
336
344
|
function renderArtifacts(result, format) {
|
|
337
|
-
const markdown
|
|
338
|
-
const lines = markdown ? ["# Google Meet Artifacts"] : [];
|
|
339
|
-
const field = (label, value) => {
|
|
340
|
-
lines.push(`${markdown ? label : label.toLowerCase()}: ${value}`);
|
|
341
|
-
};
|
|
342
|
-
if (result.input) field("Input", result.input);
|
|
343
|
-
if (result.space) field("Space", result.space.name);
|
|
344
|
-
if (markdown) lines.push("");
|
|
345
|
-
field("Conference records", result.conferenceRecords.length);
|
|
345
|
+
const { markdown, lines, field } = createReport("Artifacts", result, format);
|
|
346
346
|
for (const entry of result.artifacts) {
|
|
347
347
|
lines.push("", `${markdown ? "##" : "record:"} ${entry.conferenceRecord.name}`);
|
|
348
348
|
field("Started", formatOptional(entry.conferenceRecord.startTime));
|
|
@@ -495,8 +495,23 @@ function collectGoogleMeetArtifactWarnings(result) {
|
|
|
495
495
|
return warnings;
|
|
496
496
|
}
|
|
497
497
|
function buildGoogleMeetExportManifest(params) {
|
|
498
|
-
const transcriptEntryCount = params.artifacts.artifacts.reduce((count, entry) => count + entry.transcriptEntries.reduce((entryCount, transcript) => entryCount + transcript.entries.length, 0), 0);
|
|
499
498
|
const warnings = collectGoogleMeetArtifactWarnings(params.artifacts);
|
|
499
|
+
const counts = {
|
|
500
|
+
conferenceRecords: params.artifacts.conferenceRecords.length,
|
|
501
|
+
artifacts: params.artifacts.artifacts.length,
|
|
502
|
+
attendanceRows: params.attendance.attendance.length,
|
|
503
|
+
recordings: 0,
|
|
504
|
+
transcripts: 0,
|
|
505
|
+
transcriptEntries: 0,
|
|
506
|
+
smartNotes: 0,
|
|
507
|
+
warnings: warnings.length
|
|
508
|
+
};
|
|
509
|
+
for (const entry of params.artifacts.artifacts) {
|
|
510
|
+
counts.recordings += entry.recordings.length;
|
|
511
|
+
counts.transcripts += entry.transcripts.length;
|
|
512
|
+
counts.smartNotes += entry.smartNotes.length;
|
|
513
|
+
for (const transcript of entry.transcriptEntries) counts.transcriptEntries += transcript.entries.length;
|
|
514
|
+
}
|
|
500
515
|
return {
|
|
501
516
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
502
517
|
...params.request ? { request: params.request } : {},
|
|
@@ -506,16 +521,7 @@ function buildGoogleMeetExportManifest(params) {
|
|
|
506
521
|
...params.artifacts.input ? { artifacts: params.artifacts.input } : {},
|
|
507
522
|
...params.attendance.input ? { attendance: params.attendance.input } : {}
|
|
508
523
|
},
|
|
509
|
-
counts
|
|
510
|
-
conferenceRecords: params.artifacts.conferenceRecords.length,
|
|
511
|
-
artifacts: params.artifacts.artifacts.length,
|
|
512
|
-
attendanceRows: params.attendance.attendance.length,
|
|
513
|
-
recordings: params.artifacts.artifacts.reduce((count, entry) => count + entry.recordings.length, 0),
|
|
514
|
-
transcripts: params.artifacts.artifacts.reduce((count, entry) => count + entry.transcripts.length, 0),
|
|
515
|
-
transcriptEntries: transcriptEntryCount,
|
|
516
|
-
smartNotes: params.artifacts.artifacts.reduce((count, entry) => count + entry.smartNotes.length, 0),
|
|
517
|
-
warnings: warnings.length
|
|
518
|
-
},
|
|
524
|
+
counts,
|
|
519
525
|
conferenceRecords: params.artifacts.conferenceRecords.map((record) => record.name),
|
|
520
526
|
files: params.files,
|
|
521
527
|
...params.zipFile ? { zipFile: params.zipFile } : {},
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { a as resolveArtifactQueryFromParams, c as resolveSpaceFromParams, d as endGoogleMeetActiveConference, f as fetchGoogleMeetSpace, h as listGoogleMeetCalendarEvents, l as buildGoogleMeetPreflightReport, m as buildGoogleMeetCalendarDayWindow, n as fetchResolvedGoogleMeetArtifacts, o as resolveGoogleMeetTokenFromParams, p as fetchLatestGoogleMeetConferenceRecord, r as fetchResolvedGoogleMeetAttendance, s as resolveMeetingFromParams, t as buildGoogleMeetExportRequest, u as createGoogleMeetSpace } from "./plugin-helpers-
|
|
1
|
+
import { a as resolveArtifactQueryFromParams, c as resolveSpaceFromParams, d as endGoogleMeetActiveConference, f as fetchGoogleMeetSpace, h as listGoogleMeetCalendarEvents, l as buildGoogleMeetPreflightReport, m as buildGoogleMeetCalendarDayWindow, n as fetchResolvedGoogleMeetArtifacts, o as resolveGoogleMeetTokenFromParams, p as fetchLatestGoogleMeetConferenceRecord, r as fetchResolvedGoogleMeetAttendance, s as resolveMeetingFromParams, t as buildGoogleMeetExportRequest, u as createGoogleMeetSpace } from "./plugin-helpers-BhofFtQ0.mjs";
|
|
2
2
|
import { i as resolveGoogleMeetGatewayOperationTimeoutMs } from "./config-BXGAMntj.mjs";
|
|
3
|
-
import { C as writeStdoutJson, S as writeSetupStatus, _ as resolveGoogleMeetOAuthCallbackTimeoutMs, a as renderAttendanceCsv, b as writeLeaveResult, c as callGoogleMeetGateway, d as parseGoogleMeetTransport, f as parseOptionalNumber, g as resolveCliJoinRequest, h as promptInput, i as renderAttendance, l as parseGoogleMeetBrowserTransport, m as parsePositiveNumber, n as exportGoogleMeetBundle, o as writeCalendarEventsSummary, p as parsePositiveIntegerOption, r as renderArtifacts, s as writeLatestConferenceRecordSummary, u as parseGoogleMeetMode, v as writeCliOutput, w as writeStdoutLine, x as writeRecoverCurrentTabResult, y as writeDoctorStatus } from "./cli-export-
|
|
4
|
-
import { buildGoogleMeetAuthUrl, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode } from "./oauth-
|
|
5
|
-
import {
|
|
3
|
+
import { C as writeStdoutJson, S as writeSetupStatus, _ as resolveGoogleMeetOAuthCallbackTimeoutMs, a as renderAttendanceCsv, b as writeLeaveResult, c as callGoogleMeetGateway, d as parseGoogleMeetTransport, f as parseOptionalNumber, g as resolveCliJoinRequest, h as promptInput, i as renderAttendance, l as parseGoogleMeetBrowserTransport, m as parsePositiveNumber, n as exportGoogleMeetBundle, o as writeCalendarEventsSummary, p as parsePositiveIntegerOption, r as renderArtifacts, s as writeLatestConferenceRecordSummary, u as parseGoogleMeetMode, v as writeCliOutput, w as writeStdoutLine, x as writeRecoverCurrentTabResult, y as writeDoctorStatus } from "./cli-export-DDUSzhh0.mjs";
|
|
4
|
+
import { buildGoogleMeetAuthUrl, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode } from "./oauth-pXa-YQ9H.mjs";
|
|
5
|
+
import { i as hasGoogleMeetOAuth, r as hasCreateSpaceConfigInput, t as createSpaceFromParams } from "./create-0pfsnISA.mjs";
|
|
6
6
|
import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
7
|
-
import { callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
|
|
8
7
|
import { generateHexPkceVerifierChallenge } from "openclaw/plugin-sdk/provider-auth";
|
|
9
8
|
import { generateOAuthState } from "openclaw/plugin-sdk/provider-auth-runtime";
|
|
10
9
|
//#region extensions/google-meet/src/cli-command-context.ts
|
|
@@ -20,9 +19,21 @@ function addGoogleMeetCalendarOptions(command) {
|
|
|
20
19
|
function addGoogleMeetArtifactOptions(command) {
|
|
21
20
|
return addGoogleMeetOAuthOptions(addGoogleMeetCalendarOptions(addGoogleMeetMeetingOption(command).option("--conference-record <name>", "Conference record name or id"))).option("--page-size <n>", "Max resources per Meet API page").option("--all-conference-records", "Fetch every conference record for --meeting");
|
|
22
21
|
}
|
|
22
|
+
function resolveCliMeetingInput(config, value) {
|
|
23
|
+
const meeting = value?.trim() || config.defaults.meeting;
|
|
24
|
+
if (!meeting) throw new Error("Meeting input is required. Pass a URL/meeting code or configure defaults.meeting.");
|
|
25
|
+
return meeting;
|
|
26
|
+
}
|
|
27
|
+
function resolveCliParams(options) {
|
|
28
|
+
const { calendar, expiresAt, ...raw } = options;
|
|
29
|
+
return {
|
|
30
|
+
...raw,
|
|
31
|
+
calendarId: calendar,
|
|
32
|
+
expiresAt: parseOptionalNumber(expiresAt)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
23
35
|
async function callGoogleMeetRuntime(context, method, payload, local, timeoutMs) {
|
|
24
36
|
const delegated = await callGoogleMeetGateway({
|
|
25
|
-
callGateway: context.callGateway,
|
|
26
37
|
method,
|
|
27
38
|
payload,
|
|
28
39
|
timeoutMs
|
|
@@ -32,7 +43,22 @@ async function callGoogleMeetRuntime(context, method, payload, local, timeoutMs)
|
|
|
32
43
|
//#endregion
|
|
33
44
|
//#region extensions/google-meet/src/cli-artifact-commands.ts
|
|
34
45
|
async function resolveCliArtifactQuery(context, options) {
|
|
35
|
-
const
|
|
46
|
+
const meeting = options.meeting?.trim() || context.config.defaults.meeting;
|
|
47
|
+
const conferenceRecord = options.conferenceRecord?.trim();
|
|
48
|
+
if (!meeting && !conferenceRecord && !(options.today || options.event?.trim())) throw new Error("Meeting input or conference record is required. Pass --meeting, --today, --event, --conference-record, or configure defaults.meeting.");
|
|
49
|
+
const { lateAfterMinutes: late, earlyBeforeMinutes: early, ...queryOptions } = options;
|
|
50
|
+
const raw = {
|
|
51
|
+
...resolveCliParams(queryOptions),
|
|
52
|
+
meeting,
|
|
53
|
+
conferenceRecord,
|
|
54
|
+
pageSize: parsePositiveIntegerOption(options.pageSize, "page-size"),
|
|
55
|
+
includeTranscriptEntries: options.transcriptEntries,
|
|
56
|
+
includeAllConferenceRecords: options.allConferenceRecords,
|
|
57
|
+
includeDocumentBodies: options.includeDocBodies,
|
|
58
|
+
mergeDuplicateParticipants: options.mergeDuplicates
|
|
59
|
+
};
|
|
60
|
+
const lateAfterMinutes = parseOptionalNumber(late);
|
|
61
|
+
const earlyBeforeMinutes = parseOptionalNumber(early);
|
|
36
62
|
return {
|
|
37
63
|
...await resolveArtifactQueryFromParams(context.config, raw),
|
|
38
64
|
lateAfterMinutes,
|
|
@@ -42,36 +68,28 @@ async function resolveCliArtifactQuery(context, options) {
|
|
|
42
68
|
function resolveTokenSource(refreshed) {
|
|
43
69
|
return refreshed ? "refresh-token" : "cached-access-token";
|
|
44
70
|
}
|
|
71
|
+
async function writeArtifactOutput(options, result, refreshed, render, csv) {
|
|
72
|
+
const tokenSource = resolveTokenSource(refreshed);
|
|
73
|
+
let text;
|
|
74
|
+
if (options.json) text = JSON.stringify({
|
|
75
|
+
...result,
|
|
76
|
+
tokenSource
|
|
77
|
+
}, null, 2);
|
|
78
|
+
else if (options.format === "markdown") text = render(result, "markdown");
|
|
79
|
+
else if (options.format === "csv" && csv) text = csv(result);
|
|
80
|
+
else if (!options.format || options.format === "summary") text = `${render(result, "summary")}token source: ${tokenSource}\n`;
|
|
81
|
+
else throw new Error(csv ? "Unsupported format. Expected summary, markdown, or csv." : "Unsupported format. Expected summary or markdown.");
|
|
82
|
+
await writeCliOutput(options, text);
|
|
83
|
+
}
|
|
45
84
|
function registerGoogleMeetArtifactCommands(context) {
|
|
46
85
|
const { root } = context;
|
|
47
86
|
addGoogleMeetArtifactOptions(root.command("artifacts").description("List Meet conference records and available participant/artifact metadata")).option("--no-transcript-entries", "Skip structured transcript entry lookup").option("--include-doc-bodies", "Export linked transcript and smart-note Google Docs text").option("--format <format>", "Output format: summary or markdown", "summary").option("--output <path>", "Write output to a file instead of stdout").option("--json", "Print JSON output", false).action(async (options) => {
|
|
48
87
|
const resolved = await resolveCliArtifactQuery(context, options);
|
|
49
|
-
|
|
50
|
-
const tokenSource = resolveTokenSource(resolved.token.refreshed);
|
|
51
|
-
let text;
|
|
52
|
-
if (options.json) text = JSON.stringify({
|
|
53
|
-
...result,
|
|
54
|
-
tokenSource
|
|
55
|
-
}, null, 2);
|
|
56
|
-
else if (options.format === "markdown") text = renderArtifacts(result, "markdown");
|
|
57
|
-
else if (!options.format || options.format === "summary") text = `${renderArtifacts(result, "summary")}token source: ${tokenSource}\n`;
|
|
58
|
-
else throw new Error("Unsupported format. Expected summary or markdown.");
|
|
59
|
-
await writeCliOutput(options, text);
|
|
88
|
+
await writeArtifactOutput(options, await fetchResolvedGoogleMeetArtifacts(resolved), resolved.token.refreshed, renderArtifacts);
|
|
60
89
|
});
|
|
61
90
|
addGoogleMeetArtifactOptions(root.command("attendance").description("List Meet participants and participant sessions")).option("--no-merge-duplicates", "Keep duplicate participant resources as separate rows").option("--late-after-minutes <n>", "Mark participants late after this many minutes", "5").option("--early-before-minutes <n>", "Mark early leavers before this many minutes", "5").option("--format <format>", "Output format: summary, markdown, or csv", "summary").option("--output <path>", "Write output to a file instead of stdout").option("--json", "Print JSON output", false).action(async (options) => {
|
|
62
91
|
const resolved = await resolveCliArtifactQuery(context, options);
|
|
63
|
-
|
|
64
|
-
const tokenSource = resolveTokenSource(resolved.token.refreshed);
|
|
65
|
-
let text;
|
|
66
|
-
if (options.json) text = JSON.stringify({
|
|
67
|
-
...result,
|
|
68
|
-
tokenSource
|
|
69
|
-
}, null, 2);
|
|
70
|
-
else if (options.format === "markdown") text = renderAttendance(result, "markdown");
|
|
71
|
-
else if (options.format === "csv") text = renderAttendanceCsv(result);
|
|
72
|
-
else if (!options.format || options.format === "summary") text = `${renderAttendance(result, "summary")}token source: ${tokenSource}\n`;
|
|
73
|
-
else throw new Error("Unsupported format. Expected summary, markdown, or csv.");
|
|
74
|
-
await writeCliOutput(options, text);
|
|
92
|
+
await writeArtifactOutput(options, await fetchResolvedGoogleMeetAttendance(resolved), resolved.token.refreshed, renderAttendance, renderAttendanceCsv);
|
|
75
93
|
});
|
|
76
94
|
addGoogleMeetArtifactOptions(root.command("export").description("Write Meet artifacts, attendance, transcript, and raw JSON into a folder")).option("--no-transcript-entries", "Skip structured transcript entry lookup").option("--include-doc-bodies", "Export linked transcript and smart-note Google Docs text").option("--no-merge-duplicates", "Keep duplicate participant resources as separate rows").option("--late-after-minutes <n>", "Mark participants late after this many minutes", "5").option("--early-before-minutes <n>", "Mark early leavers before this many minutes", "5").option("--output <dir>", "Output directory").option("--zip", "Also write a portable .zip archive").option("--dry-run", "Fetch export data and print the manifest without writing files", false).option("--json", "Print JSON output", false).action(async (options) => {
|
|
77
95
|
const resolved = await resolveCliArtifactQuery(context, options);
|
|
@@ -227,11 +245,10 @@ function registerGoogleMeetDoctorCommand(context) {
|
|
|
227
245
|
//#endregion
|
|
228
246
|
//#region extensions/google-meet/src/cli-runtime-commands.ts
|
|
229
247
|
function registerGoogleMeetProbeCommands(context) {
|
|
230
|
-
const { root,
|
|
248
|
+
const { root, operationTimeoutMs } = context;
|
|
231
249
|
root.command("join").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger after join").option("--dial-in-number <phone>", "Meet dial-in number for Twilio transport").option("--pin <pin>", "Meet phone PIN; # is appended if omitted").option("--dtmf-sequence <sequence>", "Explicit Twilio DTMF sequence").action(async (url, options) => {
|
|
232
|
-
const payload = resolveCliJoinRequest(
|
|
250
|
+
const payload = resolveCliJoinRequest(resolveCliMeetingInput(context.config, url), options);
|
|
233
251
|
const delegated = await callGoogleMeetGateway({
|
|
234
|
-
callGateway,
|
|
235
252
|
method: "googlemeet.join",
|
|
236
253
|
payload,
|
|
237
254
|
timeoutMs: operationTimeoutMs
|
|
@@ -246,7 +263,7 @@ function registerGoogleMeetProbeCommands(context) {
|
|
|
246
263
|
});
|
|
247
264
|
root.command("test-speech").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger", "Say exactly: Google Meet speech test complete.").action(async (url, options) => {
|
|
248
265
|
const payload = {
|
|
249
|
-
url:
|
|
266
|
+
url: resolveCliMeetingInput(context.config, url),
|
|
250
267
|
transport: parseGoogleMeetTransport(options.transport),
|
|
251
268
|
mode: parseGoogleMeetMode(options.mode),
|
|
252
269
|
message: options.message
|
|
@@ -255,7 +272,7 @@ function registerGoogleMeetProbeCommands(context) {
|
|
|
255
272
|
});
|
|
256
273
|
root.command("test-listen").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome or chrome-node").option("--timeout-ms <ms>", "How long to wait for fresh captions/transcript movement").action(async (url, options) => {
|
|
257
274
|
const payload = {
|
|
258
|
-
url:
|
|
275
|
+
url: resolveCliMeetingInput(context.config, url),
|
|
259
276
|
transport: parseGoogleMeetBrowserTransport(options.transport),
|
|
260
277
|
timeoutMs: parsePositiveNumber(options.timeoutMs, "timeout-ms")
|
|
261
278
|
};
|
|
@@ -339,11 +356,10 @@ function writeGoogleMeetCreateOutput(payload, json) {
|
|
|
339
356
|
writeStdoutLine(joinedSessionId ? "joined: %s" : "joined: no (run `openclaw googlemeet join %s`)", joinedSessionId ?? payload.meetingUri);
|
|
340
357
|
}
|
|
341
358
|
function registerGoogleMeetCreateCommands(context) {
|
|
342
|
-
const { root,
|
|
359
|
+
const { root, operationTimeoutMs } = context;
|
|
343
360
|
addGoogleMeetOAuthOptions(root.command("create").description("Create a new Google Meet space and print its meeting URL")).option("--access-type <type>", "Google Meet SpaceConfig accessType for API create: OPEN, TRUSTED, or RESTRICTED").option("--entry-point-access <type>", "Google Meet SpaceConfig entryPointAccess for API create: ALL or CREATOR_APP_ONLY").option("--no-join", "Only create the meeting URL; do not join it").option("--transport <transport>", "Join transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Join mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger after join").option("--dial-in-number <phone>", "Meet dial-in number for Twilio transport").option("--pin <pin>", "Meet phone PIN; # is appended if omitted").option("--dtmf-sequence <sequence>", "Explicit Twilio DTMF sequence").option("--json", "Print JSON output", false).action(async (options) => {
|
|
344
361
|
if (options.join !== false) {
|
|
345
362
|
const delegated = await callGoogleMeetGateway({
|
|
346
|
-
callGateway,
|
|
347
363
|
method: "googlemeet.create",
|
|
348
364
|
payload: { ...options },
|
|
349
365
|
timeoutMs: operationTimeoutMs
|
|
@@ -354,43 +370,43 @@ function registerGoogleMeetCreateCommands(context) {
|
|
|
354
370
|
return;
|
|
355
371
|
}
|
|
356
372
|
}
|
|
357
|
-
|
|
373
|
+
let runtime;
|
|
374
|
+
let created;
|
|
375
|
+
if (!hasGoogleMeetOAuth(context.config, options)) {
|
|
358
376
|
if (hasCreateSpaceConfigInput(options)) throw new Error("Google Meet access policy options require OAuth/API room creation. Configure Google Meet OAuth or remove --access-type/--entry-point-access.");
|
|
359
|
-
|
|
360
|
-
const result = await
|
|
361
|
-
|
|
362
|
-
writeGoogleMeetCreateOutput({
|
|
377
|
+
runtime = await context.ensureRuntime();
|
|
378
|
+
const result = await runtime.createViaBrowser();
|
|
379
|
+
created = {
|
|
363
380
|
source: result.source,
|
|
364
381
|
meetingUri: result.meetingUri,
|
|
365
|
-
joined: Boolean(join),
|
|
366
|
-
...join ? { join } : {},
|
|
367
382
|
browser: {
|
|
368
383
|
nodeId: result.nodeId,
|
|
369
384
|
targetId: result.targetId,
|
|
370
385
|
browserUrl: result.browserUrl,
|
|
371
386
|
browserTitle: result.browserTitle
|
|
372
387
|
}
|
|
373
|
-
}
|
|
374
|
-
|
|
388
|
+
};
|
|
389
|
+
} else {
|
|
390
|
+
const { token, source: _source, ...result } = await createSpaceFromParams(context.config, resolveCliParams(options));
|
|
391
|
+
created = {
|
|
392
|
+
...result,
|
|
393
|
+
tokenSource: token.refreshed ? "refresh-token" : "cached-access-token"
|
|
394
|
+
};
|
|
375
395
|
}
|
|
376
|
-
const
|
|
377
|
-
const result =
|
|
378
|
-
accessToken: token.accessToken,
|
|
379
|
-
config: resolveCreateSpaceConfig(options)
|
|
380
|
-
});
|
|
381
|
-
const join = options.join !== false ? await (await context.ensureRuntime()).join(resolveCliJoinRequest(result.meetingUri, options)) : void 0;
|
|
396
|
+
const join = options.join !== false ? await (runtime ?? await context.ensureRuntime()).join(resolveCliJoinRequest(created.meetingUri, options)) : void 0;
|
|
397
|
+
const { browser, ...result } = created;
|
|
382
398
|
writeGoogleMeetCreateOutput({
|
|
383
399
|
...result,
|
|
384
|
-
tokenSource: token.refreshed ? "refresh-token" : "cached-access-token",
|
|
385
400
|
joined: Boolean(join),
|
|
386
|
-
...join ? { join } : {}
|
|
401
|
+
...join ? { join } : {},
|
|
402
|
+
...browser ? { browser } : {}
|
|
387
403
|
}, options.json);
|
|
388
404
|
});
|
|
389
405
|
addGoogleMeetOAuthOptions(root.command("end-active-conference").description("End the active conference for a Google Meet space").argument("[meeting]", "Meet URL, meeting code, or spaces/{id}")).option("--json", "Print JSON output", false).action(async (meeting, options) => {
|
|
390
406
|
const token = await resolveGoogleMeetTokenFromParams(context.config, resolveCliParams(options));
|
|
391
407
|
const result = await endGoogleMeetActiveConference({
|
|
392
408
|
accessToken: token.accessToken,
|
|
393
|
-
meeting:
|
|
409
|
+
meeting: resolveCliMeetingInput(context.config, meeting ?? options.meeting)
|
|
394
410
|
});
|
|
395
411
|
if (options.json) {
|
|
396
412
|
writeStdoutJson({
|
|
@@ -405,9 +421,9 @@ function registerGoogleMeetCreateCommands(context) {
|
|
|
405
421
|
});
|
|
406
422
|
}
|
|
407
423
|
function registerGoogleMeetApiCommands(context) {
|
|
408
|
-
const { root
|
|
424
|
+
const { root } = context;
|
|
409
425
|
addGoogleMeetOAuthOptions(addGoogleMeetMeetingOption(root.command("resolve-space").description("Resolve a Meet URL, meeting code, or spaces/{id} to its canonical space"))).option("--json", "Print JSON output", false).action(async (options) => {
|
|
410
|
-
const meeting =
|
|
426
|
+
const meeting = resolveCliMeetingInput(context.config, options.meeting);
|
|
411
427
|
const { space, token } = await resolveSpaceFromParams(context.config, {
|
|
412
428
|
...resolveCliParams(options),
|
|
413
429
|
meeting
|
|
@@ -424,7 +440,7 @@ function registerGoogleMeetApiCommands(context) {
|
|
|
424
440
|
writeStdoutLine("token source: %s", token.refreshed ? "refresh-token" : "cached-access-token");
|
|
425
441
|
});
|
|
426
442
|
addGoogleMeetOAuthOptions(addGoogleMeetMeetingOption(root.command("preflight").description("Validate OAuth + meeting resolution prerequisites for Meet media work"))).option("--json", "Print JSON output", false).action(async (options) => {
|
|
427
|
-
const meeting =
|
|
443
|
+
const meeting = resolveCliMeetingInput(context.config, options.meeting);
|
|
428
444
|
const { space, token } = await resolveSpaceFromParams(context.config, {
|
|
429
445
|
...resolveCliParams(options),
|
|
430
446
|
meeting
|
|
@@ -508,44 +524,7 @@ function registerGoogleMeetApiCommands(context) {
|
|
|
508
524
|
}
|
|
509
525
|
//#endregion
|
|
510
526
|
//#region extensions/google-meet/src/cli.ts
|
|
511
|
-
function resolveMeetingInput(config, value) {
|
|
512
|
-
const meeting = value?.trim() || config.defaults.meeting;
|
|
513
|
-
if (!meeting) throw new Error("Meeting input is required. Pass a URL/meeting code or configure defaults.meeting.");
|
|
514
|
-
return meeting;
|
|
515
|
-
}
|
|
516
|
-
function hasCalendarLookupOptions(options) {
|
|
517
|
-
return Boolean(options.today || options.event?.trim());
|
|
518
|
-
}
|
|
519
|
-
function resolveCliParams(options) {
|
|
520
|
-
const { calendar, expiresAt, ...raw } = options;
|
|
521
|
-
return {
|
|
522
|
-
...raw,
|
|
523
|
-
calendarId: calendar,
|
|
524
|
-
expiresAt: parseOptionalNumber(expiresAt)
|
|
525
|
-
};
|
|
526
|
-
}
|
|
527
|
-
function resolveCliArtifactParams(config, options) {
|
|
528
|
-
const meeting = options.meeting?.trim() || config.defaults.meeting;
|
|
529
|
-
const conferenceRecord = options.conferenceRecord?.trim();
|
|
530
|
-
if (!meeting && !conferenceRecord && !hasCalendarLookupOptions(options)) throw new Error("Meeting input or conference record is required. Pass --meeting, --today, --event, --conference-record, or configure defaults.meeting.");
|
|
531
|
-
return {
|
|
532
|
-
...resolveCliParams(options),
|
|
533
|
-
meeting,
|
|
534
|
-
conferenceRecord,
|
|
535
|
-
pageSize: parsePositiveIntegerOption(options.pageSize, "page-size"),
|
|
536
|
-
includeTranscriptEntries: options.transcriptEntries,
|
|
537
|
-
includeAllConferenceRecords: options.allConferenceRecords,
|
|
538
|
-
includeDocumentBodies: options.includeDocBodies,
|
|
539
|
-
mergeDuplicateParticipants: options.mergeDuplicates,
|
|
540
|
-
lateAfterMinutes: parseOptionalNumber(options.lateAfterMinutes),
|
|
541
|
-
earlyBeforeMinutes: parseOptionalNumber(options.earlyBeforeMinutes)
|
|
542
|
-
};
|
|
543
|
-
}
|
|
544
|
-
function hasCreateOAuth(config, options) {
|
|
545
|
-
return Boolean(options.accessToken?.trim() || options.refreshToken?.trim() || config.oauth.accessToken || config.oauth.refreshToken);
|
|
546
|
-
}
|
|
547
527
|
function registerGoogleMeetCli(params) {
|
|
548
|
-
const callGateway = params.callGatewayFromCli ?? callGatewayFromCli;
|
|
549
528
|
const operationTimeoutMs = resolveGoogleMeetGatewayOperationTimeoutMs(params.config);
|
|
550
529
|
const root = params.program.command("googlemeet").description("Google Meet participant utilities").addHelpText("after", () => `\nDocs: https://docs.openclaw.ai/plugins/google-meet\n`);
|
|
551
530
|
root.command("auth").description("Google Meet OAuth helpers").command("login").description("Run a PKCE OAuth flow and print refresh-token JSON to store in plugin config").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--manual", "Use copy/paste callback flow instead of localhost callback").option("--json", "Print the token payload as JSON", false).option("--timeout-sec <n>", "Local callback timeout in seconds", "300").action(async (options) => {
|
|
@@ -592,12 +571,7 @@ function registerGoogleMeetCli(params) {
|
|
|
592
571
|
root,
|
|
593
572
|
config: params.config,
|
|
594
573
|
ensureRuntime: params.ensureRuntime,
|
|
595
|
-
|
|
596
|
-
operationTimeoutMs,
|
|
597
|
-
resolveMeetingInput,
|
|
598
|
-
resolveCliParams,
|
|
599
|
-
resolveCliArtifactParams: (options) => resolveCliArtifactParams(params.config, options),
|
|
600
|
-
hasCreateOAuth
|
|
574
|
+
operationTimeoutMs
|
|
601
575
|
};
|
|
602
576
|
registerGoogleMeetCreateCommands(context);
|
|
603
577
|
registerGoogleMeetProbeCommands(context);
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { g as __exportAll, o as resolveGoogleMeetTokenFromParams, u as createGoogleMeetSpace } from "./plugin-helpers-
|
|
2
|
-
import { d as normalizeMode, f as normalizeTransport } from "./plugin-registration-
|
|
3
|
-
import { t as createMeetWithBrowserProxyOnNode } from "./chrome-create-
|
|
1
|
+
import { g as __exportAll, o as resolveGoogleMeetTokenFromParams, u as createGoogleMeetSpace } from "./plugin-helpers-BhofFtQ0.mjs";
|
|
2
|
+
import { d as normalizeMode, f as normalizeTransport } from "./plugin-registration-B_Ohay99.mjs";
|
|
3
|
+
import { t as createMeetWithBrowserProxyOnNode } from "./chrome-create-CW_QQzuj.mjs";
|
|
4
4
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
//#region extensions/google-meet/src/create.ts
|
|
6
6
|
var create_exports = /* @__PURE__ */ __exportAll({
|
|
7
7
|
createAndJoinMeetFromParams: () => createAndJoinMeetFromParams,
|
|
8
8
|
createMeetFromParams: () => createMeetFromParams,
|
|
9
|
+
createSpaceFromParams: () => createSpaceFromParams,
|
|
9
10
|
hasCreateSpaceConfigInput: () => hasCreateSpaceConfigInput,
|
|
11
|
+
hasGoogleMeetOAuth: () => hasGoogleMeetOAuth,
|
|
10
12
|
resolveCreateSpaceConfig: () => resolveCreateSpaceConfig
|
|
11
13
|
});
|
|
12
14
|
function normalizeGoogleMeetAccessType(value) {
|
|
@@ -100,4 +102,4 @@ async function createAndJoinMeetFromParams(params) {
|
|
|
100
102
|
};
|
|
101
103
|
}
|
|
102
104
|
//#endregion
|
|
103
|
-
export {
|
|
105
|
+
export { hasGoogleMeetOAuth as i, create_exports as n, hasCreateSpaceConfigInput as r, createSpaceFromParams as t };
|
|
@@ -3,17 +3,9 @@ import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
|
3
3
|
//#region extensions/google-meet/src/google-api.ts
|
|
4
4
|
const REAUTH_HINT = "Re-run `openclaw googlemeet auth login` and store the refreshed oauth block.";
|
|
5
5
|
const GOOGLE_API_ERROR_BODY_LIMIT_BYTES = 8192;
|
|
6
|
-
function scopeText(scopes) {
|
|
7
|
-
return scopes.map((scope) => `\`${scope}\``).join(", ");
|
|
8
|
-
}
|
|
9
6
|
async function readGoogleApiErrorDetail(response) {
|
|
10
7
|
return await readResponseTextLimited(response, GOOGLE_API_ERROR_BODY_LIMIT_BYTES);
|
|
11
8
|
}
|
|
12
|
-
async function googleApiError(params) {
|
|
13
|
-
const detail = await readGoogleApiErrorDetail(params.response);
|
|
14
|
-
const scopeHint = params.scopes && params.scopes.length > 0 ? ` Required OAuth scope: ${scopeText(params.scopes)}. ${REAUTH_HINT}` : "";
|
|
15
|
-
return /* @__PURE__ */ new Error(`${params.prefix} failed (${params.response.status}): ${detail}${scopeHint}`);
|
|
16
|
-
}
|
|
17
9
|
function appendQuery(url, query) {
|
|
18
10
|
if (!query) return url;
|
|
19
11
|
const parsed = new URL(url);
|
|
@@ -36,11 +28,11 @@ async function requestGoogleApi(params, read) {
|
|
|
36
28
|
timeoutMs: 3e4
|
|
37
29
|
});
|
|
38
30
|
try {
|
|
39
|
-
if (!response.ok)
|
|
40
|
-
response
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
const detail = await readGoogleApiErrorDetail(response);
|
|
33
|
+
const scopeHint = params.scopes && params.scopes.length > 0 ? ` Required OAuth scope: ${params.scopes.map((scope) => `\`${scope}\``).join(", ")}. ${REAUTH_HINT}` : "";
|
|
34
|
+
throw new Error(`${params.prefix} failed (${response.status}): ${detail}${scopeHint}`);
|
|
35
|
+
}
|
|
44
36
|
return await read(response);
|
|
45
37
|
} finally {
|
|
46
38
|
await release();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as GOOGLE_MEET_NODE_COMMAND } from "./google-meet-platform-constants-CnRfrYX7.mjs";
|
|
2
|
-
import { t as normalizeMeetUrl } from "./meet-url-
|
|
3
|
-
import { a as isSameMeetUrlForReuse, i as isRecoverableMeetTab, n as forceMeetEnglishUi, o as normalizeMeetUrlForReuse, r as isEnglishMeetTab, s as readMeetAuthUser, t as createMeetWithBrowserProxyOnNode } from "./chrome-create-
|
|
2
|
+
import { t as normalizeMeetUrl } from "./meet-url-i_QvIxnP.mjs";
|
|
3
|
+
import { a as isSameMeetUrlForReuse, i as isRecoverableMeetTab, n as forceMeetEnglishUi, o as normalizeMeetUrlForReuse, r as isEnglishMeetTab, s as readMeetAuthUser, t as createMeetWithBrowserProxyOnNode } from "./chrome-create-CW_QQzuj.mjs";
|
|
4
4
|
import { asRecord, filterStringEntries, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
6
6
|
import { MeetingPlatformAdapter } from "openclaw/plugin-sdk/meeting-runtime";
|
|
@@ -804,7 +804,6 @@ function buildMeetDtmfSequence(params) {
|
|
|
804
804
|
function prefixDtmfWait(sequence, delayMs) {
|
|
805
805
|
if (!sequence || delayMs <= 0) return sequence;
|
|
806
806
|
const waitCount = Math.ceil(delayMs / 500);
|
|
807
|
-
if (waitCount <= 0) return sequence;
|
|
808
807
|
return `${"w".repeat(waitCount)}${sequence}`;
|
|
809
808
|
}
|
|
810
809
|
//#endregion
|
|
@@ -3,12 +3,8 @@ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runti
|
|
|
3
3
|
function normalizeMeetUrl(input) {
|
|
4
4
|
const raw = normalizeOptionalString(input);
|
|
5
5
|
if (!raw) throw new Error("url required");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
url = new URL(raw);
|
|
9
|
-
} catch {
|
|
10
|
-
throw new Error("url must be a valid Google Meet URL");
|
|
11
|
-
}
|
|
6
|
+
const url = URL.parse(raw);
|
|
7
|
+
if (!url) throw new Error("url must be a valid Google Meet URL");
|
|
12
8
|
if (url.protocol !== "https:" || url.hostname.toLowerCase() !== "meet.google.com" || url.port || url.username || url.password) throw new Error("url must be an explicit https://meet.google.com/... URL");
|
|
13
9
|
if (!/^\/[a-z]{3}-[a-z]{4}-[a-z]{3}(?:$|[/?#])/i.test(url.pathname)) throw new Error("url must include a Google Meet meeting code");
|
|
14
10
|
return url.toString();
|