@openclaw/google-meet 2026.9.1-beta.1 → 2026.9.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/{cli-Bd63VJ5q.js → cli-Cwc266K3.js} +25 -20
- package/dist/{create-BEDHM6uL.js → create-Djmk2CQz.js} +2 -2
- package/dist/doctor-contract-api.js +3 -1
- package/dist/{google-api-errors-CDUYkIcK.js → google-api-errors-BDYXfKRa.js} +1 -1
- package/dist/index.js +5 -2
- package/dist/{oauth-9sUJ68Mw.js → oauth-DgBscjXK.js} +4 -3
- package/dist/{plugin-helpers-C9-Y0Ago.js → plugin-helpers-WF-JVJhh.js} +5 -5
- package/dist/{plugin-registration-Csi-NdQU.js → plugin-registration-NIwMvP6X.js} +3 -3
- package/dist/{runtime-B8d1beHo.js → runtime-0IuZTlpN.js} +48 -131
- package/node_modules/typebox/build/format/email.mjs +1 -1
- package/node_modules/typebox/build/format/idna/idn-hostname.mjs +19 -1
- package/node_modules/typebox/package.json +1 -1
- package/package.json +5 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as resolveGoogleMeetTokenFromParams, c as buildGoogleMeetPreflightReport, d as fetchGoogleMeetSpace, f as fetchLatestGoogleMeetConferenceRecord, i as resolveArtifactQueryFromParams, l as createGoogleMeetSpace, m as listGoogleMeetCalendarEvents, n as fetchResolvedGoogleMeetAttendance, o as resolveMeetingFromParams, p as buildGoogleMeetCalendarDayWindow, s as resolveSpaceFromParams, t as fetchResolvedGoogleMeetArtifacts, u as endGoogleMeetActiveConference } from "./plugin-helpers-
|
|
1
|
+
import { a as resolveGoogleMeetTokenFromParams, c as buildGoogleMeetPreflightReport, d as fetchGoogleMeetSpace, f as fetchLatestGoogleMeetConferenceRecord, i as resolveArtifactQueryFromParams, l as createGoogleMeetSpace, m as listGoogleMeetCalendarEvents, n as fetchResolvedGoogleMeetAttendance, o as resolveMeetingFromParams, p as buildGoogleMeetCalendarDayWindow, s as resolveSpaceFromParams, t as fetchResolvedGoogleMeetArtifacts, u as endGoogleMeetActiveConference } from "./plugin-helpers-WF-JVJhh.js";
|
|
2
2
|
import { i as resolveGoogleMeetGatewayOperationTimeoutMs } from "./config-wBK8loBb.js";
|
|
3
|
-
import { buildGoogleMeetAuthUrl, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode } from "./oauth-
|
|
4
|
-
import { n as hasCreateSpaceConfigInput, r as resolveCreateSpaceConfig } from "./create-
|
|
3
|
+
import { buildGoogleMeetAuthUrl, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode } from "./oauth-DgBscjXK.js";
|
|
4
|
+
import { n as hasCreateSpaceConfigInput, r as resolveCreateSpaceConfig } from "./create-Djmk2CQz.js";
|
|
5
5
|
import { clampTimerTimeoutMs, parseStrictNonNegativeInteger, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
6
6
|
import { callGatewayFromCli, isGatewayClientRequestError, isGatewayTransportError } from "openclaw/plugin-sdk/gateway-runtime";
|
|
7
7
|
import { generateHexPkceVerifierChallenge } from "openclaw/plugin-sdk/provider-auth";
|
|
@@ -139,7 +139,8 @@ async function callGoogleMeetGateway(params) {
|
|
|
139
139
|
}
|
|
140
140
|
function formatDuration(value) {
|
|
141
141
|
if (value === void 0) return "n/a";
|
|
142
|
-
|
|
142
|
+
const roundedMs = Math.max(0, Math.round(value / 1e3) * 1e3);
|
|
143
|
+
return formatDurationCompact(roundedMs, {
|
|
143
144
|
showYears: true,
|
|
144
145
|
spaced: true
|
|
145
146
|
}) ?? "0ms";
|
|
@@ -656,6 +657,9 @@ async function resolveCliArtifactQuery(context, options) {
|
|
|
656
657
|
earlyBeforeMinutes
|
|
657
658
|
};
|
|
658
659
|
}
|
|
660
|
+
function resolveTokenSource(refreshed) {
|
|
661
|
+
return refreshed ? "refresh-token" : "cached-access-token";
|
|
662
|
+
}
|
|
659
663
|
function registerGoogleMeetArtifactCommands(context) {
|
|
660
664
|
const params = context;
|
|
661
665
|
const { root } = context;
|
|
@@ -665,7 +669,7 @@ function registerGoogleMeetArtifactCommands(context) {
|
|
|
665
669
|
if (options.json) {
|
|
666
670
|
await writeCliOutput(options, JSON.stringify({
|
|
667
671
|
...result,
|
|
668
|
-
tokenSource: resolved.token.refreshed
|
|
672
|
+
tokenSource: resolveTokenSource(resolved.token.refreshed)
|
|
669
673
|
}, null, 2));
|
|
670
674
|
return;
|
|
671
675
|
}
|
|
@@ -675,7 +679,7 @@ function registerGoogleMeetArtifactCommands(context) {
|
|
|
675
679
|
}
|
|
676
680
|
if (options.format && options.format !== "summary") throw new Error("Unsupported format. Expected summary or markdown.");
|
|
677
681
|
writeArtifactsSummary(result);
|
|
678
|
-
writeStdoutLine("token source: %s", resolved.token.refreshed
|
|
682
|
+
writeStdoutLine("token source: %s", resolveTokenSource(resolved.token.refreshed));
|
|
679
683
|
});
|
|
680
684
|
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) => {
|
|
681
685
|
const resolved = await resolveCliArtifactQuery(params, options);
|
|
@@ -683,7 +687,7 @@ function registerGoogleMeetArtifactCommands(context) {
|
|
|
683
687
|
if (options.json) {
|
|
684
688
|
await writeCliOutput(options, JSON.stringify({
|
|
685
689
|
...result,
|
|
686
|
-
tokenSource: resolved.token.refreshed
|
|
690
|
+
tokenSource: resolveTokenSource(resolved.token.refreshed)
|
|
687
691
|
}, null, 2));
|
|
688
692
|
return;
|
|
689
693
|
}
|
|
@@ -697,7 +701,7 @@ function registerGoogleMeetArtifactCommands(context) {
|
|
|
697
701
|
}
|
|
698
702
|
if (options.format && options.format !== "summary") throw new Error("Unsupported format. Expected summary, markdown, or csv.");
|
|
699
703
|
writeAttendanceSummary(result);
|
|
700
|
-
writeStdoutLine("token source: %s", resolved.token.refreshed
|
|
704
|
+
writeStdoutLine("token source: %s", resolveTokenSource(resolved.token.refreshed));
|
|
701
705
|
});
|
|
702
706
|
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) => {
|
|
703
707
|
const resolved = await resolveCliArtifactQuery(params, options);
|
|
@@ -725,11 +729,11 @@ function registerGoogleMeetArtifactCommands(context) {
|
|
|
725
729
|
attendance,
|
|
726
730
|
files: googleMeetExportFileNames(),
|
|
727
731
|
request,
|
|
728
|
-
tokenSource: resolved.token.refreshed
|
|
732
|
+
tokenSource: resolveTokenSource(resolved.token.refreshed),
|
|
729
733
|
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {}
|
|
730
734
|
}),
|
|
731
735
|
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {},
|
|
732
|
-
tokenSource: resolved.token.refreshed
|
|
736
|
+
tokenSource: resolveTokenSource(resolved.token.refreshed)
|
|
733
737
|
});
|
|
734
738
|
return;
|
|
735
739
|
}
|
|
@@ -739,13 +743,13 @@ function registerGoogleMeetArtifactCommands(context) {
|
|
|
739
743
|
attendance,
|
|
740
744
|
zip: Boolean(options.zip),
|
|
741
745
|
request,
|
|
742
|
-
tokenSource: resolved.token.refreshed
|
|
746
|
+
tokenSource: resolveTokenSource(resolved.token.refreshed),
|
|
743
747
|
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {}
|
|
744
748
|
});
|
|
745
749
|
const payload = {
|
|
746
750
|
...bundle,
|
|
747
751
|
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {},
|
|
748
|
-
tokenSource: resolved.token.refreshed
|
|
752
|
+
tokenSource: resolveTokenSource(resolved.token.refreshed)
|
|
749
753
|
};
|
|
750
754
|
if (options.json) {
|
|
751
755
|
writeStdoutJson(payload);
|
|
@@ -1323,17 +1327,18 @@ function registerGoogleMeetCli(params) {
|
|
|
1323
1327
|
challenge,
|
|
1324
1328
|
state
|
|
1325
1329
|
});
|
|
1330
|
+
const code = await waitForGoogleMeetAuthCode({
|
|
1331
|
+
state,
|
|
1332
|
+
manual: Boolean(options.manual),
|
|
1333
|
+
timeoutMs: resolveGoogleMeetOAuthCallbackTimeoutMs(options.timeoutSec),
|
|
1334
|
+
authUrl,
|
|
1335
|
+
promptInput,
|
|
1336
|
+
writeLine: (message) => writeStdoutLine("%s", message)
|
|
1337
|
+
});
|
|
1326
1338
|
const tokens = await exchangeGoogleMeetAuthCode({
|
|
1327
1339
|
clientId,
|
|
1328
1340
|
clientSecret,
|
|
1329
|
-
code
|
|
1330
|
-
state,
|
|
1331
|
-
manual: Boolean(options.manual),
|
|
1332
|
-
timeoutMs: resolveGoogleMeetOAuthCallbackTimeoutMs(options.timeoutSec),
|
|
1333
|
-
authUrl,
|
|
1334
|
-
promptInput,
|
|
1335
|
-
writeLine: (message) => writeStdoutLine("%s", message)
|
|
1336
|
-
}),
|
|
1341
|
+
code,
|
|
1337
1342
|
verifier
|
|
1338
1343
|
});
|
|
1339
1344
|
if (!tokens.refreshToken) throw new Error("Google OAuth did not return a refresh token. Re-run the flow with consent and offline access.");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h as __exportAll, l as createGoogleMeetSpace } from "./plugin-helpers-
|
|
2
|
-
import { resolveGoogleMeetAccessToken } from "./oauth-
|
|
1
|
+
import { h as __exportAll, l as createGoogleMeetSpace } from "./plugin-helpers-WF-JVJhh.js";
|
|
2
|
+
import { resolveGoogleMeetAccessToken } from "./oauth-DgBscjXK.js";
|
|
3
3
|
import { t as createMeetWithBrowserProxyOnNode } from "./chrome-create-PKAyxCiL.js";
|
|
4
4
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
//#region extensions/google-meet/src/create.ts
|
|
@@ -20,7 +20,9 @@ const legacyConfigRules = [{
|
|
|
20
20
|
match: hasLegacyGoogleRealtimeProvider
|
|
21
21
|
}];
|
|
22
22
|
function migrateGoogleMeetLegacyRealtimeProvider(config) {
|
|
23
|
-
const
|
|
23
|
+
const rawEntry = asNullableRecord(config.plugins?.entries?.["google-meet"]);
|
|
24
|
+
const rawPluginConfig = asNullableRecord(rawEntry?.config);
|
|
25
|
+
const rawRealtime = asNullableRecord(rawPluginConfig?.realtime);
|
|
24
26
|
if (!rawRealtime || !hasLegacyGoogleRealtimeProvider(rawRealtime)) return null;
|
|
25
27
|
const nextConfig = structuredClone(config);
|
|
26
28
|
const nextPlugins = asNullableRecord(nextConfig.plugins) ?? {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
|
|
2
2
|
//#region extensions/google-meet/src/google-api-errors.ts
|
|
3
3
|
const REAUTH_HINT = "Re-run `openclaw googlemeet auth login` and store the refreshed oauth block.";
|
|
4
|
-
const GOOGLE_API_ERROR_BODY_LIMIT_BYTES =
|
|
4
|
+
const GOOGLE_API_ERROR_BODY_LIMIT_BYTES = 8192;
|
|
5
5
|
function scopeText(scopes) {
|
|
6
6
|
return scopes.map((scope) => `\`${scope}\``).join(", ");
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as GOOGLE_MEET_CLI_DESCRIPTOR } from "./cli-output-mode-BwH_6tH8.js";
|
|
2
2
|
import { n as GOOGLE_MEET_NODE_COMMAND } from "./google-meet-platform-constants-Bs5iAg3E.js";
|
|
3
3
|
import { r as resolveGoogleMeetConfig } from "./config-wBK8loBb.js";
|
|
4
|
-
import { a as createLazyGoogleMeetNodeInvokePolicy, c as loadGoogleMeetCliModule, d as normalizeMode, f as normalizeTransport, h as shouldJoinCreatedMeet, i as createGoogleMeetRuntimeAccessor, l as loadGoogleMeetNodeHostModule, m as sendGoogleMeetGatewayError, n as assertGoogleMeetAgentToolActionSupported, o as formatGoogleMeetGatewayError, p as resolveMeetingInput, r as callGoogleMeetGatewayFromTool, s as keepTrustedToolAgentId, t as asParamRecord, u as loadGoogleMeetPluginHelpers } from "./plugin-registration-
|
|
4
|
+
import { a as createLazyGoogleMeetNodeInvokePolicy, c as loadGoogleMeetCliModule, d as normalizeMode, f as normalizeTransport, h as shouldJoinCreatedMeet, i as createGoogleMeetRuntimeAccessor, l as loadGoogleMeetNodeHostModule, m as sendGoogleMeetGatewayError, n as assertGoogleMeetAgentToolActionSupported, o as formatGoogleMeetGatewayError, p as resolveMeetingInput, r as callGoogleMeetGatewayFromTool, s as keepTrustedToolAgentId, t as asParamRecord, u as loadGoogleMeetPluginHelpers } from "./plugin-registration-NIwMvP6X.js";
|
|
5
5
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
6
6
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
7
|
import { jsonResult } from "openclaw/plugin-sdk/tool-results";
|
|
@@ -338,7 +338,10 @@ var google_meet_default = definePluginEntry({
|
|
|
338
338
|
case "calendar_events":
|
|
339
339
|
case "artifacts":
|
|
340
340
|
case "attendance": return jsonResult(await queryActions[raw.action](raw));
|
|
341
|
-
case "export":
|
|
341
|
+
case "export": {
|
|
342
|
+
const helpers = await loadGoogleMeetPluginHelpers();
|
|
343
|
+
return jsonResult(await helpers.exportGoogleMeetBundleFromParams(config, raw));
|
|
344
|
+
}
|
|
342
345
|
case "leave":
|
|
343
346
|
case "speak":
|
|
344
347
|
if (!normalizeOptionalString(raw.sessionId)) throw new Error("sessionId required");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as readGoogleApiErrorDetail } from "./google-api-errors-
|
|
1
|
+
import { n as readGoogleApiErrorDetail } from "./google-api-errors-BDYXfKRa.js";
|
|
2
2
|
import { MAX_DATE_TIMESTAMP_MS, resolveDateTimestampMs, resolveExpiresAtMsFromDurationSeconds } from "openclaw/plugin-sdk/number-runtime";
|
|
3
3
|
import { parseOAuthCallbackInput, waitForLocalOAuthCallback } from "openclaw/plugin-sdk/provider-auth-runtime";
|
|
4
4
|
import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
|
|
@@ -9,7 +9,7 @@ const GOOGLE_MEET_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
|
9
9
|
const GOOGLE_MEET_TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
10
10
|
const GOOGLE_MEET_TOKEN_HOST = "oauth2.googleapis.com";
|
|
11
11
|
const GOOGLE_MEET_DEFAULT_TOKEN_LIFETIME_SECONDS = 3600;
|
|
12
|
-
const GOOGLE_OAUTH_TOKEN_JSON_MAX_BYTES =
|
|
12
|
+
const GOOGLE_OAUTH_TOKEN_JSON_MAX_BYTES = 262144;
|
|
13
13
|
const GOOGLE_OAUTH_REQUEST_TIMEOUT_MS = 3e4;
|
|
14
14
|
const GOOGLE_MEET_SCOPES = [
|
|
15
15
|
"https://www.googleapis.com/auth/meetings.space.created",
|
|
@@ -123,7 +123,8 @@ function isLocalCallbackListenerError(error) {
|
|
|
123
123
|
return error.message.includes("EADDRINUSE") || error.message.includes("port") || error.message.includes("listen");
|
|
124
124
|
}
|
|
125
125
|
async function readManualGoogleMeetAuthCode(params) {
|
|
126
|
-
const
|
|
126
|
+
const input = await params.promptInput("Paste the full redirect URL here: ");
|
|
127
|
+
const parsed = parseOAuthCallbackInput(input, {
|
|
127
128
|
missingState: "Missing 'state' parameter. Paste the full redirect URL.",
|
|
128
129
|
invalidInput: "Paste the full redirect URL, not just the code."
|
|
129
130
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as loadGoogleMeetCliModule, p as resolveMeetingInput } from "./plugin-registration-
|
|
2
|
-
import { t as googleApiError } from "./google-api-errors-
|
|
1
|
+
import { c as loadGoogleMeetCliModule, p as resolveMeetingInput } from "./plugin-registration-NIwMvP6X.js";
|
|
2
|
+
import { t as googleApiError } from "./google-api-errors-BDYXfKRa.js";
|
|
3
3
|
import { t as normalizeMeetUrl } from "./meet-url-BP2Jlvjs.js";
|
|
4
4
|
import { normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
@@ -87,7 +87,7 @@ function rankCalendarEvent(event, nowMs) {
|
|
|
87
87
|
const endMs = parseCalendarEventTime(event.end) ?? startMs;
|
|
88
88
|
if (startMs <= nowMs && endMs >= nowMs) return 0;
|
|
89
89
|
if (startMs > nowMs) return startMs - nowMs;
|
|
90
|
-
return nowMs - startMs +
|
|
90
|
+
return nowMs - startMs + 2592e6;
|
|
91
91
|
}
|
|
92
92
|
function chooseBestMeetCalendarEvent(events, now) {
|
|
93
93
|
const nowMs = now.getTime();
|
|
@@ -773,7 +773,7 @@ var plugin_helpers_exports = /* @__PURE__ */ __exportAll({
|
|
|
773
773
|
resolveMeetingFromParams: () => resolveMeetingFromParams,
|
|
774
774
|
resolveSpaceFromParams: () => resolveSpaceFromParams
|
|
775
775
|
});
|
|
776
|
-
const loadGoogleMeetCreateModule = createLazyRuntimeModule(() => import("./create-
|
|
776
|
+
const loadGoogleMeetCreateModule = createLazyRuntimeModule(() => import("./create-Djmk2CQz.js").then((n) => n.t));
|
|
777
777
|
async function createMeetFromParams(params) {
|
|
778
778
|
return (await loadGoogleMeetCreateModule()).createMeetFromParams(params);
|
|
779
779
|
}
|
|
@@ -781,7 +781,7 @@ async function createAndJoinMeetFromParams(params) {
|
|
|
781
781
|
return (await loadGoogleMeetCreateModule()).createAndJoinMeetFromParams(params);
|
|
782
782
|
}
|
|
783
783
|
async function resolveGoogleMeetTokenFromParams(config, raw) {
|
|
784
|
-
const { resolveGoogleMeetAccessToken } = await import("./oauth-
|
|
784
|
+
const { resolveGoogleMeetAccessToken } = await import("./oauth-DgBscjXK.js");
|
|
785
785
|
return resolveGoogleMeetAccessToken({
|
|
786
786
|
clientId: normalizeOptionalString(raw.clientId) ?? config.oauth.clientId,
|
|
787
787
|
clientSecret: normalizeOptionalString(raw.clientSecret) ?? config.oauth.clientSecret,
|
|
@@ -4,10 +4,10 @@ import { asNonArrayRecord as asParamRecord, normalizeOptionalString } from "open
|
|
|
4
4
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
5
5
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
6
6
|
//#region extensions/google-meet/src/plugin-registration.ts
|
|
7
|
-
const loadGoogleMeetPluginHelpers = createLazyRuntimeModule(() => import("./plugin-helpers-
|
|
8
|
-
const loadGoogleMeetCliModule = createLazyRuntimeModule(() => import("./cli-
|
|
7
|
+
const loadGoogleMeetPluginHelpers = createLazyRuntimeModule(() => import("./plugin-helpers-WF-JVJhh.js").then((n) => n.r));
|
|
8
|
+
const loadGoogleMeetCliModule = createLazyRuntimeModule(() => import("./cli-Cwc266K3.js"));
|
|
9
9
|
const loadGoogleMeetNodeHostModule = createLazyRuntimeModule(() => import("./node-host-BXtXbsMa.js"));
|
|
10
|
-
const loadGoogleMeetRuntimeModule = createLazyRuntimeModule(() => import("./runtime-
|
|
10
|
+
const loadGoogleMeetRuntimeModule = createLazyRuntimeModule(() => import("./runtime-0IuZTlpN.js"));
|
|
11
11
|
const loadGoogleMeetNodeInvokePolicyModule = createLazyRuntimeModule(() => import("./node-invoke-policy-B0gOlLJR.js"));
|
|
12
12
|
const loadGoogleMeetGatewayRuntimeModule = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/gateway-runtime"));
|
|
13
13
|
const loadGoogleMeetNodeInvokePolicy = async (config) => (await loadGoogleMeetNodeInvokePolicyModule()).createGoogleMeetChromeNodeInvokePolicy(config);
|
|
@@ -71,7 +71,8 @@ function resolveUserPath(input) {
|
|
|
71
71
|
}
|
|
72
72
|
function isProviderUnreachableWebhookUrl(webhookUrl) {
|
|
73
73
|
try {
|
|
74
|
-
|
|
74
|
+
const parsed = new URL(webhookUrl);
|
|
75
|
+
return isBlockedHostnameOrIp(parsed.hostname);
|
|
75
76
|
} catch {
|
|
76
77
|
return false;
|
|
77
78
|
}
|
|
@@ -355,10 +356,24 @@ function parseNodeStartResult(raw) {
|
|
|
355
356
|
if (!value || typeof value !== "object") throw new Error("Google Meet node returned an invalid start result.");
|
|
356
357
|
return value;
|
|
357
358
|
}
|
|
359
|
+
function chromeNodeBrowserRequest(runtime, nodeId) {
|
|
360
|
+
return async (request) => await callBrowserProxyOnNode({
|
|
361
|
+
runtime,
|
|
362
|
+
nodeId,
|
|
363
|
+
method: request.method,
|
|
364
|
+
path: request.path,
|
|
365
|
+
body: request.body,
|
|
366
|
+
timeoutMs: request.timeoutMs
|
|
367
|
+
});
|
|
368
|
+
}
|
|
358
369
|
async function leaveChromeMeet(params) {
|
|
370
|
+
const node = params.transport === "chrome-node" ? { nodeId: params.nodeId ?? await resolveChromeNode({
|
|
371
|
+
runtime: params.runtime,
|
|
372
|
+
requestedNode: params.config.chromeNode.node
|
|
373
|
+
}) } : void 0;
|
|
359
374
|
return await leaveMeetingWithBrowser({
|
|
360
375
|
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
361
|
-
callBrowser: await resolveLocalMeetingBrowserRequest(params.runtime),
|
|
376
|
+
callBrowser: node ? chromeNodeBrowserRequest(params.runtime, node.nodeId) : await resolveLocalMeetingBrowserRequest(params.runtime),
|
|
362
377
|
launch: params.config.chrome.launch,
|
|
363
378
|
meetingSessionId: params.meetingSessionId,
|
|
364
379
|
meetingUrl: params.meetingUrl,
|
|
@@ -367,59 +382,18 @@ async function leaveChromeMeet(params) {
|
|
|
367
382
|
});
|
|
368
383
|
}
|
|
369
384
|
async function readChromeMeetTranscript(params) {
|
|
370
|
-
|
|
371
|
-
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
372
|
-
callBrowser: await resolveLocalMeetingBrowserRequest(params.runtime),
|
|
373
|
-
finalize: params.finalize === true,
|
|
374
|
-
meetingUrl: params.meetingUrl,
|
|
375
|
-
meetingSessionId: params.meetingSessionId,
|
|
376
|
-
tab: params.tab,
|
|
377
|
-
timeoutMs: Math.min(Math.max(1e3, params.config.chrome.joinTimeoutMs), 1e4)
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
async function readChromeMeetTranscriptOnNode(params) {
|
|
381
|
-
const nodeId = params.nodeId ?? await resolveChromeNode({
|
|
385
|
+
const node = params.transport === "chrome-node" ? { nodeId: params.nodeId ?? await resolveChromeNode({
|
|
382
386
|
runtime: params.runtime,
|
|
383
387
|
requestedNode: params.config.chromeNode.node
|
|
384
|
-
});
|
|
385
|
-
const timeoutMs = Math.min(Math.max(1e3, params.config.chrome.joinTimeoutMs), 1e4);
|
|
388
|
+
}) } : void 0;
|
|
386
389
|
return await readMeetingTranscriptWithBrowser({
|
|
387
390
|
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
388
|
-
callBrowser:
|
|
389
|
-
runtime: params.runtime,
|
|
390
|
-
nodeId,
|
|
391
|
-
method: request.method,
|
|
392
|
-
path: request.path,
|
|
393
|
-
body: request.body,
|
|
394
|
-
timeoutMs: request.timeoutMs
|
|
395
|
-
}),
|
|
391
|
+
callBrowser: node ? chromeNodeBrowserRequest(params.runtime, node.nodeId) : await resolveLocalMeetingBrowserRequest(params.runtime),
|
|
396
392
|
finalize: params.finalize === true,
|
|
397
393
|
meetingUrl: params.meetingUrl,
|
|
398
394
|
meetingSessionId: params.meetingSessionId,
|
|
399
395
|
tab: params.tab,
|
|
400
|
-
timeoutMs
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
async function leaveChromeMeetOnNode(params) {
|
|
404
|
-
const nodeId = params.nodeId ?? await resolveChromeNode({
|
|
405
|
-
runtime: params.runtime,
|
|
406
|
-
requestedNode: params.config.chromeNode.node
|
|
407
|
-
});
|
|
408
|
-
return await leaveMeetingWithBrowser({
|
|
409
|
-
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
410
|
-
callBrowser: async (request) => await callBrowserProxyOnNode({
|
|
411
|
-
runtime: params.runtime,
|
|
412
|
-
nodeId,
|
|
413
|
-
method: request.method,
|
|
414
|
-
path: request.path,
|
|
415
|
-
body: request.body,
|
|
416
|
-
timeoutMs: request.timeoutMs
|
|
417
|
-
}),
|
|
418
|
-
launch: params.config.chrome.launch,
|
|
419
|
-
meetingSessionId: params.meetingSessionId,
|
|
420
|
-
meetingUrl: params.meetingUrl,
|
|
421
|
-
tab: params.tab,
|
|
422
|
-
timeoutMs: params.config.chrome.joinTimeoutMs
|
|
396
|
+
timeoutMs: Math.min(Math.max(1e3, params.config.chrome.joinTimeoutMs), 1e4)
|
|
423
397
|
});
|
|
424
398
|
}
|
|
425
399
|
async function openMeetWithBrowserProxy(params) {
|
|
@@ -468,43 +442,21 @@ async function openMeetWithBrowserProxy(params) {
|
|
|
468
442
|
});
|
|
469
443
|
}
|
|
470
444
|
async function recoverCurrentMeetTab(params) {
|
|
471
|
-
|
|
472
|
-
transport: "chrome",
|
|
473
|
-
...await recoverMeetingBrowserTab({
|
|
474
|
-
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
475
|
-
callBrowser: await resolveLocalMeetingBrowserRequest(params.runtime),
|
|
476
|
-
captureCaptions: shouldCaptureCaptions(params.mode ?? "bidi", params.fullConfig),
|
|
477
|
-
config: params.config.chrome,
|
|
478
|
-
locationLabel: "in local Chrome",
|
|
479
|
-
mode: params.mode ?? "bidi",
|
|
480
|
-
readOnly: params.readOnly,
|
|
481
|
-
requestedMeetingUrl: params.url,
|
|
482
|
-
trackedMeetingUrl: params.trackedMeetingUrl,
|
|
483
|
-
trackedTargetId: params.trackedTargetId
|
|
484
|
-
})
|
|
485
|
-
};
|
|
486
|
-
}
|
|
487
|
-
async function recoverCurrentMeetTabOnNode(params) {
|
|
488
|
-
const nodeId = await resolveChromeNode({
|
|
445
|
+
const node = params.transport === "chrome-node" ? { nodeId: await resolveChromeNode({
|
|
489
446
|
runtime: params.runtime,
|
|
490
447
|
requestedNode: params.config.chromeNode.node
|
|
491
|
-
});
|
|
448
|
+
}) } : void 0;
|
|
492
449
|
return {
|
|
493
|
-
|
|
494
|
-
|
|
450
|
+
...node ? {
|
|
451
|
+
transport: "chrome-node",
|
|
452
|
+
nodeId: node.nodeId
|
|
453
|
+
} : { transport: "chrome" },
|
|
495
454
|
...await recoverMeetingBrowserTab({
|
|
496
455
|
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
497
|
-
callBrowser:
|
|
498
|
-
runtime: params.runtime,
|
|
499
|
-
nodeId,
|
|
500
|
-
method: request.method,
|
|
501
|
-
path: request.path,
|
|
502
|
-
body: request.body,
|
|
503
|
-
timeoutMs: request.timeoutMs
|
|
504
|
-
}),
|
|
456
|
+
callBrowser: node ? chromeNodeBrowserRequest(params.runtime, node.nodeId) : await resolveLocalMeetingBrowserRequest(params.runtime),
|
|
505
457
|
captureCaptions: shouldCaptureCaptions(params.mode ?? "bidi", params.fullConfig),
|
|
506
458
|
config: params.config.chrome,
|
|
507
|
-
locationLabel: "on the selected Chrome node",
|
|
459
|
+
locationLabel: node ? "on the selected Chrome node" : "in local Chrome",
|
|
508
460
|
mode: params.mode ?? "bidi",
|
|
509
461
|
readOnly: params.readOnly,
|
|
510
462
|
requestedMeetingUrl: params.url,
|
|
@@ -665,11 +617,12 @@ async function launchChromeMeetOnNode(params) {
|
|
|
665
617
|
//#endregion
|
|
666
618
|
//#region extensions/google-meet/src/runtime-setup.ts
|
|
667
619
|
function collectChromeAudioCommands(config) {
|
|
668
|
-
|
|
620
|
+
const commands = config.chrome.audioBridgeCommand ? [config.chrome.audioBridgeCommand[0]] : [
|
|
669
621
|
config.chrome.audioInputCommand?.[0],
|
|
670
622
|
config.chrome.audioOutputCommand?.[0],
|
|
671
623
|
config.chrome.bargeInInputCommand?.[0]
|
|
672
|
-
]
|
|
624
|
+
];
|
|
625
|
+
return uniqueStrings(commands.filter((value) => Boolean(value?.trim())));
|
|
673
626
|
}
|
|
674
627
|
async function commandExists(runtime, command) {
|
|
675
628
|
return (await runtime.system.runCommandWithTimeout([
|
|
@@ -964,15 +917,11 @@ var GoogleMeetRuntime = class {
|
|
|
964
917
|
const transport = resolveTransport(request.transport, this.params.config);
|
|
965
918
|
if (transport === "twilio") throw new Error("recover_current_tab only supports chrome or chrome-node transports");
|
|
966
919
|
const url = request.url ? GOOGLE_MEET_PLATFORM_ADAPTER.urls.validateAndNormalize(request.url) : void 0;
|
|
967
|
-
return
|
|
968
|
-
runtime: this.params.runtime,
|
|
969
|
-
config: this.params.config,
|
|
970
|
-
fullConfig: this.params.fullConfig,
|
|
971
|
-
url
|
|
972
|
-
}) : await recoverCurrentMeetTab({
|
|
920
|
+
return await recoverCurrentMeetTab({
|
|
973
921
|
runtime: this.params.runtime,
|
|
974
922
|
config: this.params.config,
|
|
975
923
|
fullConfig: this.params.fullConfig,
|
|
924
|
+
transport,
|
|
976
925
|
url
|
|
977
926
|
});
|
|
978
927
|
}
|
|
@@ -1009,16 +958,7 @@ var GoogleMeetRuntime = class {
|
|
|
1009
958
|
async #joinTransport(request, session, context) {
|
|
1010
959
|
if (isBrowserTransport(session.transport)) {
|
|
1011
960
|
const chromeConfig = withSessionAgentConfig(this.params.config, session.agentId);
|
|
1012
|
-
const result = session.transport === "chrome-node" ?
|
|
1013
|
-
runtime: this.params.runtime,
|
|
1014
|
-
config: chromeConfig,
|
|
1015
|
-
fullConfig: this.params.fullConfig,
|
|
1016
|
-
meetingSessionId: session.id,
|
|
1017
|
-
requesterSessionKey: request.requesterSessionKey,
|
|
1018
|
-
mode: session.mode,
|
|
1019
|
-
url: session.url,
|
|
1020
|
-
logger: this.params.logger
|
|
1021
|
-
}) : await launchChromeMeet({
|
|
961
|
+
const result = await (session.transport === "chrome-node" ? launchChromeMeetOnNode : launchChromeMeet)({
|
|
1022
962
|
runtime: this.params.runtime,
|
|
1023
963
|
config: chromeConfig,
|
|
1024
964
|
fullConfig: this.params.fullConfig,
|
|
@@ -1125,15 +1065,7 @@ var GoogleMeetRuntime = class {
|
|
|
1125
1065
|
node: session.chrome.nodeId
|
|
1126
1066
|
} } : {}
|
|
1127
1067
|
};
|
|
1128
|
-
const result = session.transport === "chrome-node" ?
|
|
1129
|
-
runtime: this.params.runtime,
|
|
1130
|
-
config: recoveryConfig,
|
|
1131
|
-
fullConfig: this.params.fullConfig,
|
|
1132
|
-
meetingSessionId: session.id,
|
|
1133
|
-
mode: session.mode,
|
|
1134
|
-
url: session.url,
|
|
1135
|
-
logger: this.params.logger
|
|
1136
|
-
}) : await launchChromeMeet({
|
|
1068
|
+
const result = await (session.transport === "chrome-node" ? launchChromeMeetOnNode : launchChromeMeet)({
|
|
1137
1069
|
runtime: this.params.runtime,
|
|
1138
1070
|
config: recoveryConfig,
|
|
1139
1071
|
fullConfig: this.params.fullConfig,
|
|
@@ -1147,19 +1079,11 @@ var GoogleMeetRuntime = class {
|
|
|
1147
1079
|
}
|
|
1148
1080
|
async #refreshBrowserHealth(session, options = {}) {
|
|
1149
1081
|
try {
|
|
1150
|
-
const result =
|
|
1151
|
-
runtime: this.params.runtime,
|
|
1152
|
-
config: this.params.config,
|
|
1153
|
-
fullConfig: this.params.fullConfig,
|
|
1154
|
-
mode: session.mode,
|
|
1155
|
-
readOnly: options.readOnly,
|
|
1156
|
-
trackedMeetingUrl: session.url,
|
|
1157
|
-
trackedTargetId: session.chrome?.browserTab?.targetId,
|
|
1158
|
-
url: session.url
|
|
1159
|
-
}) : await recoverCurrentMeetTab({
|
|
1082
|
+
const result = await recoverCurrentMeetTab({
|
|
1160
1083
|
runtime: this.params.runtime,
|
|
1161
1084
|
config: this.params.config,
|
|
1162
1085
|
fullConfig: this.params.fullConfig,
|
|
1086
|
+
transport: session.transport === "chrome-node" ? "chrome-node" : "chrome",
|
|
1163
1087
|
mode: session.mode,
|
|
1164
1088
|
readOnly: options.readOnly,
|
|
1165
1089
|
trackedMeetingUrl: session.url,
|
|
@@ -1236,16 +1160,12 @@ var GoogleMeetRuntime = class {
|
|
|
1236
1160
|
async #captureTranscript(session, options = {}) {
|
|
1237
1161
|
const tab = session.chrome?.browserTab;
|
|
1238
1162
|
if (!tab) return;
|
|
1239
|
-
return
|
|
1240
|
-
runtime: this.params.runtime,
|
|
1241
|
-
nodeId: session.chrome?.nodeId,
|
|
1242
|
-
config: this.params.config,
|
|
1243
|
-
...options.finalize === void 0 ? {} : { finalize: options.finalize },
|
|
1244
|
-
meetingUrl: session.url,
|
|
1245
|
-
meetingSessionId: session.id,
|
|
1246
|
-
tab
|
|
1247
|
-
}) : await readChromeMeetTranscript({
|
|
1163
|
+
return await readChromeMeetTranscript({
|
|
1248
1164
|
runtime: this.params.runtime,
|
|
1165
|
+
...session.transport === "chrome-node" ? {
|
|
1166
|
+
transport: "chrome-node",
|
|
1167
|
+
nodeId: session.chrome?.nodeId
|
|
1168
|
+
} : {},
|
|
1249
1169
|
config: this.params.config,
|
|
1250
1170
|
...options.finalize === void 0 ? {} : { finalize: options.finalize },
|
|
1251
1171
|
meetingUrl: session.url,
|
|
@@ -1268,15 +1188,12 @@ var GoogleMeetRuntime = class {
|
|
|
1268
1188
|
}
|
|
1269
1189
|
let left;
|
|
1270
1190
|
try {
|
|
1271
|
-
const result =
|
|
1272
|
-
runtime: this.params.runtime,
|
|
1273
|
-
nodeId: session.chrome?.nodeId,
|
|
1274
|
-
config: this.params.config,
|
|
1275
|
-
meetingSessionId: session.id,
|
|
1276
|
-
meetingUrl: session.url,
|
|
1277
|
-
tab
|
|
1278
|
-
}) : await leaveChromeMeet({
|
|
1191
|
+
const result = await leaveChromeMeet({
|
|
1279
1192
|
runtime: this.params.runtime,
|
|
1193
|
+
...session.transport === "chrome-node" ? {
|
|
1194
|
+
transport: "chrome-node",
|
|
1195
|
+
nodeId: session.chrome?.nodeId
|
|
1196
|
+
} : {},
|
|
1280
1197
|
config: this.params.config,
|
|
1281
1198
|
meetingSessionId: session.id,
|
|
1282
1199
|
meetingUrl: session.url,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const Email = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[^"\\]
|
|
1
|
+
const Email = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[^"\\]|\\[\x20-\x7e])*")@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*|\[(?:IPv6:[a-f0-9:]+|(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})\])$/i;
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is an Email
|
|
4
4
|
* @specification https://datatracker.ietf.org/doc/html/rfc5322
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import * as FormatBidi from './format/bidi.mjs';
|
|
2
2
|
import * as LabelUnicode from './label/unicode.mjs';
|
|
3
3
|
import * as LabelPuny from './label/puny.mjs';
|
|
4
|
+
// ------------------------------------------------------------------
|
|
5
|
+
// IsLabel
|
|
6
|
+
// ------------------------------------------------------------------
|
|
4
7
|
function IsValidLabelLength(value) {
|
|
5
8
|
return value.length > 0 && value.length <= 63;
|
|
6
9
|
}
|
|
@@ -8,9 +11,24 @@ function IsLabel(value) {
|
|
|
8
11
|
return IsValidLabelLength(value) && (LabelPuny.IsPunyLabel(value) ||
|
|
9
12
|
LabelUnicode.IsUnicodeLabel(value));
|
|
10
13
|
}
|
|
14
|
+
// ------------------------------------------------------------------
|
|
15
|
+
// NormalizeHostname
|
|
16
|
+
//
|
|
17
|
+
// Normalizes a hostname for label validation. Normalizes for NFC
|
|
18
|
+
// such that equivalent codepoint sequences can be uniformly
|
|
19
|
+
// compared. It also removes codepoints that IDNA mapping ignores,
|
|
20
|
+
// and converts full stop variants to ASCII '.' so the hostname can
|
|
21
|
+
// be split into labels.
|
|
22
|
+
// ------------------------------------------------------------------
|
|
11
23
|
function NormalizeHostname(value) {
|
|
12
|
-
return value
|
|
24
|
+
return value
|
|
25
|
+
.normalize('NFC')
|
|
26
|
+
.replace(/[\u00ad\u034f\u180b-\u180d\u200b\ufe00-\ufe0f\u{e0100}-\u{e01ef}]/gu, '') // RE_IGNORED_MAPPING
|
|
27
|
+
.replace(/[\u002E\u3002\uFF0E\uFF61]/g, '.'); // RE_FULL_STOP_MAPPING
|
|
13
28
|
}
|
|
29
|
+
// ------------------------------------------------------------------
|
|
30
|
+
// IsIdnHostname
|
|
31
|
+
// ------------------------------------------------------------------
|
|
14
32
|
export function IsIdnHostname(value) {
|
|
15
33
|
if (value.length === 0 || value.includes(' '))
|
|
16
34
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/google-meet",
|
|
3
|
-
"version": "2026.9.1
|
|
3
|
+
"version": "2026.9.1",
|
|
4
4
|
"description": "OpenClaw Google Meet participant plugin for joining calls through Chrome or Twilio transports.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
"type": "module",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"jszip": "3.10.1",
|
|
12
|
-
"typebox": "1.3.
|
|
12
|
+
"typebox": "1.3.17"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"openclaw": ">=2026.9.1
|
|
15
|
+
"openclaw": ">=2026.9.1"
|
|
16
16
|
},
|
|
17
17
|
"peerDependenciesMeta": {
|
|
18
18
|
"openclaw": {
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"minHostVersion": ">=2026.4.20"
|
|
30
30
|
},
|
|
31
31
|
"compat": {
|
|
32
|
-
"pluginApi": ">=2026.9.1
|
|
32
|
+
"pluginApi": ">=2026.9.1"
|
|
33
33
|
},
|
|
34
34
|
"build": {
|
|
35
|
-
"openclawVersion": "2026.9.1
|
|
35
|
+
"openclawVersion": "2026.9.1"
|
|
36
36
|
},
|
|
37
37
|
"release": {
|
|
38
38
|
"publishToClawHub": true,
|