@openclaw/googlechat 2026.7.1 → 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.
- package/dist/actions-I93fRoRd.js +76 -0
- package/dist/api.js +2 -2
- package/dist/approval-auth-CMMwmCPY.js +30 -0
- package/dist/{approval-handler.runtime-BnkufknT.js → approval-handler.runtime-DcSqrj8k.js} +5 -4
- package/dist/{channel-_o671C-U.js → channel-9ZeBzfmP.js} +17 -20
- package/dist/{channel-base-DJICAvKH.js → channel-base-B16U1bY7.js} +0 -1
- package/dist/channel-config-api.js +1 -2
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.adapters-FEj7zUjh.js → channel.adapters-CvESEXlT.js} +77 -142
- package/dist/{channel.runtime-CYmt7Ybo.js → channel.runtime-B0u_Dy7b.js} +145 -116
- package/dist/config-api-CsD0IFxF.js +3 -0
- package/dist/directory-contract-api.js +1 -1
- package/dist/{doctor-contract-BcEqUZ4j.js → doctor-contract-CvhD0eoX.js} +19 -3
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{runtime-api-BbVoWRxq.js → runtime-api-1v-DgldF.js} +3 -6
- package/dist/runtime-api.js +3 -2
- package/dist/{secret-contract-lCMHqumt.js → secret-contract-D__4IIu_.js} +19 -26
- package/dist/secret-contract-api.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/npm-shrinkwrap.json +3 -4
- package/openclaw.plugin.json +72 -48
- package/package.json +4 -6
- package/dist/actions-BacnMHv0.js +0 -159
- package/dist/approval-auth-C_BVZZFA.js +0 -27
|
@@ -1,15 +1,73 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as googleChatApprovalAuth } from "./approval-auth-
|
|
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 {
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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.
|
|
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
|
-
|
|
365
|
-
|
|
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
|
|
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
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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:
|
|
478
|
+
thread: replyThreadName
|
|
412
479
|
});
|
|
413
480
|
};
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
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
|
-
|
|
897
|
-
|
|
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
|
|
992
|
+
let typingMessage;
|
|
993
|
+
const typingMessageThreadName = account.config.replyToMode && account.config.replyToMode !== "off" ? replyThreadName : void 0;
|
|
968
994
|
if (typingIndicator === "message") try {
|
|
969
|
-
|
|
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:
|
|
978
|
-
})
|
|
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
|
-
|
|
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
|
-
|
|
1051
|
+
typingMessage
|
|
1022
1052
|
});
|
|
1023
|
-
|
|
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
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as googlechatDirectoryAdapter } from "./channel.adapters-
|
|
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
|
|
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-
|
|
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
|
|
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 {
|
|
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 };
|
package/dist/runtime-api.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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-
|
|
1
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-D__4IIu_.js";
|
|
2
2
|
export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
|
package/dist/setup-plugin-api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as createGoogleChatPluginBase } from "./channel-base-
|
|
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
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/googlechat",
|
|
3
|
-
"version": "2026.7.1",
|
|
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",
|
|
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"
|
|
15
|
+
"openclaw": ">=2026.7.2-beta.1"
|
|
17
16
|
},
|
|
18
17
|
"peerDependenciesMeta": {
|
|
19
18
|
"openclaw": {
|