@openclaw/googlechat 2026.6.1 → 2026.6.5-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,7 +1,6 @@
1
- import { c as resolveGoogleChatAccount, o as listEnabledGoogleChatAccounts } from "./channel-base-DpPD0ef1.js";
1
+ import { l as resolveGoogleChatAccount, o as listEnabledGoogleChatAccounts } from "./channel-base-Qh87GFW_.js";
2
+ import { b as uploadGoogleChatAttachment, d as resolveGoogleChatOutboundSpace, f as createGoogleChatReaction, g as listGoogleChatReactions, m as deleteGoogleChatReaction, v as sendGoogleChatMessage } from "./channel.adapters-BQoq1F4R.js";
2
3
  import { P as getGoogleChatRuntime } from "./runtime-api-BbVoWRxq.js";
3
- import { c as sendGoogleChatMessage, o as listGoogleChatReactions, r as deleteGoogleChatReaction, t as createGoogleChatReaction, u as uploadGoogleChatAttachment } from "./api-DPvlxpWa.js";
4
- import { n as resolveGoogleChatOutboundSpace } from "./channel-DxHy0I-n.js";
5
4
  import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
6
5
  import { createActionGate, jsonResult, readPositiveIntegerParam, readReactionParams, readStringParam } from "openclaw/plugin-sdk/channel-actions";
7
6
  import { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";
package/dist/api.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as googlechatSetupAdapter, i as googlechatSetupWizard } from "./channel-base-DpPD0ef1.js";
2
- import { t as googlechatPlugin } from "./channel-DxHy0I-n.js";
1
+ import { a as googlechatSetupAdapter, i as googlechatSetupWizard } from "./channel-base-Qh87GFW_.js";
2
+ import { t as googlechatPlugin } from "./channel-BY9hwCh2.js";
3
3
  export { googlechatPlugin, googlechatSetupAdapter, googlechatSetupWizard };
@@ -0,0 +1,27 @@
1
+ import { l as resolveGoogleChatAccount } from "./channel-base-Qh87GFW_.js";
2
+ import { l as isGoogleChatUserTarget, u as normalizeGoogleChatTarget } from "./channel.adapters-BQoq1F4R.js";
3
+ import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
5
+ //#region extensions/googlechat/src/approval-auth.ts
6
+ function normalizeGoogleChatApproverId(value) {
7
+ const normalized = normalizeGoogleChatTarget(String(value));
8
+ if (!normalized || !isGoogleChatUserTarget(normalized)) return;
9
+ const suffix = normalizeLowercaseStringOrEmpty(normalized.slice(6));
10
+ if (!suffix || suffix.includes("@")) return;
11
+ return `users/${suffix}`;
12
+ }
13
+ function getGoogleChatApprovalApprovers(params) {
14
+ const account = resolveGoogleChatAccount(params).config;
15
+ return resolveApprovalApprovers({
16
+ allowFrom: account.dm?.allowFrom,
17
+ defaultTo: account.defaultTo,
18
+ normalizeApprover: normalizeGoogleChatApproverId
19
+ });
20
+ }
21
+ const googleChatApprovalAuth = createResolvedApproverActionAuthAdapter({
22
+ channelLabel: "Google Chat",
23
+ resolveApprovers: getGoogleChatApprovalApprovers,
24
+ normalizeSenderId: (value) => normalizeGoogleChatApproverId(value)
25
+ });
26
+ //#endregion
27
+ export { googleChatApprovalAuth as n, normalizeGoogleChatApproverId as r, getGoogleChatApprovalApprovers as t };
@@ -0,0 +1,272 @@
1
+ import { l as resolveGoogleChatAccount } from "./channel-base-Qh87GFW_.js";
2
+ import { A as registerGoogleChatManualApprovalFollowupSuppression, C as buildGoogleChatApprovalActionParameters, E as createGoogleChatApprovalToken, M as unregisterGoogleChatApprovalCardBindings, N as unregisterGoogleChatManualApprovalFollowupSuppression, S as GOOGLECHAT_APPROVAL_ACTION, d as resolveGoogleChatOutboundSpace, k as registerGoogleChatApprovalCardBinding, v as sendGoogleChatMessage, y as updateGoogleChatMessage } from "./channel.adapters-BQoq1F4R.js";
3
+ import { n as isGoogleChatNativeApprovalClientEnabled, r as shouldHandleGoogleChatNativeApprovalRequest } from "./channel-BY9hwCh2.js";
4
+ import { buildChannelApprovalNativeTargetKey } from "openclaw/plugin-sdk/approval-native-runtime";
5
+ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
+ import { createChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
7
+ import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
8
+ //#region extensions/googlechat/src/approval-handler.runtime.ts
9
+ const log = createSubsystemLogger("googlechat/approvals");
10
+ const GOOGLECHAT_APPROVAL_CARD_ID = "openclaw-approval";
11
+ const MAX_TEXT_PARAGRAPH_CHARS = 1800;
12
+ function resolveHandlerAccount(params) {
13
+ const account = params.context?.account ?? resolveGoogleChatAccount({
14
+ cfg: params.cfg,
15
+ accountId: params.accountId
16
+ });
17
+ if (!account.enabled || account.credentialSource === "none") return null;
18
+ return account;
19
+ }
20
+ function escapeGoogleChatText(text) {
21
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
22
+ }
23
+ function truncateText(text, maxChars = MAX_TEXT_PARAGRAPH_CHARS) {
24
+ return text.length <= maxChars ? text : `${text.slice(0, maxChars - 3)}...`;
25
+ }
26
+ function buildMetadataText(metadata) {
27
+ return metadata.map((item) => `<b>${escapeGoogleChatText(item.label)}:</b> ${escapeGoogleChatText(item.value)}`).join("<br>");
28
+ }
29
+ function formatDecision(decision) {
30
+ return decision === "allow-once" ? "Allowed once" : decision === "allow-always" ? "Allowed always" : "Denied";
31
+ }
32
+ function buildMainTextWidget(text) {
33
+ return { textParagraph: { text: escapeGoogleChatText(truncateText(text)) } };
34
+ }
35
+ function buildHtmlTextWidget(text) {
36
+ return { textParagraph: { text: truncateText(text) } };
37
+ }
38
+ function buildExecPendingSections(view) {
39
+ if (view.approvalKind !== "exec") return [];
40
+ return [{
41
+ header: "Command",
42
+ widgets: [buildMainTextWidget(view.commandText)]
43
+ }, ...view.commandPreview && view.commandPreview !== view.commandText ? [{
44
+ header: "Preview",
45
+ widgets: [buildMainTextWidget(view.commandPreview)]
46
+ }] : []];
47
+ }
48
+ function buildPluginPendingSections(view) {
49
+ if (view.approvalKind !== "plugin") return [];
50
+ return [{
51
+ header: "Request",
52
+ widgets: [buildHtmlTextWidget(`<b>${escapeGoogleChatText(view.title)}</b>${view.description ? `<br>${escapeGoogleChatText(view.description)}` : ""}`)]
53
+ }];
54
+ }
55
+ function buildMetadataSection(view) {
56
+ const metadata = [{
57
+ label: "Approval ID",
58
+ value: view.approvalId
59
+ }, ...view.metadata];
60
+ return metadata.length > 0 ? [{
61
+ header: "Details",
62
+ widgets: [buildHtmlTextWidget(buildMetadataText(metadata))]
63
+ }] : [];
64
+ }
65
+ function buildActionSection(params) {
66
+ const { actionFunction, view } = params;
67
+ const actionTokens = view.actions.map((action) => ({
68
+ token: createGoogleChatApprovalToken(),
69
+ decision: action.decision
70
+ }));
71
+ return {
72
+ actionTokens,
73
+ section: { widgets: [{ buttonList: { buttons: view.actions.map((action, index) => {
74
+ const actionToken = actionTokens[index];
75
+ if (!actionToken) throw new Error("Google Chat approval action token missing.");
76
+ return {
77
+ text: action.label,
78
+ onClick: { action: {
79
+ function: actionFunction,
80
+ parameters: buildGoogleChatApprovalActionParameters(actionToken.token),
81
+ loadIndicator: "SPINNER"
82
+ } }
83
+ };
84
+ }) } }] }
85
+ };
86
+ }
87
+ function buildPendingPayload(params) {
88
+ const { actionFunction, nowMs, view } = params;
89
+ const { section: actionSection, actionTokens } = buildActionSection({
90
+ actionFunction,
91
+ view
92
+ });
93
+ const card = {
94
+ cardId: GOOGLECHAT_APPROVAL_CARD_ID,
95
+ card: {
96
+ header: {
97
+ title: view.approvalKind === "plugin" ? "Plugin Approval Required" : "Exec Approval Required",
98
+ subtitle: `Expires in ${Math.max(0, Math.ceil((view.expiresAtMs - nowMs) / 1e3))}s`
99
+ },
100
+ sections: [
101
+ ...buildExecPendingSections(view),
102
+ ...buildPluginPendingSections(view),
103
+ ...buildMetadataSection(view),
104
+ actionSection
105
+ ]
106
+ }
107
+ };
108
+ return {
109
+ approvalId: view.approvalId,
110
+ approvalKind: view.approvalKind,
111
+ expiresAtMs: view.expiresAtMs,
112
+ cardsV2: [card],
113
+ actionTokens,
114
+ allowedDecisions: view.actions.map((action) => action.decision)
115
+ };
116
+ }
117
+ function resolveApprovalActionFunction(params) {
118
+ const account = resolveHandlerAccount(params);
119
+ const audience = normalizeOptionalString(account?.config.audience);
120
+ const appPrincipal = normalizeOptionalString(account?.config.appPrincipal);
121
+ return account?.config.audienceType === "app-url" && audience && appPrincipal ? audience : GOOGLECHAT_APPROVAL_ACTION;
122
+ }
123
+ function buildResolvedPayload(view) {
124
+ const resolvedBy = normalizeOptionalString(view.resolvedBy);
125
+ return { cardsV2: [{
126
+ cardId: GOOGLECHAT_APPROVAL_CARD_ID,
127
+ card: {
128
+ header: {
129
+ title: `${view.approvalKind === "plugin" ? "Plugin" : "Exec"} Approval: ${formatDecision(view.decision)}`,
130
+ subtitle: resolvedBy ? `Resolved by ${resolvedBy}` : "Resolved"
131
+ },
132
+ sections: buildMetadataSection(view)
133
+ }
134
+ }] };
135
+ }
136
+ function buildExpiredPayload(view) {
137
+ return { cardsV2: [{
138
+ cardId: GOOGLECHAT_APPROVAL_CARD_ID,
139
+ card: {
140
+ header: {
141
+ title: `${view.approvalKind === "plugin" ? "Plugin" : "Exec"} Approval Expired`,
142
+ subtitle: "This approval request expired before it was resolved."
143
+ },
144
+ sections: buildMetadataSection(view)
145
+ }
146
+ }] };
147
+ }
148
+ const googleChatApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({
149
+ eventKinds: ["exec", "plugin"],
150
+ availability: {
151
+ isConfigured: ({ cfg, accountId }) => isGoogleChatNativeApprovalClientEnabled({
152
+ cfg,
153
+ accountId
154
+ }),
155
+ shouldHandle: ({ cfg, accountId, request }) => shouldHandleGoogleChatNativeApprovalRequest({
156
+ cfg,
157
+ accountId,
158
+ request
159
+ })
160
+ },
161
+ presentation: {
162
+ buildPendingPayload: ({ cfg, accountId, context, nowMs, view }) => buildPendingPayload({
163
+ actionFunction: resolveApprovalActionFunction({
164
+ cfg,
165
+ accountId,
166
+ context
167
+ }),
168
+ nowMs,
169
+ view
170
+ }),
171
+ buildResolvedResult: ({ view }) => ({
172
+ kind: "update",
173
+ payload: buildResolvedPayload(view)
174
+ }),
175
+ buildExpiredResult: ({ view }) => ({
176
+ kind: "update",
177
+ payload: buildExpiredPayload(view)
178
+ })
179
+ },
180
+ transport: {
181
+ prepareTarget: ({ plannedTarget }) => ({
182
+ dedupeKey: buildChannelApprovalNativeTargetKey(plannedTarget.target),
183
+ target: {
184
+ to: plannedTarget.target.to,
185
+ threadName: plannedTarget.target.threadId != null ? String(plannedTarget.target.threadId) : void 0
186
+ }
187
+ }),
188
+ deliverPending: async ({ cfg, accountId, context, preparedTarget, pendingPayload }) => {
189
+ const account = resolveHandlerAccount({
190
+ cfg,
191
+ accountId,
192
+ context
193
+ });
194
+ if (!account) return null;
195
+ const spaceName = await resolveGoogleChatOutboundSpace({
196
+ account,
197
+ target: preparedTarget.to
198
+ });
199
+ registerGoogleChatManualApprovalFollowupSuppression({
200
+ approvalId: pendingPayload.approvalId,
201
+ approvalKind: pendingPayload.approvalKind,
202
+ allowedDecisions: pendingPayload.allowedDecisions,
203
+ expiresAtMs: pendingPayload.expiresAtMs
204
+ });
205
+ let sent;
206
+ try {
207
+ sent = await sendGoogleChatMessage({
208
+ account,
209
+ space: spaceName,
210
+ cardsV2: pendingPayload.cardsV2,
211
+ thread: preparedTarget.threadName
212
+ });
213
+ } catch (error) {
214
+ unregisterGoogleChatManualApprovalFollowupSuppression(pendingPayload.approvalId);
215
+ throw error;
216
+ }
217
+ if (!sent?.messageName) {
218
+ unregisterGoogleChatManualApprovalFollowupSuppression(pendingPayload.approvalId);
219
+ return null;
220
+ }
221
+ return {
222
+ accountId: account.accountId,
223
+ spaceName,
224
+ messageName: sent.messageName,
225
+ ...preparedTarget.threadName ? { threadName: preparedTarget.threadName } : {},
226
+ actionTokens: pendingPayload.actionTokens
227
+ };
228
+ },
229
+ updateEntry: async ({ cfg, accountId, context, entry, payload }) => {
230
+ const account = resolveHandlerAccount({
231
+ cfg,
232
+ accountId,
233
+ context
234
+ });
235
+ if (!account) return;
236
+ await updateGoogleChatMessage({
237
+ account,
238
+ messageName: entry.messageName,
239
+ cardsV2: payload.cardsV2
240
+ });
241
+ }
242
+ },
243
+ interactions: {
244
+ bindPending: ({ entry, request, approvalKind, view, pendingPayload }) => {
245
+ const tokens = [];
246
+ for (const actionToken of entry.actionTokens) if (registerGoogleChatApprovalCardBinding({
247
+ token: actionToken.token,
248
+ accountId: entry.accountId,
249
+ approvalId: request.id,
250
+ approvalKind,
251
+ decision: actionToken.decision,
252
+ allowedDecisions: pendingPayload.allowedDecisions,
253
+ spaceName: entry.spaceName,
254
+ messageName: entry.messageName,
255
+ threadName: entry.threadName ?? null,
256
+ expiresAtMs: view.expiresAtMs
257
+ })) tokens.push(actionToken.token);
258
+ return tokens.length > 0 ? tokens : null;
259
+ },
260
+ unbindPending: ({ binding }) => {
261
+ unregisterGoogleChatApprovalCardBindings(binding);
262
+ },
263
+ cancelDelivered: ({ entry }) => {
264
+ unregisterGoogleChatApprovalCardBindings(entry.actionTokens.map((actionToken) => actionToken.token));
265
+ }
266
+ },
267
+ observe: { onDeliveryError: ({ error, request }) => {
268
+ log.error(`googlechat approvals: failed to send request ${request.id}: ${String(error)}`);
269
+ } }
270
+ });
271
+ //#endregion
272
+ export { googleChatApprovalNativeRuntime };