@openclaw/googlechat 2026.7.1-beta.6 → 2026.7.2-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.
@@ -1,15 +1,73 @@
1
- import { A as readGoogleChatApprovalActionToken, C as verifyGoogleChatRequest, D as completeGoogleChatApprovalCardBinding, E as claimGoogleChatApprovalCardBinding, N as releaseGoogleChatApprovalCardBinding, S as uploadGoogleChatAttachment, _ as downloadGoogleChatMedia, b as sendGoogleChatMessage, c as isGoogleChatGroupSpace, h as deleteGoogleChatMessage, k as getGoogleChatApprovalCardBinding, x as updateGoogleChatMessage, y as probeGoogleChat } from "./channel.adapters-FEj7zUjh.js";
2
- import { E as resolveDefaultGroupPolicy, M as warnMissingProviderGroupPolicyFallbackOnce, O as resolveInboundRouteEnvelopeBuilderWithRuntime, P as getGoogleChatRuntime, k as resolveWebhookPath, m as isDangerousNameMatchingEnabled, n as GROUP_POLICY_BLOCKED_LABEL, u as createChannelPairingController, w as resolveAllowlistProviderRuntimeGroupPolicy } from "./runtime-api-BbVoWRxq.js";
3
- import { n as googleChatApprovalAuth } from "./approval-auth-C_BVZZFA.js";
1
+ import { C as completeGoogleChatApprovalCardBinding, E as readGoogleChatApprovalActionToken, S as claimGoogleChatApprovalCardBinding, T as getGoogleChatApprovalCardBinding, _ as sendGoogleChatMessage, c as isGoogleChatGroupSpace, g as probeGoogleChat, h as downloadGoogleChatMedia, k as releaseGoogleChatApprovalCardBinding, m as deleteGoogleChatMessage, v as updateGoogleChatMessage, y as verifyGoogleChatRequest } from "./channel.adapters-CvESEXlT.js";
2
+ import { C as resolveInboundRouteEnvelopeBuilderWithRuntime, D as warnMissingProviderGroupPolicyFallbackOnce, b as resolveAllowlistProviderRuntimeGroupPolicy, c as createChannelPairingController, f as isDangerousNameMatchingEnabled, k as getGoogleChatRuntime, n as GROUP_POLICY_BLOCKED_LABEL, w as resolveWebhookPath, x as resolveDefaultGroupPolicy } from "./runtime-api-1v-DgldF.js";
3
+ import { n as googleChatApprovalAuth } from "./approval-auth-CMMwmCPY.js";
4
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
6
6
  import { recordChannelBotPairLoopAndCheckSuppression } from "openclaw/plugin-sdk/channel-inbound";
7
7
  import { WEBHOOK_RATE_LIMIT_DEFAULTS, createFixedWindowRateLimiter, normalizeWebhookPath, resolveRequestClientIp } from "openclaw/plugin-sdk/webhook-ingress";
8
8
  import { registerWebhookTargetWithPluginRoute, resolveWebhookTargetWithAuthOrReject, withResolvedWebhookRequestPipeline } from "openclaw/plugin-sdk/webhook-targets";
9
9
  import { createWebhookInFlightLimiter, readJsonWebhookBodyOrReject } from "openclaw/plugin-sdk/webhook-request-guards";
10
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
10
11
  import { resolveApprovalOverGateway } from "openclaw/plugin-sdk/approval-gateway-runtime";
11
12
  import { channelIngressRoutes, createChannelIngressResolver, defineStableChannelIngressIdentity } from "openclaw/plugin-sdk/channel-ingress-runtime";
12
- import { deliverTextOrMediaReply, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
13
+ import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
14
+ //#region extensions/googlechat/src/approval-terminal-card.ts
15
+ const GOOGLECHAT_APPROVAL_CARD_ID = "openclaw-approval";
16
+ const MAX_TEXT_PARAGRAPH_CHARS = 1800;
17
+ function escapeGoogleChatText(text) {
18
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
19
+ }
20
+ function truncateText(text) {
21
+ return text.length <= MAX_TEXT_PARAGRAPH_CHARS ? text : `${truncateUtf16Safe(text, MAX_TEXT_PARAGRAPH_CHARS - 3)}...`;
22
+ }
23
+ function formatApprovalId(value) {
24
+ return JSON.stringify(value).slice(1, -1);
25
+ }
26
+ function formatCanonicalOutcome(approval) {
27
+ switch (approval.status) {
28
+ case "allowed": return approval.decision === "allow-always" ? "Allowed always" : "Allowed once";
29
+ case "denied": return "Denied";
30
+ case "expired": return "Expired";
31
+ case "cancelled": return "Cancelled";
32
+ }
33
+ return "Unavailable";
34
+ }
35
+ function buildSubjectSection(presentation) {
36
+ if (presentation.kind === "exec") return {
37
+ header: "Command",
38
+ widgets: [{ textParagraph: { text: escapeGoogleChatText(truncateText(presentation.commandPreview ?? presentation.commandText)) } }]
39
+ };
40
+ const description = presentation.description.trim();
41
+ return {
42
+ header: "Request",
43
+ widgets: [{ textParagraph: { text: truncateText(`<b>${escapeGoogleChatText(presentation.title)}</b>${description ? `<br>${escapeGoogleChatText(description)}` : ""}`) } }]
44
+ };
45
+ }
46
+ /** Render the canonical first-answer result without retaining any actionable buttons. */
47
+ function buildGoogleChatCanonicalApprovalTerminalCards(result) {
48
+ const { approval } = result;
49
+ const kindLabel = approval.presentation.kind === "plugin" ? "Plugin" : "Exec";
50
+ const detailLines = [
51
+ `<b>Approval ID:</b> ${escapeGoogleChatText(formatApprovalId(approval.id))}`,
52
+ `<b>Status:</b> ${escapeGoogleChatText(approval.status)}`,
53
+ ...approval.status === "allowed" || approval.status === "denied" ? [`<b>Decision:</b> ${escapeGoogleChatText(approval.decision)}`] : [],
54
+ `<b>Reason:</b> ${escapeGoogleChatText(approval.reason)}`
55
+ ];
56
+ return [{
57
+ cardId: GOOGLECHAT_APPROVAL_CARD_ID,
58
+ card: {
59
+ header: {
60
+ title: `${kindLabel} Approval: ${formatCanonicalOutcome(approval)}`,
61
+ subtitle: result.applied ? "Resolved by this action" : "Already resolved"
62
+ },
63
+ sections: [buildSubjectSection(approval.presentation), {
64
+ header: "Details",
65
+ widgets: [{ textParagraph: { text: truncateText(detailLines.join("<br>")) } }]
66
+ }]
67
+ }
68
+ }];
69
+ }
70
+ //#endregion
13
71
  //#region extensions/googlechat/src/approval-card-click.ts
14
72
  function logIgnored(target, message) {
15
73
  target.runtime.log?.(`[${target.account.accountId}] googlechat approval ignored: ${message}`);
@@ -60,21 +118,29 @@ async function maybeHandleGoogleChatApprovalCardClick(params) {
60
118
  return true;
61
119
  }
62
120
  const consumed = claim.binding;
121
+ let result;
63
122
  try {
64
- await resolveApprovalOverGateway({
123
+ result = await resolveApprovalOverGateway({
65
124
  cfg: params.target.config,
66
125
  approvalId: consumed.approvalId,
126
+ approvalKind: consumed.approvalKind,
67
127
  decision: consumed.decision,
68
128
  senderId: actor,
69
- allowPluginFallback: consumed.approvalKind === "exec",
70
129
  clientDisplayName: `Google Chat approval (${actor?.trim() || "unknown"})`
71
130
  });
131
+ await updateGoogleChatMessage({
132
+ account: params.target.account,
133
+ messageName: consumed.messageName,
134
+ cardsV2: buildGoogleChatCanonicalApprovalTerminalCards(result)
135
+ });
72
136
  } catch (error) {
73
137
  releaseGoogleChatApprovalCardBinding(token);
74
138
  throw error;
75
139
  }
76
140
  completeGoogleChatApprovalCardBinding(token);
77
- params.target.runtime.log?.(`[${params.target.account.accountId}] googlechat approval resolved id=${consumed.approvalId} decision=${consumed.decision} sender=${actor || "unknown"}`);
141
+ const outcome = result.applied ? "resolved" : "already resolved";
142
+ const decision = "decision" in result.approval ? result.approval.decision : "none";
143
+ params.target.runtime.log?.(`[${params.target.account.accountId}] googlechat approval ${outcome} id=${consumed.approvalId} status=${result.approval.status} decision=${decision} sender=${actor || "unknown"}`);
78
144
  return true;
79
145
  }
80
146
  //#endregion
@@ -112,7 +178,7 @@ const googleChatIngressIdentity = defineStableChannelIngressIdentity({
112
178
  isWildcardEntry: (entry) => normalizeEntryValue(entry) === "*",
113
179
  resolveEntryId: ({ entryIndex, fieldKey }) => fieldKey === "stableId" ? `entry-${entryIndex + 1}:user` : `entry-${entryIndex + 1}:${fieldKey}`
114
180
  });
115
- function resolveGroupConfig(params) {
181
+ function resolveGoogleChatGroupConfig(params) {
116
182
  const { groupId, groupName, groups } = params;
117
183
  const entries = groups ?? {};
118
184
  const keys = Object.keys(entries);
@@ -191,7 +257,7 @@ async function applyGoogleChatInboundAccessPolicy(params) {
191
257
  log: logVerbose
192
258
  });
193
259
  warnMutableGroupKeysConfigured(logVerbose, account.config.groups ?? void 0);
194
- const groupConfigResolved = resolveGroupConfig({
260
+ const groupConfigResolved = resolveGoogleChatGroupConfig({
195
261
  groupId: spaceId,
196
262
  groupName: space.displayName ?? null,
197
263
  groups: account.config.groups ?? void 0
@@ -357,49 +423,50 @@ async function applyGoogleChatInboundAccessPolicy(params) {
357
423
  //#endregion
358
424
  //#region extensions/googlechat/src/monitor-durable.ts
359
425
  function resolveGoogleChatDurableReplyOptions(params) {
360
- if (params.infoKind !== "final" || params.typingMessageName) return false;
426
+ if (params.infoKind !== "final" || params.hasTypingMessage) return false;
361
427
  const threadId = params.payload.replyToId?.trim() || void 0;
428
+ if (!threadId) return {
429
+ to: params.spaceId,
430
+ replyToId: null
431
+ };
362
432
  return {
363
433
  to: params.spaceId,
364
- ...threadId ? {
365
- replyToId: threadId,
366
- threadId
367
- } : {}
434
+ replyToId: threadId,
435
+ threadId
368
436
  };
369
437
  }
370
438
  //#endregion
371
439
  //#region extensions/googlechat/src/monitor-reply-delivery.ts
372
440
  async function deliverGoogleChatReply(params) {
373
441
  const { payload, account, spaceId, runtime, core, config, statusSink } = params;
374
- let typingMessageName = params.typingMessageName;
442
+ let typingMessage = params.typingMessage;
443
+ const replyThreadName = payload.replyToId?.trim() || void 0;
444
+ const typingMessageThreadName = typingMessage?.thread?.trim() || void 0;
375
445
  const reply = resolveSendableOutboundReplyParts(payload);
376
- const mediaCount = reply.mediaCount;
377
- const hasMedia = reply.hasMedia;
378
446
  const text = reply.text;
379
447
  let firstTextChunk = true;
380
- let suppressCaption = false;
381
- if (hasMedia && typingMessageName) try {
382
- await deleteGoogleChatMessage({
383
- account,
384
- messageName: typingMessageName
385
- });
386
- typingMessageName = void 0;
387
- } catch (err) {
388
- runtime.error?.(`Google Chat typing cleanup failed: ${String(err)}`);
389
- if (typingMessageName) {
390
- const fallbackText = reply.hasText ? text : mediaCount > 1 ? "Sent attachments." : "Sent attachment.";
391
- try {
392
- await updateGoogleChatMessage({
393
- account,
394
- messageName: typingMessageName,
395
- text: fallbackText
396
- });
397
- suppressCaption = Boolean(text.trim());
398
- } catch (updateErr) {
399
- runtime.error?.(`Google Chat typing update failed: ${String(updateErr)}`);
400
- typingMessageName = void 0;
401
- }
448
+ if (typingMessage && typingMessageThreadName !== replyThreadName) {
449
+ try {
450
+ await deleteGoogleChatMessage({
451
+ account,
452
+ messageName: typingMessage.name
453
+ });
454
+ } catch (err) {
455
+ runtime.error?.(`Google Chat typing cleanup failed: ${String(err)}`);
402
456
  }
457
+ typingMessage = void 0;
458
+ }
459
+ if (reply.hasMedia) runtime.error?.("Google Chat outbound attachments require user OAuth and are not supported by this service-account channel; sending text fallback only.");
460
+ if (reply.hasMedia && !reply.hasText) {
461
+ try {
462
+ if (typingMessage) await deleteGoogleChatMessage({
463
+ account,
464
+ messageName: typingMessage.name
465
+ });
466
+ } catch (err) {
467
+ runtime.error?.(`Google Chat typing cleanup failed: ${String(err)}`);
468
+ }
469
+ throw new Error("Google Chat outbound attachments require user OAuth and no text fallback is available.");
403
470
  }
404
471
  const chunkLimit = account.config.textChunkLimit ?? 4e3;
405
472
  const chunkMode = core.channel.text.resolveChunkMode(config, "googlechat", account.accountId);
@@ -408,78 +475,36 @@ async function deliverGoogleChatReply(params) {
408
475
  account,
409
476
  space: spaceId,
410
477
  text: chunk,
411
- thread: payload.replyToId
478
+ thread: replyThreadName
412
479
  });
413
480
  };
414
- await deliverTextOrMediaReply({
415
- payload,
416
- text: suppressCaption ? "" : reply.text,
417
- chunkText: (value) => core.channel.text.chunkMarkdownTextWithMode(value, chunkLimit, chunkMode),
418
- sendText: async (chunk) => {
419
- try {
420
- if (firstTextChunk && typingMessageName) await updateGoogleChatMessage({
421
- account,
422
- messageName: typingMessageName,
423
- text: chunk
424
- });
425
- else await sendTextMessage(chunk);
426
- firstTextChunk = false;
427
- statusSink?.({ lastOutboundAt: Date.now() });
428
- } catch (err) {
429
- runtime.error?.(`Google Chat message send failed: ${String(err)}`);
430
- if (firstTextChunk && typingMessageName) {
431
- typingMessageName = void 0;
432
- try {
433
- await sendTextMessage(chunk);
434
- statusSink?.({ lastOutboundAt: Date.now() });
435
- } catch (fallbackErr) {
436
- runtime.error?.(`Google Chat message fallback send failed: ${String(fallbackErr)}`);
437
- } finally {
438
- firstTextChunk = false;
439
- }
481
+ const chunks = core.channel.text.chunkMarkdownTextWithMode(text, chunkLimit, chunkMode);
482
+ for (const chunk of chunks) {
483
+ if (!chunk) continue;
484
+ try {
485
+ if (firstTextChunk && typingMessage) await updateGoogleChatMessage({
486
+ account,
487
+ messageName: typingMessage.name,
488
+ text: chunk
489
+ });
490
+ else await sendTextMessage(chunk);
491
+ firstTextChunk = false;
492
+ statusSink?.({ lastOutboundAt: Date.now() });
493
+ } catch (err) {
494
+ runtime.error?.(`Google Chat message send failed: ${String(err)}`);
495
+ if (firstTextChunk && typingMessage) {
496
+ typingMessage = void 0;
497
+ try {
498
+ await sendTextMessage(chunk);
499
+ statusSink?.({ lastOutboundAt: Date.now() });
500
+ } catch (fallbackErr) {
501
+ runtime.error?.(`Google Chat message fallback send failed: ${String(fallbackErr)}`);
502
+ } finally {
503
+ firstTextChunk = false;
440
504
  }
441
505
  }
442
- },
443
- sendMedia: async ({ mediaUrl, caption }) => {
444
- try {
445
- const loaded = await core.channel.media.readRemoteMediaBuffer({
446
- url: mediaUrl,
447
- maxBytes: (account.config.mediaMaxMb ?? 20) * 1024 * 1024
448
- });
449
- const upload = await uploadAttachmentForReply({
450
- account,
451
- spaceId,
452
- buffer: loaded.buffer,
453
- contentType: loaded.contentType,
454
- filename: loaded.fileName ?? "attachment"
455
- });
456
- if (!upload.attachmentUploadToken) throw new Error("missing attachment upload token");
457
- await sendGoogleChatMessage({
458
- account,
459
- space: spaceId,
460
- text: caption,
461
- thread: payload.replyToId,
462
- attachments: [{
463
- attachmentUploadToken: upload.attachmentUploadToken,
464
- contentName: loaded.fileName
465
- }]
466
- });
467
- statusSink?.({ lastOutboundAt: Date.now() });
468
- } catch (err) {
469
- runtime.error?.(`Google Chat attachment send failed: ${String(err)}`);
470
- }
471
506
  }
472
- });
473
- }
474
- async function uploadAttachmentForReply(params) {
475
- const { account, spaceId, buffer, contentType, filename } = params;
476
- return await uploadGoogleChatAttachment({
477
- account,
478
- space: spaceId,
479
- filename,
480
- buffer,
481
- contentType
482
- });
507
+ }
483
508
  }
484
509
  //#endregion
485
510
  //#region extensions/googlechat/src/monitor-webhook.ts
@@ -893,8 +918,8 @@ async function processMessageWithPipeline(params) {
893
918
  });
894
919
  let mediaPath;
895
920
  let mediaType;
896
- if (attachments.length > 0) {
897
- const first = attachments[0];
921
+ const first = attachments.at(0);
922
+ if (first) {
898
923
  const attachmentData = await downloadAttachment(first, account, mediaMaxMb, core);
899
924
  if (attachmentData) {
900
925
  mediaPath = attachmentData.path;
@@ -964,9 +989,10 @@ async function processMessageWithPipeline(params) {
964
989
  runtime.error?.(`[${account.accountId}] typingIndicator="reaction" requires user OAuth (not supported with service account). Falling back to "message" mode.`);
965
990
  typingIndicator = "message";
966
991
  }
967
- let typingMessageName;
992
+ let typingMessage;
993
+ const typingMessageThreadName = account.config.replyToMode && account.config.replyToMode !== "off" ? replyThreadName : void 0;
968
994
  if (typingIndicator === "message") try {
969
- typingMessageName = (await sendGoogleChatMessage({
995
+ const result = await sendGoogleChatMessage({
970
996
  account,
971
997
  space: spaceId,
972
998
  text: `_${resolveBotDisplayName({
@@ -974,8 +1000,12 @@ async function processMessageWithPipeline(params) {
974
1000
  agentId: route.agentId,
975
1001
  config
976
1002
  })} is typing..._`,
977
- thread: replyThreadName
978
- }))?.messageName;
1003
+ thread: typingMessageThreadName
1004
+ });
1005
+ if (result?.messageName) typingMessage = {
1006
+ name: result.messageName,
1007
+ thread: typingMessageThreadName
1008
+ };
979
1009
  } catch (err) {
980
1010
  runtime.error?.(`Failed sending typing message: ${String(err)}`);
981
1011
  }
@@ -1007,7 +1037,7 @@ async function processMessageWithPipeline(params) {
1007
1037
  payload,
1008
1038
  infoKind: info.kind,
1009
1039
  spaceId,
1010
- typingMessageName
1040
+ hasTypingMessage: Boolean(typingMessage)
1011
1041
  }),
1012
1042
  deliver: async (payload) => {
1013
1043
  await deliverGoogleChatReply({
@@ -1018,9 +1048,9 @@ async function processMessageWithPipeline(params) {
1018
1048
  core,
1019
1049
  config,
1020
1050
  statusSink,
1021
- typingMessageName
1051
+ typingMessage
1022
1052
  });
1023
- typingMessageName = void 0;
1053
+ typingMessage = void 0;
1024
1054
  },
1025
1055
  onDelivered: () => {
1026
1056
  statusSink?.({ lastOutboundAt: Date.now() });
@@ -1102,7 +1132,6 @@ function resolveGoogleChatWebhookPath(params) {
1102
1132
  const googleChatChannelRuntime = {
1103
1133
  probeGoogleChat,
1104
1134
  sendGoogleChatMessage,
1105
- uploadGoogleChatAttachment,
1106
1135
  resolveGoogleChatWebhookPath,
1107
1136
  startGoogleChatMonitor
1108
1137
  };
@@ -0,0 +1,3 @@
1
+ import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
2
+ import { GoogleChatConfigSchema } from "openclaw/plugin-sdk/bundled-channel-config-schema";
3
+ export { buildChannelConfigSchema as n, GoogleChatConfigSchema as t };
@@ -1,4 +1,4 @@
1
- import { t as googlechatDirectoryAdapter } from "./channel.adapters-FEj7zUjh.js";
1
+ import { t as googlechatDirectoryAdapter } from "./channel.adapters-CvESEXlT.js";
2
2
  //#region extensions/googlechat/directory-contract-api.ts
3
3
  const googlechatDirectoryContractPlugin = {
4
4
  id: "googlechat",
@@ -1,5 +1,13 @@
1
- import { asObjectRecord } from "openclaw/plugin-sdk/runtime-doctor";
1
+ import { asObjectRecord, defineChannelAliasMigration } from "openclaw/plugin-sdk/runtime-doctor";
2
2
  //#region extensions/googlechat/src/doctor-contract.ts
3
+ const streamingAliasMigration = defineChannelAliasMigration({
4
+ channelId: "googlechat",
5
+ streaming: {
6
+ defaultMode: "partial",
7
+ deliveryOnly: true
8
+ },
9
+ accountStreamingReplacesRoot: true
10
+ });
3
11
  function hasLegacyGoogleChatStreamMode(value) {
4
12
  return asObjectRecord(value)?.streamMode !== void 0;
5
13
  }
@@ -90,9 +98,10 @@ const legacyConfigRules = [
90
98
  ],
91
99
  message: "channels.googlechat.accounts.<id>.groups.<id>.allow is legacy; use channels.googlechat.accounts.<id>.groups.<id>.enabled instead. Run \"openclaw doctor --fix\".",
92
100
  match: (value) => hasLegacyAccountAliases(value, hasLegacyGoogleChatGroupAllowAlias)
93
- }
101
+ },
102
+ ...streamingAliasMigration.legacyConfigRules
94
103
  ];
95
- function normalizeCompatibilityConfig({ cfg }) {
104
+ function normalizeRetiredGoogleChatKeys(cfg) {
96
105
  const rawEntry = asObjectRecord(cfg.channels?.googlechat);
97
106
  if (!rawEntry) return {
98
107
  config: cfg,
@@ -147,5 +156,12 @@ function normalizeCompatibilityConfig({ cfg }) {
147
156
  changes
148
157
  };
149
158
  }
159
+ function normalizeCompatibilityConfig({ cfg }) {
160
+ const retired = normalizeRetiredGoogleChatKeys(cfg);
161
+ return streamingAliasMigration.normalizeChannelConfig({
162
+ cfg: retired.config,
163
+ changes: retired.changes
164
+ });
165
+ }
150
166
  //#endregion
151
167
  export { normalizeCompatibilityConfig as n, legacyConfigRules as t };
@@ -1,2 +1,2 @@
1
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-BcEqUZ4j.js";
1
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-CvhD0eoX.js";
2
2
  export { legacyConfigRules, normalizeCompatibilityConfig };
@@ -1,18 +1,15 @@
1
+ import "./config-api-CsD0IFxF.js";
1
2
  import { extractToolSend as extractToolSend$1 } from "openclaw/plugin-sdk/tool-send";
2
- import { readRemoteMediaBuffer, resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
3
3
  import { fetchWithSsrFGuard as fetchWithSsrFGuard$1 } from "openclaw/plugin-sdk/ssrf-runtime";
4
4
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
5
- import { createActionGate as createActionGate$1, jsonResult as jsonResult$1, readNumberParam, readReactionParams as readReactionParams$1, readStringParam as readStringParam$1 } from "openclaw/plugin-sdk/channel-actions";
6
- import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-primitives";
5
+ import { createActionGate, jsonResult as jsonResult$1, readNumberParam, readReactionParams, readStringParam as readStringParam$1 } from "openclaw/plugin-sdk/channel-actions";
7
6
  import { missingTargetError } from "openclaw/plugin-sdk/channel-feedback";
8
7
  import { createAccountStatusSink as createAccountStatusSink$1, createChannelMessageReplyPipeline, runPassiveAccountLifecycle as runPassiveAccountLifecycle$1 } from "openclaw/plugin-sdk/channel-outbound";
9
8
  import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
10
9
  import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
11
10
  import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
12
- import { GoogleChatConfigSchema } from "openclaw/plugin-sdk/bundled-channel-config-schema";
13
11
  import { GROUP_POLICY_BLOCKED_LABEL, resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
14
12
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
15
- import { loadOutboundMediaFromUrl as loadOutboundMediaFromUrl$1 } from "openclaw/plugin-sdk/outbound-media";
16
13
  import { resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";
17
14
  import { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";
18
15
  import { resolveWebhookPath } from "openclaw/plugin-sdk/webhook-ingress";
@@ -25,4 +22,4 @@ const { setRuntime: setGoogleChatRuntime, getRuntime: getGoogleChatRuntime } = c
25
22
  errorMessage: "Google Chat runtime not initialized"
26
23
  });
27
24
  //#endregion
28
- export { resolveWebhookTargetWithAuthOrReject$1 as A, registerWebhookTargetWithPluginRoute$1 as C, resolveInboundMentionDecision as D, resolveDefaultGroupPolicy as E, setGoogleChatRuntime as F, warnMissingProviderGroupPolicyFallbackOnce as M, withResolvedWebhookRequestPipeline$1 as N, resolveInboundRouteEnvelopeBuilderWithRuntime as O, getGoogleChatRuntime as P, readStringParam$1 as S, resolveChannelMediaMaxBytes as T, missingTargetError as _, buildChannelConfigSchema as a, readReactionParams$1 as b, createActionGate$1 as c, createWebhookInFlightLimiter$1 as d, extractToolSend$1 as f, loadOutboundMediaFromUrl$1 as g, jsonResult$1 as h, PAIRING_APPROVED_MESSAGE as i, runPassiveAccountLifecycle$1 as j, resolveWebhookPath as k, createChannelMessageReplyPipeline as l, isDangerousNameMatchingEnabled as m, GROUP_POLICY_BLOCKED_LABEL as n, chunkTextForOutbound as o, fetchWithSsrFGuard$1 as p, GoogleChatConfigSchema as r, createAccountStatusSink$1 as s, DEFAULT_ACCOUNT_ID as t, createChannelPairingController as u, readJsonWebhookBodyOrReject$1 as v, resolveAllowlistProviderRuntimeGroupPolicy as w, readRemoteMediaBuffer as x, readNumberParam as y };
25
+ export { setGoogleChatRuntime as A, resolveInboundRouteEnvelopeBuilderWithRuntime as C, warnMissingProviderGroupPolicyFallbackOnce as D, runPassiveAccountLifecycle$1 as E, withResolvedWebhookRequestPipeline$1 as O, resolveInboundMentionDecision as S, resolveWebhookTargetWithAuthOrReject$1 as T, readReactionParams as _, createAccountStatusSink$1 as a, resolveAllowlistProviderRuntimeGroupPolicy as b, createChannelPairingController as c, fetchWithSsrFGuard$1 as d, isDangerousNameMatchingEnabled as f, readNumberParam as g, readJsonWebhookBodyOrReject$1 as h, chunkTextForOutbound as i, getGoogleChatRuntime as k, createWebhookInFlightLimiter$1 as l, missingTargetError as m, GROUP_POLICY_BLOCKED_LABEL as n, createActionGate as o, jsonResult$1 as p, PAIRING_APPROVED_MESSAGE as r, createChannelMessageReplyPipeline as s, DEFAULT_ACCOUNT_ID as t, extractToolSend$1 as u, readStringParam$1 as v, resolveWebhookPath as w, resolveDefaultGroupPolicy as x, registerWebhookTargetWithPluginRoute$1 as y };
@@ -1,2 +1,3 @@
1
- import { A as resolveWebhookTargetWithAuthOrReject, C as registerWebhookTargetWithPluginRoute, D as resolveInboundMentionDecision, E as resolveDefaultGroupPolicy, F as setGoogleChatRuntime, M as warnMissingProviderGroupPolicyFallbackOnce, N as withResolvedWebhookRequestPipeline, O as resolveInboundRouteEnvelopeBuilderWithRuntime, S as readStringParam, T as resolveChannelMediaMaxBytes, _ as missingTargetError, a as buildChannelConfigSchema, b as readReactionParams, c as createActionGate, d as createWebhookInFlightLimiter, f as extractToolSend, g as loadOutboundMediaFromUrl, h as jsonResult, i as PAIRING_APPROVED_MESSAGE, j as runPassiveAccountLifecycle, k as resolveWebhookPath, l as createChannelMessageReplyPipeline, m as isDangerousNameMatchingEnabled, n as GROUP_POLICY_BLOCKED_LABEL, o as chunkTextForOutbound, p as fetchWithSsrFGuard, r as GoogleChatConfigSchema, s as createAccountStatusSink, t as DEFAULT_ACCOUNT_ID, u as createChannelPairingController, v as readJsonWebhookBodyOrReject, w as resolveAllowlistProviderRuntimeGroupPolicy, x as readRemoteMediaBuffer, y as readNumberParam } from "./runtime-api-BbVoWRxq.js";
2
- export { DEFAULT_ACCOUNT_ID, GROUP_POLICY_BLOCKED_LABEL, GoogleChatConfigSchema, PAIRING_APPROVED_MESSAGE, buildChannelConfigSchema, chunkTextForOutbound, createAccountStatusSink, createActionGate, createChannelMessageReplyPipeline, createChannelPairingController, createWebhookInFlightLimiter, extractToolSend, fetchWithSsrFGuard, isDangerousNameMatchingEnabled, jsonResult, loadOutboundMediaFromUrl, missingTargetError, readJsonWebhookBodyOrReject, readNumberParam, readReactionParams, readRemoteMediaBuffer, readStringParam, registerWebhookTargetWithPluginRoute, resolveAllowlistProviderRuntimeGroupPolicy, resolveChannelMediaMaxBytes, resolveDefaultGroupPolicy, resolveInboundMentionDecision, resolveInboundRouteEnvelopeBuilderWithRuntime, resolveWebhookPath, resolveWebhookTargetWithAuthOrReject, runPassiveAccountLifecycle, setGoogleChatRuntime, warnMissingProviderGroupPolicyFallbackOnce, withResolvedWebhookRequestPipeline };
1
+ import { n as buildChannelConfigSchema, t as GoogleChatConfigSchema } from "./config-api-CsD0IFxF.js";
2
+ import { A as setGoogleChatRuntime, C as resolveInboundRouteEnvelopeBuilderWithRuntime, D as warnMissingProviderGroupPolicyFallbackOnce, E as runPassiveAccountLifecycle, O as withResolvedWebhookRequestPipeline, S as resolveInboundMentionDecision, T as resolveWebhookTargetWithAuthOrReject, _ as readReactionParams, a as createAccountStatusSink, b as resolveAllowlistProviderRuntimeGroupPolicy, c as createChannelPairingController, d as fetchWithSsrFGuard, f as isDangerousNameMatchingEnabled, g as readNumberParam, h as readJsonWebhookBodyOrReject, i as chunkTextForOutbound, l as createWebhookInFlightLimiter, m as missingTargetError, n as GROUP_POLICY_BLOCKED_LABEL, o as createActionGate, p as jsonResult, r as PAIRING_APPROVED_MESSAGE, s as createChannelMessageReplyPipeline, t as DEFAULT_ACCOUNT_ID, u as extractToolSend, v as readStringParam, w as resolveWebhookPath, x as resolveDefaultGroupPolicy, y as registerWebhookTargetWithPluginRoute } from "./runtime-api-1v-DgldF.js";
3
+ export { DEFAULT_ACCOUNT_ID, GROUP_POLICY_BLOCKED_LABEL, GoogleChatConfigSchema, PAIRING_APPROVED_MESSAGE, buildChannelConfigSchema, chunkTextForOutbound, createAccountStatusSink, createActionGate, createChannelMessageReplyPipeline, createChannelPairingController, createWebhookInFlightLimiter, extractToolSend, fetchWithSsrFGuard, isDangerousNameMatchingEnabled, jsonResult, missingTargetError, readJsonWebhookBodyOrReject, readNumberParam, readReactionParams, readStringParam, registerWebhookTargetWithPluginRoute, resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, resolveInboundMentionDecision, resolveInboundRouteEnvelopeBuilderWithRuntime, resolveWebhookPath, resolveWebhookTargetWithAuthOrReject, runPassiveAccountLifecycle, setGoogleChatRuntime, warnMissingProviderGroupPolicyFallbackOnce, withResolvedWebhookRequestPipeline };
@@ -1,31 +1,24 @@
1
- import { getChannelSurface, hasOwnProperty, pushAssignment, pushInactiveSurfaceWarning, pushWarning, resolveChannelAccountSurface } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
1
+ import { createChannelSecretTargetRegistryEntries, getChannelSurface, hasOwnProperty, pushAssignment, pushInactiveSurfaceWarning, pushWarning, resolveChannelAccountSurface } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
2
2
  import { coerceSecretRef } from "openclaw/plugin-sdk/secret-ref-runtime";
3
3
  //#region extensions/googlechat/src/secret-contract.ts
4
- const secretTargetRegistryEntries = [{
5
- id: "channels.googlechat.accounts.*.serviceAccount",
6
- targetType: "channels.googlechat.serviceAccount",
7
- targetTypeAliases: ["channels.googlechat.accounts.*.serviceAccount"],
8
- configFile: "openclaw.json",
9
- pathPattern: "channels.googlechat.accounts.*.serviceAccount",
10
- refPathPattern: "channels.googlechat.accounts.*.serviceAccountRef",
11
- secretShape: "sibling_ref",
12
- expectedResolvedValue: "string-or-object",
13
- includeInPlan: true,
14
- includeInConfigure: true,
15
- includeInAudit: true,
16
- accountIdPathSegmentIndex: 3
17
- }, {
18
- id: "channels.googlechat.serviceAccount",
19
- targetType: "channels.googlechat.serviceAccount",
20
- configFile: "openclaw.json",
21
- pathPattern: "channels.googlechat.serviceAccount",
22
- refPathPattern: "channels.googlechat.serviceAccountRef",
23
- secretShape: "sibling_ref",
24
- expectedResolvedValue: "string-or-object",
25
- includeInPlan: true,
26
- includeInConfigure: true,
27
- includeInAudit: true
28
- }];
4
+ const secretTargetRegistryEntries = createChannelSecretTargetRegistryEntries({
5
+ channelKey: "googlechat",
6
+ account: [{
7
+ path: "serviceAccount",
8
+ refPath: "serviceAccountRef",
9
+ targetType: "channels.googlechat.serviceAccount",
10
+ targetTypeAliases: ["channels.googlechat.accounts.*.serviceAccount"],
11
+ secretShape: "sibling_ref",
12
+ expectedResolvedValue: "string-or-object",
13
+ accountIdPathSegmentIndex: 3
14
+ }],
15
+ channel: [{
16
+ path: "serviceAccount",
17
+ refPath: "serviceAccountRef",
18
+ secretShape: "sibling_ref",
19
+ expectedResolvedValue: "string-or-object"
20
+ }]
21
+ });
29
22
  function resolveSecretInputRef(params) {
30
23
  const explicitRef = coerceSecretRef(params.refValue, params.defaults);
31
24
  const inlineRef = explicitRef ? null : coerceSecretRef(params.value, params.defaults);
@@ -1,2 +1,2 @@
1
- import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-lCMHqumt.js";
1
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-D__4IIu_.js";
2
2
  export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
@@ -1,4 +1,4 @@
1
- import { n as createGoogleChatPluginBase } from "./channel-base-DJICAvKH.js";
1
+ import { n as createGoogleChatPluginBase } from "./channel-base-B16U1bY7.js";
2
2
  //#region extensions/googlechat/src/channel.setup.ts
3
3
  const googlechatSetupPlugin = createGoogleChatPluginBase();
4
4
  //#endregion
@@ -1,19 +1,18 @@
1
1
  {
2
2
  "name": "@openclaw/googlechat",
3
- "version": "2026.7.1-beta.6",
3
+ "version": "2026.7.2-beta.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/googlechat",
9
- "version": "2026.7.1-beta.6",
9
+ "version": "2026.7.2-beta.1",
10
10
  "dependencies": {
11
- "gaxios": "7.1.5",
12
11
  "google-auth-library": "10.9.0",
13
12
  "zod": "4.4.3"
14
13
  },
15
14
  "peerDependencies": {
16
- "openclaw": ">=2026.7.1-beta.6"
15
+ "openclaw": ">=2026.7.2-beta.1"
17
16
  },
18
17
  "peerDependenciesMeta": {
19
18
  "openclaw": {