@openclaw/google-meet 2026.7.2-beta.5 → 2026.8.1-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/dist/chrome-create-PKAyxCiL.js +325 -0
- package/dist/{cli-GeuAaEIy.js → cli-o7RWVqDb.js} +166 -234
- package/dist/{config-BcaS1BDr.js → config-wBK8loBb.js} +97 -221
- package/dist/{create-af1MDlus.js → create-UHeaRzsH.js} +3 -14
- package/dist/google-meet-platform-adapter-C3J-iFRE.js +791 -0
- package/dist/google-meet-platform-constants-Bs5iAg3E.js +25 -0
- package/dist/index.js +185 -2639
- package/dist/meet-url-BP2Jlvjs.js +17 -0
- package/dist/node-host-BXtXbsMa.js +49 -0
- package/dist/node-invoke-policy-B0gOlLJR.js +24 -0
- package/dist/{oauth-DOfMKlGp.js → oauth-9sUJ68Mw.js} +3 -14
- package/dist/{chrome-create-DMKruRFW.js → plugin-helpers-CfeT1SYY.js} +335 -355
- package/dist/plugin-registration-rSOssQmm.js +141 -0
- package/dist/runtime-B8d1beHo.js +1308 -0
- package/openclaw.plugin.json +8 -47
- package/package.json +4 -4
- /package/node_modules/{core-util-is → jszip/node_modules/core-util-is}/LICENSE +0 -0
- /package/node_modules/{core-util-is → jszip/node_modules/core-util-is}/README.md +0 -0
- /package/node_modules/{core-util-is → jszip/node_modules/core-util-is}/lib/util.js +0 -0
- /package/node_modules/{core-util-is → jszip/node_modules/core-util-is}/package.json +0 -0
- /package/node_modules/{immediate → jszip/node_modules/immediate}/LICENSE.txt +0 -0
- /package/node_modules/{immediate → jszip/node_modules/immediate}/README.md +0 -0
- /package/node_modules/{immediate → jszip/node_modules/immediate}/dist/immediate.js +0 -0
- /package/node_modules/{immediate → jszip/node_modules/immediate}/dist/immediate.min.js +0 -0
- /package/node_modules/{immediate → jszip/node_modules/immediate}/lib/browser.js +0 -0
- /package/node_modules/{immediate → jszip/node_modules/immediate}/lib/index.js +0 -0
- /package/node_modules/{immediate → jszip/node_modules/immediate}/package.json +0 -0
- /package/node_modules/{inherits → jszip/node_modules/inherits}/LICENSE +0 -0
- /package/node_modules/{inherits → jszip/node_modules/inherits}/README.md +0 -0
- /package/node_modules/{inherits → jszip/node_modules/inherits}/inherits.js +0 -0
- /package/node_modules/{inherits → jszip/node_modules/inherits}/inherits_browser.js +0 -0
- /package/node_modules/{inherits → jszip/node_modules/inherits}/package.json +0 -0
- /package/node_modules/{isarray → jszip/node_modules/isarray}/.npmignore +0 -0
- /package/node_modules/{isarray → jszip/node_modules/isarray}/.travis.yml +0 -0
- /package/node_modules/{isarray → jszip/node_modules/isarray}/Makefile +0 -0
- /package/node_modules/{isarray → jszip/node_modules/isarray}/README.md +0 -0
- /package/node_modules/{isarray → jszip/node_modules/isarray}/component.json +0 -0
- /package/node_modules/{isarray → jszip/node_modules/isarray}/index.js +0 -0
- /package/node_modules/{isarray → jszip/node_modules/isarray}/package.json +0 -0
- /package/node_modules/{isarray → jszip/node_modules/isarray}/test.js +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/README.md +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/dist/lie.js +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/dist/lie.min.js +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/dist/lie.polyfill.js +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/dist/lie.polyfill.min.js +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/lib/browser.js +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/lib/index.js +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/license.md +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/lie.d.ts +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/package.json +0 -0
- /package/node_modules/{lie → jszip/node_modules/lie}/polyfill.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/CHANGELOG.md +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/LICENSE +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/README.md +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/dist/pako.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/dist/pako.min.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/dist/pako_deflate.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/dist/pako_deflate.min.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/dist/pako_inflate.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/dist/pako_inflate.min.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/index.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/deflate.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/inflate.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/utils/common.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/utils/strings.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/README +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/adler32.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/constants.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/crc32.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/deflate.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/gzheader.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/inffast.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/inflate.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/inftrees.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/messages.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/trees.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/lib/zlib/zstream.js +0 -0
- /package/node_modules/{pako → jszip/node_modules/pako}/package.json +0 -0
- /package/node_modules/{process-nextick-args → jszip/node_modules/process-nextick-args}/index.js +0 -0
- /package/node_modules/{process-nextick-args → jszip/node_modules/process-nextick-args}/license.md +0 -0
- /package/node_modules/{process-nextick-args → jszip/node_modules/process-nextick-args}/package.json +0 -0
- /package/node_modules/{process-nextick-args → jszip/node_modules/process-nextick-args}/readme.md +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/.travis.yml +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/CONTRIBUTING.md +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/GOVERNANCE.md +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/LICENSE +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/README.md +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/doc/wg-meetings/2015-01-30.md +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/duplex-browser.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/duplex.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/lib/_stream_duplex.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/lib/_stream_passthrough.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/lib/_stream_readable.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/lib/_stream_transform.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/lib/_stream_writable.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/lib/internal/streams/BufferList.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/lib/internal/streams/destroy.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/lib/internal/streams/stream-browser.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/lib/internal/streams/stream.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/package.json +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/passthrough.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/readable-browser.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/readable.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/transform.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/writable-browser.js +0 -0
- /package/node_modules/{readable-stream → jszip/node_modules/readable-stream}/writable.js +0 -0
- /package/node_modules/{safe-buffer → jszip/node_modules/safe-buffer}/LICENSE +0 -0
- /package/node_modules/{safe-buffer → jszip/node_modules/safe-buffer}/README.md +0 -0
- /package/node_modules/{safe-buffer → jszip/node_modules/safe-buffer}/index.d.ts +0 -0
- /package/node_modules/{safe-buffer → jszip/node_modules/safe-buffer}/index.js +0 -0
- /package/node_modules/{safe-buffer → jszip/node_modules/safe-buffer}/package.json +0 -0
- /package/node_modules/{setimmediate → jszip/node_modules/setimmediate}/LICENSE.txt +0 -0
- /package/node_modules/{setimmediate → jszip/node_modules/setimmediate}/package.json +0 -0
- /package/node_modules/{setimmediate → jszip/node_modules/setimmediate}/setImmediate.js +0 -0
- /package/node_modules/{string_decoder → jszip/node_modules/string_decoder}/.travis.yml +0 -0
- /package/node_modules/{string_decoder → jszip/node_modules/string_decoder}/LICENSE +0 -0
- /package/node_modules/{string_decoder → jszip/node_modules/string_decoder}/README.md +0 -0
- /package/node_modules/{string_decoder → jszip/node_modules/string_decoder}/lib/string_decoder.js +0 -0
- /package/node_modules/{string_decoder → jszip/node_modules/string_decoder}/package.json +0 -0
- /package/node_modules/{util-deprecate → jszip/node_modules/util-deprecate}/History.md +0 -0
- /package/node_modules/{util-deprecate → jszip/node_modules/util-deprecate}/LICENSE +0 -0
- /package/node_modules/{util-deprecate → jszip/node_modules/util-deprecate}/README.md +0 -0
- /package/node_modules/{util-deprecate → jszip/node_modules/util-deprecate}/browser.js +0 -0
- /package/node_modules/{util-deprecate → jszip/node_modules/util-deprecate}/node.js +0 -0
- /package/node_modules/{util-deprecate → jszip/node_modules/util-deprecate}/package.json +0 -0
- /package/node_modules/{parse-ms → pretty-ms/node_modules/parse-ms}/index.d.ts +0 -0
- /package/node_modules/{parse-ms → pretty-ms/node_modules/parse-ms}/index.js +0 -0
- /package/node_modules/{parse-ms → pretty-ms/node_modules/parse-ms}/license +0 -0
- /package/node_modules/{parse-ms → pretty-ms/node_modules/parse-ms}/package.json +0 -0
- /package/node_modules/{parse-ms → pretty-ms/node_modules/parse-ms}/readme.md +0 -0
|
@@ -1,9 +1,174 @@
|
|
|
1
|
+
import { c as loadGoogleMeetCliModule, p as resolveMeetingInput } from "./plugin-registration-rSOssQmm.js";
|
|
1
2
|
import { t as googleApiError } from "./google-api-errors-CDUYkIcK.js";
|
|
2
|
-
import {
|
|
3
|
+
import { t as normalizeMeetUrl } from "./meet-url-BP2Jlvjs.js";
|
|
4
|
+
import { normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
|
+
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
6
|
+
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
7
|
+
import { parseDateStringTimestampMs } from "openclaw/plugin-sdk/number-runtime";
|
|
8
|
+
import { readPositiveIntegerParam } from "openclaw/plugin-sdk/channel-actions";
|
|
3
9
|
import { readProviderJsonResponse, readProviderTextResponse } from "openclaw/plugin-sdk/provider-http";
|
|
4
10
|
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
5
|
-
|
|
6
|
-
|
|
11
|
+
//#region \0rolldown/runtime.js
|
|
12
|
+
var __defProp = Object.defineProperty;
|
|
13
|
+
var __exportAll = (all, no_symbols) => {
|
|
14
|
+
let target = {};
|
|
15
|
+
for (var name in all) __defProp(target, name, {
|
|
16
|
+
get: all[name],
|
|
17
|
+
enumerable: true
|
|
18
|
+
});
|
|
19
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
20
|
+
return target;
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region extensions/google-meet/src/calendar.ts
|
|
24
|
+
const GOOGLE_CALENDAR_API_BASE_URL = "https://www.googleapis.com/calendar/v3";
|
|
25
|
+
const GOOGLE_CALENDAR_API_HOST = "www.googleapis.com";
|
|
26
|
+
const GOOGLE_CALENDAR_EVENTS_SCOPE = "https://www.googleapis.com/auth/calendar.events.readonly";
|
|
27
|
+
const GOOGLE_CALENDAR_REQUEST_TIMEOUT_MS = 3e4;
|
|
28
|
+
function appendQuery$2(url, query) {
|
|
29
|
+
const parsed = new URL(url);
|
|
30
|
+
for (const [key, value] of Object.entries(query)) if (value !== void 0) parsed.searchParams.set(key, String(value));
|
|
31
|
+
return parsed.toString();
|
|
32
|
+
}
|
|
33
|
+
function normalizeGoogleMeetCalendarUri(value) {
|
|
34
|
+
if (!value?.trim()) return;
|
|
35
|
+
try {
|
|
36
|
+
const url = new URL(value);
|
|
37
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return;
|
|
38
|
+
if (url.hostname.toLowerCase() !== "meet.google.com" || url.port || url.username || url.password) return;
|
|
39
|
+
url.protocol = "https:";
|
|
40
|
+
return normalizeMeetUrl(url.toString());
|
|
41
|
+
} catch {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function extractGoogleMeetUriFromText(value) {
|
|
46
|
+
const matches = value?.matchAll(/https:\/\/meet\.google\.com\/[a-z0-9-]+/gi);
|
|
47
|
+
for (const match of matches ?? []) {
|
|
48
|
+
const uri = normalizeGoogleMeetCalendarUri(match[0]);
|
|
49
|
+
if (uri) return uri;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function findFirstGoogleMeetCalendarUri(entryPoints, predicate = () => true) {
|
|
53
|
+
for (const entry of entryPoints) {
|
|
54
|
+
if (!predicate(entry)) continue;
|
|
55
|
+
const uri = normalizeGoogleMeetCalendarUri(entry.uri);
|
|
56
|
+
if (uri) return uri;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function extractGoogleMeetUriFromCalendarEvent(event) {
|
|
60
|
+
const hangoutLink = normalizeGoogleMeetCalendarUri(event.hangoutLink);
|
|
61
|
+
if (hangoutLink) return hangoutLink;
|
|
62
|
+
const entryPoints = event.conferenceData?.entryPoints ?? [];
|
|
63
|
+
const videoEntryUri = findFirstGoogleMeetCalendarUri(entryPoints, (entry) => entry.entryPointType === "video");
|
|
64
|
+
if (videoEntryUri) return videoEntryUri;
|
|
65
|
+
const meetEntryUri = findFirstGoogleMeetCalendarUri(entryPoints);
|
|
66
|
+
if (meetEntryUri) return meetEntryUri;
|
|
67
|
+
return extractGoogleMeetUriFromText(event.location) ?? extractGoogleMeetUriFromText(event.description);
|
|
68
|
+
}
|
|
69
|
+
function buildGoogleMeetCalendarDayWindow(now = /* @__PURE__ */ new Date()) {
|
|
70
|
+
const start = new Date(now);
|
|
71
|
+
start.setHours(0, 0, 0, 0);
|
|
72
|
+
const end = new Date(start);
|
|
73
|
+
end.setDate(start.getDate() + 1);
|
|
74
|
+
return {
|
|
75
|
+
timeMin: start.toISOString(),
|
|
76
|
+
timeMax: end.toISOString()
|
|
77
|
+
};
|
|
78
|
+
}
|
|
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
|
+
function rankCalendarEvent(event, nowMs) {
|
|
86
|
+
const startMs = parseCalendarEventTime(event.start) ?? Number.POSITIVE_INFINITY;
|
|
87
|
+
const endMs = parseCalendarEventTime(event.end) ?? startMs;
|
|
88
|
+
if (startMs <= nowMs && endMs >= nowMs) return 0;
|
|
89
|
+
if (startMs > nowMs) return startMs - nowMs;
|
|
90
|
+
return nowMs - startMs + 720 * 60 * 60 * 1e3;
|
|
91
|
+
}
|
|
92
|
+
function chooseBestMeetCalendarEvent(events, now) {
|
|
93
|
+
const nowMs = now.getTime();
|
|
94
|
+
let selected;
|
|
95
|
+
let selectedRank = Number.POSITIVE_INFINITY;
|
|
96
|
+
for (const event of events) {
|
|
97
|
+
if (event.status === "cancelled" || !extractGoogleMeetUriFromCalendarEvent(event)) continue;
|
|
98
|
+
const rank = rankCalendarEvent(event, nowMs);
|
|
99
|
+
if (!selected || rank < selectedRank) {
|
|
100
|
+
selected = event;
|
|
101
|
+
selectedRank = rank;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return selected;
|
|
105
|
+
}
|
|
106
|
+
async function fetchGoogleCalendarEvents(params) {
|
|
107
|
+
const calendarId = params.calendarId?.trim() || "primary";
|
|
108
|
+
const now = params.now ?? /* @__PURE__ */ new Date();
|
|
109
|
+
const defaultTimeMax = new Date(now);
|
|
110
|
+
defaultTimeMax.setDate(defaultTimeMax.getDate() + 7);
|
|
111
|
+
const { response, release } = await fetchWithSsrFGuard({
|
|
112
|
+
url: appendQuery$2(`${GOOGLE_CALENDAR_API_BASE_URL}/calendars/${encodeURIComponent(calendarId)}/events`, {
|
|
113
|
+
maxResults: params.maxResults ?? 50,
|
|
114
|
+
orderBy: "startTime",
|
|
115
|
+
q: params.eventQuery?.trim() || void 0,
|
|
116
|
+
showDeleted: false,
|
|
117
|
+
singleEvents: true,
|
|
118
|
+
timeMin: params.timeMin ?? now.toISOString(),
|
|
119
|
+
timeMax: params.timeMax ?? defaultTimeMax.toISOString()
|
|
120
|
+
}),
|
|
121
|
+
init: { headers: {
|
|
122
|
+
Authorization: `Bearer ${params.accessToken}`,
|
|
123
|
+
Accept: "application/json"
|
|
124
|
+
} },
|
|
125
|
+
policy: { allowedHostnames: [GOOGLE_CALENDAR_API_HOST] },
|
|
126
|
+
auditContext: "google-meet.calendar.events.list",
|
|
127
|
+
timeoutMs: GOOGLE_CALENDAR_REQUEST_TIMEOUT_MS
|
|
128
|
+
});
|
|
129
|
+
try {
|
|
130
|
+
if (!response.ok) throw await googleApiError({
|
|
131
|
+
response,
|
|
132
|
+
prefix: "Google Calendar events.list",
|
|
133
|
+
scopes: [GOOGLE_CALENDAR_EVENTS_SCOPE]
|
|
134
|
+
});
|
|
135
|
+
const payload = await readProviderJsonResponse(response, "Google Calendar events.list");
|
|
136
|
+
if (payload.items !== void 0 && !Array.isArray(payload.items)) throw new Error("Google Calendar events.list response had non-array items");
|
|
137
|
+
return {
|
|
138
|
+
calendarId,
|
|
139
|
+
events: payload.items ?? [],
|
|
140
|
+
now
|
|
141
|
+
};
|
|
142
|
+
} finally {
|
|
143
|
+
await release();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function listGoogleMeetCalendarEvents(params) {
|
|
147
|
+
const { calendarId, events, now } = await fetchGoogleCalendarEvents(params);
|
|
148
|
+
const best = chooseBestMeetCalendarEvent(events, now);
|
|
149
|
+
return {
|
|
150
|
+
calendarId,
|
|
151
|
+
events: events.map((event) => {
|
|
152
|
+
const meetingUri = extractGoogleMeetUriFromCalendarEvent(event);
|
|
153
|
+
return meetingUri ? {
|
|
154
|
+
event,
|
|
155
|
+
meetingUri,
|
|
156
|
+
selected: event === best
|
|
157
|
+
} : void 0;
|
|
158
|
+
}).filter((event) => Boolean(event))
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
async function findGoogleMeetCalendarEvent(params) {
|
|
162
|
+
const result = await listGoogleMeetCalendarEvents(params);
|
|
163
|
+
const selected = result.events.find((event) => event.selected) ?? result.events[0];
|
|
164
|
+
if (!selected) throw new Error("No Google Calendar event with a Google Meet link matched the query");
|
|
165
|
+
return {
|
|
166
|
+
calendarId: result.calendarId,
|
|
167
|
+
event: selected.event,
|
|
168
|
+
meetingUri: selected.meetingUri
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
7
172
|
//#region extensions/google-meet/src/drive.ts
|
|
8
173
|
const GOOGLE_DRIVE_API_BASE_URL = "https://www.googleapis.com/drive/v3";
|
|
9
174
|
const GOOGLE_DRIVE_API_HOST = "www.googleapis.com";
|
|
@@ -101,9 +266,6 @@ function assertResourceArray(value, key, context) {
|
|
|
101
266
|
for (const resource of resources) if (!resource.name?.trim()) throw new Error(`Google Meet ${context} response included a resource without name`);
|
|
102
267
|
return resources;
|
|
103
268
|
}
|
|
104
|
-
function getErrorMessage(error) {
|
|
105
|
-
return error instanceof Error ? error.message : String(error);
|
|
106
|
-
}
|
|
107
269
|
async function requestGoogleMeetApi(params) {
|
|
108
270
|
return await fetchWithSsrFGuard({
|
|
109
271
|
url: appendQuery(`${GOOGLE_MEET_API_BASE_URL}/${params.path}`, params.query),
|
|
@@ -394,52 +556,47 @@ async function attachDocumentText(params) {
|
|
|
394
556
|
} catch (error) {
|
|
395
557
|
return {
|
|
396
558
|
...params.resource,
|
|
397
|
-
documentTextError:
|
|
559
|
+
documentTextError: formatErrorMessage(error)
|
|
398
560
|
};
|
|
399
561
|
}
|
|
400
562
|
}
|
|
401
|
-
function parseGoogleMeetTimestamp(value) {
|
|
402
|
-
if (!value?.trim()) return;
|
|
403
|
-
const parsed = Date.parse(value);
|
|
404
|
-
return Number.isFinite(parsed) ? parsed : void 0;
|
|
405
|
-
}
|
|
406
563
|
function isoFromMs(value) {
|
|
407
564
|
return typeof value === "number" && Number.isFinite(value) ? new Date(value).toISOString() : void 0;
|
|
408
565
|
}
|
|
409
566
|
function minTimestamp(values) {
|
|
410
|
-
const parsed = values.map(
|
|
567
|
+
const parsed = values.map(parseDateStringTimestampMs).filter((value) => typeof value === "number");
|
|
411
568
|
return parsed.length > 0 ? isoFromMs(Math.min(...parsed)) : void 0;
|
|
412
569
|
}
|
|
413
570
|
function maxTimestamp(values) {
|
|
414
|
-
const parsed = values.map(
|
|
571
|
+
const parsed = values.map(parseDateStringTimestampMs).filter((value) => typeof value === "number");
|
|
415
572
|
return parsed.length > 0 ? isoFromMs(Math.max(...parsed)) : void 0;
|
|
416
573
|
}
|
|
417
574
|
function sumSessionDurationMs(sessions, fallbackStart, fallbackEnd) {
|
|
418
575
|
const sessionTotal = sessions.reduce((total, session) => {
|
|
419
|
-
const startMs =
|
|
420
|
-
const endMs =
|
|
576
|
+
const startMs = parseDateStringTimestampMs(session.startTime);
|
|
577
|
+
const endMs = parseDateStringTimestampMs(session.endTime);
|
|
421
578
|
return startMs !== void 0 && endMs !== void 0 && endMs > startMs ? total + (endMs - startMs) : total;
|
|
422
579
|
}, 0);
|
|
423
580
|
if (sessionTotal > 0) return sessionTotal;
|
|
424
|
-
const startMs =
|
|
425
|
-
const endMs =
|
|
581
|
+
const startMs = parseDateStringTimestampMs(fallbackStart);
|
|
582
|
+
const endMs = parseDateStringTimestampMs(fallbackEnd);
|
|
426
583
|
return startMs !== void 0 && endMs !== void 0 && endMs > startMs ? endMs - startMs : void 0;
|
|
427
584
|
}
|
|
428
585
|
function attendanceMergeKey(row) {
|
|
429
586
|
return (row.user ?? row.displayName ?? row.participant).trim().toLocaleLowerCase();
|
|
430
587
|
}
|
|
431
588
|
function sortSessions(sessions) {
|
|
432
|
-
return sessions.toSorted((left, right) => (
|
|
589
|
+
return sessions.toSorted((left, right) => (parseDateStringTimestampMs(left.startTime) ?? 0) - (parseDateStringTimestampMs(right.startTime) ?? 0));
|
|
433
590
|
}
|
|
434
591
|
function decorateAttendanceRow(row, conferenceRecord, params) {
|
|
435
592
|
const sessions = sortSessions(row.sessions);
|
|
436
593
|
const firstJoinTime = minTimestamp([row.earliestStartTime, ...sessions.map((session) => session.startTime)]);
|
|
437
594
|
const lastLeaveTime = maxTimestamp([row.latestEndTime, ...sessions.map((session) => session.endTime)]);
|
|
438
595
|
const durationMs = sumSessionDurationMs(sessions, firstJoinTime, lastLeaveTime);
|
|
439
|
-
const conferenceStartMs =
|
|
440
|
-
const conferenceEndMs =
|
|
441
|
-
const firstJoinMs =
|
|
442
|
-
const lastLeaveMs =
|
|
596
|
+
const conferenceStartMs = parseDateStringTimestampMs(conferenceRecord.startTime);
|
|
597
|
+
const conferenceEndMs = parseDateStringTimestampMs(conferenceRecord.endTime);
|
|
598
|
+
const firstJoinMs = parseDateStringTimestampMs(firstJoinTime);
|
|
599
|
+
const lastLeaveMs = parseDateStringTimestampMs(lastLeaveTime);
|
|
443
600
|
const lateGraceMs = (params.lateAfterMinutes ?? 5) * 6e4;
|
|
444
601
|
const earlyGraceMs = (params.earlyBeforeMinutes ?? 5) * 6e4;
|
|
445
602
|
const lateByMs = conferenceStartMs !== void 0 && firstJoinMs !== void 0 ? Math.max(firstJoinMs - conferenceStartMs, 0) : void 0;
|
|
@@ -511,7 +668,7 @@ async function fetchGoogleMeetArtifacts(params) {
|
|
|
511
668
|
pageSize: params.pageSize
|
|
512
669
|
}).then((smartNotes) => ({ smartNotes })).catch((error) => ({
|
|
513
670
|
smartNotes: [],
|
|
514
|
-
smartNotesError:
|
|
671
|
+
smartNotesError: formatErrorMessage(error)
|
|
515
672
|
}))
|
|
516
673
|
]);
|
|
517
674
|
const transcriptEntries = params.includeTranscriptEntries === false ? [] : await Promise.all(transcripts.map(async (transcript) => {
|
|
@@ -528,7 +685,7 @@ async function fetchGoogleMeetArtifacts(params) {
|
|
|
528
685
|
return {
|
|
529
686
|
transcript: transcript.name,
|
|
530
687
|
entries: [],
|
|
531
|
-
entriesError:
|
|
688
|
+
entriesError: formatErrorMessage(error)
|
|
532
689
|
};
|
|
533
690
|
}
|
|
534
691
|
}));
|
|
@@ -599,347 +756,170 @@ function buildGoogleMeetPreflightReport(params) {
|
|
|
599
756
|
};
|
|
600
757
|
}
|
|
601
758
|
//#endregion
|
|
602
|
-
//#region extensions/google-meet/src/
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
759
|
+
//#region extensions/google-meet/src/plugin-helpers.ts
|
|
760
|
+
var plugin_helpers_exports = /* @__PURE__ */ __exportAll({
|
|
761
|
+
buildGoogleMeetCalendarDayWindow: () => buildGoogleMeetCalendarDayWindow,
|
|
762
|
+
buildGoogleMeetPreflightReport: () => buildGoogleMeetPreflightReport,
|
|
763
|
+
createAndJoinMeetFromParams: () => createAndJoinMeetFromParams,
|
|
764
|
+
createMeetFromParams: () => createMeetFromParams,
|
|
765
|
+
endGoogleMeetActiveConference: () => endGoogleMeetActiveConference,
|
|
766
|
+
exportGoogleMeetBundleFromParams: () => exportGoogleMeetBundleFromParams,
|
|
767
|
+
fetchLatestGoogleMeetConferenceRecord: () => fetchLatestGoogleMeetConferenceRecord,
|
|
768
|
+
fetchResolvedGoogleMeetArtifacts: () => fetchResolvedGoogleMeetArtifacts,
|
|
769
|
+
fetchResolvedGoogleMeetAttendance: () => fetchResolvedGoogleMeetAttendance,
|
|
770
|
+
listGoogleMeetCalendarEvents: () => listGoogleMeetCalendarEvents,
|
|
771
|
+
resolveArtifactQueryFromParams: () => resolveArtifactQueryFromParams,
|
|
772
|
+
resolveGoogleMeetTokenFromParams: () => resolveGoogleMeetTokenFromParams,
|
|
773
|
+
resolveMeetingFromParams: () => resolveMeetingFromParams,
|
|
774
|
+
resolveSpaceFromParams: () => resolveSpaceFromParams
|
|
775
|
+
});
|
|
776
|
+
const loadGoogleMeetCreateModule = createLazyRuntimeModule(() => import("./create-UHeaRzsH.js").then((n) => n.t));
|
|
777
|
+
async function createMeetFromParams(params) {
|
|
778
|
+
return (await loadGoogleMeetCreateModule()).createMeetFromParams(params);
|
|
779
|
+
}
|
|
780
|
+
async function createAndJoinMeetFromParams(params) {
|
|
781
|
+
return (await loadGoogleMeetCreateModule()).createAndJoinMeetFromParams(params);
|
|
782
|
+
}
|
|
783
|
+
async function resolveGoogleMeetTokenFromParams(config, raw) {
|
|
784
|
+
const { resolveGoogleMeetAccessToken } = await import("./oauth-9sUJ68Mw.js");
|
|
785
|
+
return resolveGoogleMeetAccessToken({
|
|
786
|
+
clientId: normalizeOptionalString(raw.clientId) ?? config.oauth.clientId,
|
|
787
|
+
clientSecret: normalizeOptionalString(raw.clientSecret) ?? config.oauth.clientSecret,
|
|
788
|
+
refreshToken: normalizeOptionalString(raw.refreshToken) ?? config.oauth.refreshToken,
|
|
789
|
+
accessToken: normalizeOptionalString(raw.accessToken) ?? config.oauth.accessToken,
|
|
790
|
+
expiresAt: typeof raw.expiresAt === "number" ? raw.expiresAt : config.oauth.expiresAt
|
|
615
791
|
});
|
|
616
792
|
}
|
|
617
|
-
|
|
618
|
-
return
|
|
619
|
-
...params,
|
|
620
|
-
adapter: GOOGLE_MEET_BROWSER_NODE_ADAPTER
|
|
621
|
-
});
|
|
793
|
+
function wantsCalendarLookup(raw) {
|
|
794
|
+
return raw.today === true || Boolean(normalizeOptionalString(raw.event));
|
|
622
795
|
}
|
|
623
|
-
async function
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
const parsed = new URL(url);
|
|
636
|
-
parsed.searchParams.set("hl", "en");
|
|
637
|
-
return parsed.toString();
|
|
638
|
-
} catch {
|
|
639
|
-
return url;
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
function normalizeMeetUrlForReuse(url) {
|
|
643
|
-
if (!url) return;
|
|
644
|
-
try {
|
|
645
|
-
const parsed = new URL(url);
|
|
646
|
-
if (parsed.protocol !== "https:" || parsed.hostname.toLowerCase() !== "meet.google.com") return;
|
|
647
|
-
const match = parsed.pathname.match(/^\/([a-z]{3}-[a-z]{4}-[a-z]{3})(?:\/)?$/i);
|
|
648
|
-
if (!match?.[1]) return;
|
|
649
|
-
return `https://meet.google.com/${match[1].toLowerCase()}`;
|
|
650
|
-
} catch {
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
function isSameMeetUrlForReuse(a, b) {
|
|
655
|
-
const normalizedA = normalizeMeetUrlForReuse(a);
|
|
656
|
-
const normalizedB = normalizeMeetUrlForReuse(b);
|
|
657
|
-
return Boolean(normalizedA && normalizedB && normalizedA === normalizedB);
|
|
658
|
-
}
|
|
659
|
-
function isEnglishMeetTab(url) {
|
|
660
|
-
if (!url) return false;
|
|
661
|
-
try {
|
|
662
|
-
const parsed = new URL(url);
|
|
663
|
-
return parsed.protocol === "https:" && parsed.hostname.toLowerCase() === "meet.google.com" && parsed.searchParams.get("hl")?.toLowerCase() === "en";
|
|
664
|
-
} catch {
|
|
665
|
-
return false;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
function readMeetAuthUser(url) {
|
|
669
|
-
if (!url) return;
|
|
670
|
-
try {
|
|
671
|
-
return new URL(url).searchParams.get("authuser") ?? void 0;
|
|
672
|
-
} catch {
|
|
673
|
-
return;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
function isRecoverableMeetTab(tab, url) {
|
|
677
|
-
if (url) return isSameMeetUrlForReuse(tab.url, url);
|
|
678
|
-
if (normalizeMeetUrlForReuse(tab.url)) return true;
|
|
679
|
-
return (tab.url ?? "").startsWith("https://accounts.google.com/") && /sign in|google accounts|meet/i.test(tab.title ?? "");
|
|
680
|
-
}
|
|
681
|
-
//#endregion
|
|
682
|
-
//#region extensions/google-meet/src/transports/chrome-create.ts
|
|
683
|
-
const GOOGLE_MEET_NEW_URL = "https://meet.google.com/new";
|
|
684
|
-
const GOOGLE_MEET_BROWSER_CREATE_TIMEOUT_MS = 6e4;
|
|
685
|
-
const GOOGLE_MEET_BROWSER_STEP_TIMEOUT_MS = 1e4;
|
|
686
|
-
const GOOGLE_MEET_BROWSER_NAVIGATION_RETRY_MS = 1e3;
|
|
687
|
-
const GOOGLE_MEET_BROWSER_POLL_MS = 500;
|
|
688
|
-
var GoogleMeetBrowserManualActionError = class extends Error {
|
|
689
|
-
constructor(payload) {
|
|
690
|
-
super(`${payload.manualAction.reason}: ${payload.manualAction.message}`);
|
|
691
|
-
this.name = "GoogleMeetBrowserManualActionError";
|
|
692
|
-
this.payload = {
|
|
693
|
-
source: "browser",
|
|
694
|
-
error: this.message,
|
|
695
|
-
...payload
|
|
796
|
+
async function resolveMeetingFromParams(params) {
|
|
797
|
+
if (wantsCalendarLookup(params.raw)) {
|
|
798
|
+
const window = params.raw.today === true ? buildGoogleMeetCalendarDayWindow() : {};
|
|
799
|
+
const calendarEvent = await findGoogleMeetCalendarEvent({
|
|
800
|
+
accessToken: params.accessToken,
|
|
801
|
+
calendarId: normalizeOptionalString(params.raw.calendarId),
|
|
802
|
+
eventQuery: normalizeOptionalString(params.raw.event),
|
|
803
|
+
...window
|
|
804
|
+
});
|
|
805
|
+
return {
|
|
806
|
+
meeting: calendarEvent.meetingUri,
|
|
807
|
+
calendarEvent
|
|
696
808
|
};
|
|
697
809
|
}
|
|
698
|
-
};
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
} catch {
|
|
707
|
-
return "unknown error";
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
function isBrowserNavigationInterruption(error) {
|
|
711
|
-
return /execution context was destroyed|navigation|target closed/i.test(formatBrowserAutomationError(error));
|
|
712
|
-
}
|
|
713
|
-
function isGoogleMeetCreateTab(tab) {
|
|
714
|
-
const url = tab.url ?? "";
|
|
715
|
-
if (/^https:\/\/meet\.google\.com\/(?:new|[a-z]{3}-[a-z]{4}-[a-z]{3})(?:$|[/?#])/i.test(url)) return true;
|
|
716
|
-
return url.startsWith("https://accounts.google.com/") && /sign in|google accounts|meet/i.test(tab.title ?? "");
|
|
717
|
-
}
|
|
718
|
-
async function findGoogleMeetCreateTab(params) {
|
|
719
|
-
return asBrowserTabs(await callBrowserProxyOnNode({
|
|
720
|
-
runtime: params.runtime,
|
|
721
|
-
nodeId: params.nodeId,
|
|
722
|
-
method: "GET",
|
|
723
|
-
path: "/tabs",
|
|
724
|
-
timeoutMs: params.timeoutMs
|
|
725
|
-
})).find(isGoogleMeetCreateTab);
|
|
726
|
-
}
|
|
727
|
-
async function focusBrowserTab(params) {
|
|
728
|
-
await callBrowserProxyOnNode({
|
|
729
|
-
runtime: params.runtime,
|
|
730
|
-
nodeId: params.nodeId,
|
|
731
|
-
method: "POST",
|
|
732
|
-
path: "/tabs/focus",
|
|
733
|
-
body: { targetId: params.targetId },
|
|
734
|
-
timeoutMs: params.timeoutMs
|
|
810
|
+
return { meeting: resolveMeetingInput(params.config, params.raw.meeting) };
|
|
811
|
+
}
|
|
812
|
+
async function resolveSpaceFromParams(config, raw) {
|
|
813
|
+
const token = await resolveGoogleMeetTokenFromParams(config, raw);
|
|
814
|
+
const { meeting, calendarEvent } = await resolveMeetingFromParams({
|
|
815
|
+
config,
|
|
816
|
+
raw,
|
|
817
|
+
accessToken: token.accessToken
|
|
735
818
|
});
|
|
819
|
+
return {
|
|
820
|
+
meeting,
|
|
821
|
+
token,
|
|
822
|
+
space: await fetchGoogleMeetSpace({
|
|
823
|
+
accessToken: token.accessToken,
|
|
824
|
+
meeting
|
|
825
|
+
}),
|
|
826
|
+
calendarEvent
|
|
827
|
+
};
|
|
736
828
|
}
|
|
737
|
-
function
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
}
|
|
748
|
-
function readBrowserCreateResult(result) {
|
|
749
|
-
const record = result && typeof result === "object" ? result : {};
|
|
750
|
-
const nested = record.result && typeof record.result === "object" ? record.result : record;
|
|
829
|
+
async function resolveArtifactQueryFromParams(config, raw) {
|
|
830
|
+
const meeting = normalizeOptionalString(raw.meeting) ?? config.defaults.meeting;
|
|
831
|
+
const conferenceRecord = normalizeOptionalString(raw.conferenceRecord);
|
|
832
|
+
const token = await resolveGoogleMeetTokenFromParams(config, raw);
|
|
833
|
+
const resolvedMeeting = conferenceRecord ? { meeting } : wantsCalendarLookup(raw) ? await resolveMeetingFromParams({
|
|
834
|
+
config,
|
|
835
|
+
raw,
|
|
836
|
+
accessToken: token.accessToken
|
|
837
|
+
}) : { meeting };
|
|
838
|
+
if (!resolvedMeeting.meeting && !conferenceRecord) throw new Error("Meeting input, calendar lookup, or conferenceRecord required");
|
|
751
839
|
return {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
840
|
+
token,
|
|
841
|
+
meeting: resolvedMeeting.meeting,
|
|
842
|
+
calendarEvent: resolvedMeeting.calendarEvent,
|
|
843
|
+
conferenceRecord,
|
|
844
|
+
pageSize: readPositiveIntegerParam(raw, "pageSize"),
|
|
845
|
+
includeTranscriptEntries: raw.includeTranscriptEntries !== false,
|
|
846
|
+
includeDocumentBodies: raw.includeDocumentBodies === true,
|
|
847
|
+
allConferenceRecords: raw.includeAllConferenceRecords === true,
|
|
848
|
+
mergeDuplicateParticipants: raw.mergeDuplicateParticipants !== false,
|
|
849
|
+
lateAfterMinutes: readPositiveIntegerParam(raw, "lateAfterMinutes"),
|
|
850
|
+
earlyBeforeMinutes: readPositiveIntegerParam(raw, "earlyBeforeMinutes")
|
|
758
851
|
};
|
|
759
852
|
}
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
button.getAttribute("aria-label"),
|
|
770
|
-
button.getAttribute("data-tooltip"),
|
|
771
|
-
text(button),
|
|
772
|
-
]
|
|
773
|
-
.filter(Boolean)
|
|
774
|
-
.join(" ");
|
|
775
|
-
return pattern.test(label) && !button.disabled;
|
|
776
|
-
});
|
|
777
|
-
const clickButton = (pattern, note) => {
|
|
778
|
-
const button = findButton(pattern);
|
|
779
|
-
if (!button) {
|
|
780
|
-
return false;
|
|
781
|
-
}
|
|
782
|
-
button.click();
|
|
783
|
-
notes.push(note);
|
|
784
|
-
return true;
|
|
785
|
-
};
|
|
786
|
-
if (!current().startsWith("https://meet.google.com/")) {
|
|
787
|
-
return {
|
|
788
|
-
manualAction: manualActionFor("google-login-required", "Sign in to Google in the OpenClaw browser profile, then retry meeting creation."),
|
|
789
|
-
browserUrl: current(),
|
|
790
|
-
browserTitle: document.title,
|
|
791
|
-
notes,
|
|
792
|
-
};
|
|
793
|
-
}
|
|
794
|
-
const href = current();
|
|
795
|
-
if (meetUrlPattern.test(href)) {
|
|
796
|
-
// The /new redirect keeps the hl=en param we open with; strip query/hash so the
|
|
797
|
-
// meeting link handed to users stays canonical instead of forcing English on them.
|
|
798
|
-
return { meetingUri: href.split(/[?#]/)[0], browserUrl: href, browserTitle: document.title, notes };
|
|
799
|
-
}
|
|
800
|
-
const pageText = text(document.body);
|
|
801
|
-
if (clickButton(/\\buse microphone\\b/i, "Accepted Meet microphone prompt with browser automation.")) {
|
|
802
|
-
return { browserUrl: href, browserTitle: document.title, notes, retryAfterMs: 1000 };
|
|
803
|
-
}
|
|
804
|
-
if (
|
|
805
|
-
clickButton(
|
|
806
|
-
/continue without microphone/i,
|
|
807
|
-
"Continued through Meet microphone prompt with browser automation.",
|
|
808
|
-
)
|
|
809
|
-
) {
|
|
810
|
-
return { browserUrl: href, browserTitle: document.title, notes, retryAfterMs: 1000 };
|
|
811
|
-
}
|
|
812
|
-
if (/do you want people to hear you in the meeting/i.test(pageText)) {
|
|
813
|
-
return {
|
|
814
|
-
manualAction: manualActionFor("meet-audio-choice-required", "Meet is showing the microphone choice. Click Use microphone in the OpenClaw browser profile, then retry meeting creation."),
|
|
815
|
-
browserUrl: href,
|
|
816
|
-
browserTitle: document.title,
|
|
817
|
-
notes,
|
|
818
|
-
};
|
|
819
|
-
}
|
|
820
|
-
if (/allow.*(microphone|camera)|blocked.*(microphone|camera)|permission.*(microphone|camera)/i.test(pageText)) {
|
|
821
|
-
return {
|
|
822
|
-
manualAction: manualActionFor("meet-permission-required", "Allow microphone/camera permissions for Meet in the OpenClaw browser profile, then retry meeting creation."),
|
|
823
|
-
browserUrl: href,
|
|
824
|
-
browserTitle: document.title,
|
|
825
|
-
notes,
|
|
826
|
-
};
|
|
827
|
-
}
|
|
828
|
-
if (/couldn't create|unable to create/i.test(pageText)) {
|
|
829
|
-
return {
|
|
830
|
-
manualAction: manualActionFor("browser-control-unavailable", "Resolve the Google Meet page prompt in the OpenClaw browser profile, then retry meeting creation."),
|
|
831
|
-
browserUrl: href,
|
|
832
|
-
browserTitle: document.title,
|
|
833
|
-
notes,
|
|
834
|
-
};
|
|
835
|
-
}
|
|
836
|
-
if (location.hostname.toLowerCase() === "accounts.google.com" || /use your google account|to continue to google meet|choose an account|sign in to (join|continue)/i.test(pageText)) {
|
|
837
|
-
return {
|
|
838
|
-
manualAction: manualActionFor("google-login-required", "Sign in to Google in the OpenClaw browser profile, then retry meeting creation."),
|
|
839
|
-
browserUrl: href,
|
|
840
|
-
browserTitle: document.title,
|
|
841
|
-
notes,
|
|
842
|
-
};
|
|
843
|
-
}
|
|
844
|
-
return {
|
|
845
|
-
retryAfterMs: 500,
|
|
846
|
-
browserUrl: current(),
|
|
847
|
-
browserTitle: document.title,
|
|
848
|
-
notes,
|
|
849
|
-
};
|
|
850
|
-
}`;
|
|
851
|
-
async function createMeetWithBrowserProxyOnNode(params) {
|
|
852
|
-
const nodeId = await resolveChromeNode({
|
|
853
|
-
runtime: params.runtime,
|
|
854
|
-
requestedNode: params.config.chromeNode.node
|
|
853
|
+
function fetchResolvedGoogleMeetArtifacts(query) {
|
|
854
|
+
return fetchGoogleMeetArtifacts({
|
|
855
|
+
accessToken: query.token.accessToken,
|
|
856
|
+
meeting: query.meeting,
|
|
857
|
+
conferenceRecord: query.conferenceRecord,
|
|
858
|
+
pageSize: query.pageSize,
|
|
859
|
+
includeTranscriptEntries: query.includeTranscriptEntries,
|
|
860
|
+
includeDocumentBodies: query.includeDocumentBodies,
|
|
861
|
+
allConferenceRecords: query.allConferenceRecords
|
|
855
862
|
});
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
+
}
|
|
864
|
+
function fetchResolvedGoogleMeetAttendance(query) {
|
|
865
|
+
return fetchGoogleMeetAttendance({
|
|
866
|
+
accessToken: query.token.accessToken,
|
|
867
|
+
meeting: query.meeting,
|
|
868
|
+
conferenceRecord: query.conferenceRecord,
|
|
869
|
+
pageSize: query.pageSize,
|
|
870
|
+
allConferenceRecords: query.allConferenceRecords,
|
|
871
|
+
mergeDuplicateParticipants: query.mergeDuplicateParticipants,
|
|
872
|
+
lateAfterMinutes: query.lateAfterMinutes,
|
|
873
|
+
earlyBeforeMinutes: query.earlyBeforeMinutes
|
|
863
874
|
});
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
timeoutMs: stepTimeoutMs
|
|
913
|
-
}));
|
|
914
|
-
lastResult = result;
|
|
915
|
-
for (const note of result.notes ?? []) notes.add(note);
|
|
916
|
-
if (result.meetingUri) return {
|
|
917
|
-
source: "browser",
|
|
918
|
-
nodeId,
|
|
919
|
-
targetId,
|
|
920
|
-
openedByPlugin,
|
|
921
|
-
meetingUri: result.meetingUri,
|
|
922
|
-
browserUrl: result.browserUrl,
|
|
923
|
-
browserTitle: result.browserTitle,
|
|
924
|
-
notes: [...notes]
|
|
925
|
-
};
|
|
926
|
-
if (result.manualAction) throw new GoogleMeetBrowserManualActionError({
|
|
927
|
-
manualAction: result.manualAction,
|
|
928
|
-
browser: {
|
|
929
|
-
nodeId,
|
|
930
|
-
targetId,
|
|
931
|
-
browserUrl: result.browserUrl,
|
|
932
|
-
browserTitle: result.browserTitle,
|
|
933
|
-
notes: [...notes]
|
|
934
|
-
}
|
|
935
|
-
});
|
|
936
|
-
await sleep(result.retryAfterMs ?? GOOGLE_MEET_BROWSER_POLL_MS);
|
|
937
|
-
} catch (error) {
|
|
938
|
-
lastError = error;
|
|
939
|
-
if (!isBrowserNavigationInterruption(error)) throw error;
|
|
940
|
-
await sleep(GOOGLE_MEET_BROWSER_NAVIGATION_RETRY_MS);
|
|
941
|
-
}
|
|
942
|
-
throw new Error(lastResult?.manualAction?.message ?? `Google Meet did not return a meeting URL from the browser create flow before timeout.${lastError ? ` Last browser automation error: ${formatBrowserAutomationError(lastError)}` : ""}`);
|
|
875
|
+
}
|
|
876
|
+
async function exportGoogleMeetBundleFromParams(config, raw) {
|
|
877
|
+
const resolved = await resolveArtifactQueryFromParams(config, raw);
|
|
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 = {
|
|
882
|
+
...resolved.meeting ? { meeting: resolved.meeting } : {},
|
|
883
|
+
...resolved.conferenceRecord ? { conferenceRecord: resolved.conferenceRecord } : {},
|
|
884
|
+
...resolved.calendarEvent?.event.id ? { calendarEventId: resolved.calendarEvent.event.id } : {},
|
|
885
|
+
...resolved.calendarEvent?.event.summary ? { calendarEventSummary: resolved.calendarEvent.event.summary } : {},
|
|
886
|
+
...calendarId ? { calendarId } : {},
|
|
887
|
+
...resolved.pageSize !== void 0 ? { pageSize: resolved.pageSize } : {},
|
|
888
|
+
includeTranscriptEntries: resolved.includeTranscriptEntries,
|
|
889
|
+
includeDocumentBodies: resolved.includeDocumentBodies,
|
|
890
|
+
allConferenceRecords: resolved.allConferenceRecords,
|
|
891
|
+
mergeDuplicateParticipants: resolved.mergeDuplicateParticipants,
|
|
892
|
+
...resolved.lateAfterMinutes !== void 0 ? { lateAfterMinutes: resolved.lateAfterMinutes } : {},
|
|
893
|
+
...resolved.earlyBeforeMinutes !== void 0 ? { earlyBeforeMinutes: resolved.earlyBeforeMinutes } : {}
|
|
894
|
+
};
|
|
895
|
+
const tokenSource = resolved.token.refreshed ? "refresh-token" : "cached-access-token";
|
|
896
|
+
if (raw.dryRun === true) return {
|
|
897
|
+
dryRun: true,
|
|
898
|
+
manifest: buildGoogleMeetExportManifest({
|
|
899
|
+
artifacts,
|
|
900
|
+
attendance,
|
|
901
|
+
files: googleMeetExportFileNames(),
|
|
902
|
+
request,
|
|
903
|
+
tokenSource,
|
|
904
|
+
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {}
|
|
905
|
+
}),
|
|
906
|
+
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {},
|
|
907
|
+
tokenSource
|
|
908
|
+
};
|
|
909
|
+
const outputDir = normalizeOptionalString(raw.outputDir) ?? normalizeOptionalString(raw.output);
|
|
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
|
+
};
|
|
943
923
|
}
|
|
944
924
|
//#endregion
|
|
945
|
-
export {
|
|
925
|
+
export { resolveGoogleMeetTokenFromParams as a, buildGoogleMeetPreflightReport as c, fetchGoogleMeetSpace as d, fetchLatestGoogleMeetConferenceRecord as f, __exportAll as h, resolveArtifactQueryFromParams as i, createGoogleMeetSpace as l, listGoogleMeetCalendarEvents as m, fetchResolvedGoogleMeetAttendance as n, resolveMeetingFromParams as o, buildGoogleMeetCalendarDayWindow as p, plugin_helpers_exports as r, resolveSpaceFromParams as s, fetchResolvedGoogleMeetArtifacts as t, endGoogleMeetActiveConference as u };
|