






















@@ -1,3 +1,8 @@
1+import {
2+callGatewayFromCli,
3+ErrorCodes,
4+errorShape,
5+} from "openclaw/plugin-sdk/browser-node-runtime";
16import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
27import type { GatewayRequestHandlerOptions } from "openclaw/plugin-sdk/gateway-runtime";
38import { definePluginEntry, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
@@ -287,6 +292,78 @@ function shouldJoinCreatedMeet(raw: Record<string, unknown>): boolean {
287292return raw.join !== false && raw.join !== "false";
288293}
289294295+const googleMeetToolDeps = {
296+ callGatewayFromCli,
297+};
298+299+export const __testing = {
300+setCallGatewayFromCliForTests(next?: typeof callGatewayFromCli): void {
301+googleMeetToolDeps.callGatewayFromCli = next ?? callGatewayFromCli;
302+},
303+};
304+305+type GoogleMeetGatewayToolAction =
306+| "join"
307+| "create"
308+| "status"
309+| "recover_current_tab"
310+| "setup_status"
311+| "leave"
312+| "speak"
313+| "test_speech";
314+315+function googleMeetGatewayMethodForToolAction(action: GoogleMeetGatewayToolAction): string {
316+switch (action) {
317+case "recover_current_tab":
318+return "googlemeet.recoverCurrentTab";
319+case "setup_status":
320+return "googlemeet.setup";
321+case "test_speech":
322+return "googlemeet.testSpeech";
323+default:
324+return `googlemeet.${action}`;
325+}
326+}
327+328+function resolveGoogleMeetToolGatewayTimeoutMs(config: GoogleMeetConfig): number {
329+return Math.max(
330+60_000,
331+config.chrome.joinTimeoutMs + 30_000,
332+config.voiceCall.requestTimeoutMs + 10_000,
333+);
334+}
335+336+function readGatewayErrorDetails(err: unknown): unknown {
337+if (!err || typeof err !== "object" || !("details" in err)) {
338+return undefined;
339+}
340+return (err as { details?: unknown }).details;
341+}
342+343+async function callGoogleMeetGatewayFromTool(params: {
344+config: GoogleMeetConfig;
345+action: GoogleMeetGatewayToolAction;
346+raw: Record<string, unknown>;
347+}): Promise<unknown> {
348+try {
349+return await googleMeetToolDeps.callGatewayFromCli(
350+googleMeetGatewayMethodForToolAction(params.action),
351+{
352+json: true,
353+timeout: String(resolveGoogleMeetToolGatewayTimeoutMs(params.config)),
354+},
355+params.raw,
356+{ progress: false },
357+);
358+} catch (err) {
359+const details = readGatewayErrorDetails(err);
360+if (details && typeof details === "object") {
361+return details;
362+}
363+throw err;
364+}
365+}
366+290367async function createMeetFromParams(params: {
291368config: GoogleMeetConfig;
292369runtime: OpenClawPluginApi["runtime"];
@@ -498,8 +575,23 @@ export default definePluginEntry({
498575const formatGatewayError = (err: unknown) =>
499576isGoogleMeetBrowserManualActionError(err) ? err.payload : { error: formatErrorMessage(err) };
500577501-const sendError = (respond: (ok: boolean, payload?: unknown) => void, err: unknown) => {
502-respond(false, formatGatewayError(err));
578+const sendError = (
579+respond: GatewayRequestHandlerOptions["respond"],
580+err: unknown,
581+code: Parameters<typeof errorShape>[0] = ErrorCodes.UNAVAILABLE,
582+) => {
583+const payload = formatGatewayError(err);
584+respond(
585+false,
586+payload,
587+errorShape(
588+code,
589+typeof payload.error === "string" ? payload.error : "Google Meet request failed",
590+{
591+details: payload,
592+},
593+),
594+);
503595};
504596505597api.registerGatewayMethod(
@@ -699,7 +791,7 @@ export default definePluginEntry({
699791try {
700792const sessionId = normalizeOptionalString(params?.sessionId);
701793if (!sessionId) {
702-respond(false, { error: "sessionId required" });
794+sendError(respond, new Error("sessionId required"), ErrorCodes.INVALID_REQUEST);
703795return;
704796}
705797const rt = await ensureRuntime();
@@ -716,7 +808,7 @@ export default definePluginEntry({
716808try {
717809const sessionId = normalizeOptionalString(params?.sessionId);
718810if (!sessionId) {
719-respond(false, { error: "sessionId required" });
811+sendError(respond, new Error("sessionId required"), ErrorCodes.INVALID_REQUEST);
720812return;
721813}
722814const rt = await ensureRuntime();
@@ -759,61 +851,32 @@ export default definePluginEntry({
759851try {
760852switch (raw.action) {
761853case "join": {
762-const rt = await ensureRuntime();
763-return json(
764-await rt.join({
765-url: resolveMeetingInput(config, raw.url),
766-transport: normalizeTransport(raw.transport),
767-mode: normalizeMode(raw.mode),
768-dialInNumber: normalizeOptionalString(raw.dialInNumber),
769-pin: normalizeOptionalString(raw.pin),
770-dtmfSequence: normalizeOptionalString(raw.dtmfSequence),
771-message: normalizeOptionalString(raw.message),
772-}),
773-);
854+return json(await callGoogleMeetGatewayFromTool({ config, action: "join", raw }));
774855}
775856case "create": {
776-return json(
777-shouldJoinCreatedMeet(raw)
778- ? await createAndJoinMeetFromParams({
779- config,
780-runtime: api.runtime,
781- raw,
782- ensureRuntime,
783-})
784- : await createMeetFromParams({ config, runtime: api.runtime, raw }),
785-);
857+return json(await callGoogleMeetGatewayFromTool({ config, action: "create", raw }));
786858}
787859case "test_speech": {
788-const rt = await ensureRuntime();
789860return json(
790-await rt.testSpeech({
791-url: resolveMeetingInput(config, raw.url),
792-transport: normalizeTransport(raw.transport),
793-mode: normalizeMode(raw.mode),
794-dialInNumber: normalizeOptionalString(raw.dialInNumber),
795-pin: normalizeOptionalString(raw.pin),
796-dtmfSequence: normalizeOptionalString(raw.dtmfSequence),
797-message: normalizeOptionalString(raw.message),
798-}),
861+await callGoogleMeetGatewayFromTool({ config, action: "test_speech", raw }),
799862);
800863}
801864case "status": {
802-const rt = await ensureRuntime();
803-return json(rt.status(normalizeOptionalString(raw.sessionId)));
865+return json(await callGoogleMeetGatewayFromTool({ config, action: "status", raw }));
804866}
805867case "recover_current_tab": {
806-const rt = await ensureRuntime();
807868return json(
808-await rt.recoverCurrentTab({
809-url: normalizeOptionalString(raw.url),
810-transport: normalizeTransport(raw.transport),
869+await callGoogleMeetGatewayFromTool({
870+ config,
871+action: "recover_current_tab",
872+ raw,
811873}),
812874);
813875}
814876case "setup_status": {
815-const rt = await ensureRuntime();
816-return json(await rt.setupStatus({ transport: normalizeTransport(raw.transport) }));
877+return json(
878+await callGoogleMeetGatewayFromTool({ config, action: "setup_status", raw }),
879+);
817880}
818881case "resolve_space": {
819882const { token: _token, ...result } = await resolveSpaceFromParams(config, raw);
@@ -890,20 +953,18 @@ export default definePluginEntry({
890953return json(await exportGoogleMeetBundleFromParams(config, raw));
891954}
892955case "leave": {
893-const rt = await ensureRuntime();
894956const sessionId = normalizeOptionalString(raw.sessionId);
895957if (!sessionId) {
896958throw new Error("sessionId required");
897959}
898-return json(await rt.leave(sessionId));
960+return json(await callGoogleMeetGatewayFromTool({ config, action: "leave", raw }));
899961}
900962case "speak": {
901-const rt = await ensureRuntime();
902963const sessionId = normalizeOptionalString(raw.sessionId);
903964if (!sessionId) {
904965throw new Error("sessionId required");
905966}
906-return json(rt.speak(sessionId, normalizeOptionalString(raw.message)));
967+return json(await callGoogleMeetGatewayFromTool({ config, action: "speak", raw }));
907968}
908969default:
909970throw new Error("unknown google_meet action");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。