@openclaw/msteams 2026.10.5-beta.4 → 2026.10.10-beta.2
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/.setup/{adapter.runtime-JoPydWqP.cjs → adapter.runtime-B-6Q3nMI.cjs} +6 -4
- package/dist/.setup/{approval-handler.runtime-bUN9icMr.cjs → approval-handler.runtime-DccVf5AY.cjs} +16 -6
- package/dist/.setup/{bot-framework-service-url-CPp4d-Q6.cjs → bot-framework-service-url-B3FWn2SV.cjs} +13 -0
- package/dist/.setup/{channel-Cifn9fsv.cjs → channel-B7Gy3QUW.cjs} +261 -175
- package/dist/.setup/{channel.runtime-DWRAolil.cjs → channel.runtime-DzKeQAqd.cjs} +84 -49
- package/dist/.setup/channel.setup-B5ClEcNI.cjs +990 -0
- package/dist/.setup/config-schema-CkKdphSp.cjs +293 -0
- package/dist/.setup/{conversation-store-state-DprmOfl7.cjs → conversation-store-state-C3__T9mK.cjs} +79 -91
- package/dist/.setup/delegated-state-Bv5cWuec.cjs +110 -0
- package/dist/.setup/{monitor-C9x_CJhY.cjs → monitor-CzRI-Hsc.cjs} +283 -240
- package/dist/.setup/{oauth-CWJ85AMw.cjs → oauth-D9u8sPCD.cjs} +1 -1
- package/dist/.setup/{reaction-types-Ig9sQJuR.cjs → reaction-types-DSQWVA4Z.cjs} +15 -9
- package/dist/.setup/{resolve-allowlist-DdDBVCzl.cjs → resolve-allowlist-tYgAHx0t.cjs} +252 -38
- package/dist/.setup/{secret-contract-api-ChQdBeU1.cjs → secret-contract-api-YY3v6MP8.cjs} +1 -1
- package/dist/.setup/secret-contract-api-wAyY5UHv.cjs +85 -0
- package/dist/.setup/{send-rJpcVtRp.cjs → send-Bgm8RYUa.cjs} +45 -24
- package/dist/.setup/{setup-plugin-api-DfoVOqMJ.cjs → setup-plugin-api-BACfeF7_.cjs} +1 -1
- package/dist/.setup/{thread-session-B74FC1Id.cjs → thread-session-C7KTMwLU.cjs} +11 -4
- package/dist/.setup/token-config-bEpua_Q7.cjs +93 -0
- package/dist/api.cjs +2 -2
- package/dist/channel-config-api.cjs +1 -1
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/directory-contract-api.cjs +30 -22
- package/dist/doctor-contract-api.cjs +11 -10
- package/dist/qa-runner-api.cjs +1 -1
- package/dist/runtime-api.cjs +2 -2
- package/dist/secret-contract-api.cjs +1 -1
- package/dist/setup-entry.cjs +2 -2
- package/dist/setup-plugin-api.cjs +1 -1
- package/openclaw.plugin.json +715 -0
- package/package.json +57 -6
- package/dist/.setup/channel.setup-BjbHugkL.cjs +0 -632
- package/dist/.setup/config-schema-Dk0mRIam.cjs +0 -160
- package/dist/.setup/secret-contract-api-ipiUsANg.cjs +0 -28
- package/dist/.setup/token-config-CqIh8z7Q.cjs +0 -138
|
@@ -1,632 +0,0 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-DdDBVCzl.cjs");
|
|
2
|
-
const require_token_config = require("./token-config-CqIh8z7Q.cjs");
|
|
3
|
-
const require_config_schema = require("./config-schema-Dk0mRIam.cjs");
|
|
4
|
-
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
5
|
-
let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
|
|
6
|
-
let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
|
|
7
|
-
let openclaw_plugin_sdk_account_helpers = require("openclaw/plugin-sdk/account-helpers");
|
|
8
|
-
let openclaw_plugin_sdk_number_runtime = require("openclaw/plugin-sdk/number-runtime");
|
|
9
|
-
let openclaw_plugin_sdk_secret_input = require("openclaw/plugin-sdk/secret-input");
|
|
10
|
-
let openclaw_plugin_sdk_channel_config_helpers = require("openclaw/plugin-sdk/channel-config-helpers");
|
|
11
|
-
let openclaw_plugin_sdk_secret_file_runtime = require("openclaw/plugin-sdk/secret-file-runtime");
|
|
12
|
-
let openclaw_plugin_sdk_channel_setup = require("openclaw/plugin-sdk/channel-setup");
|
|
13
|
-
let openclaw_plugin_sdk_setup = require("openclaw/plugin-sdk/setup");
|
|
14
|
-
let openclaw_plugin_sdk_setup_tools = require("openclaw/plugin-sdk/setup-tools");
|
|
15
|
-
let openclaw_plugin_sdk_retry_runtime = require("openclaw/plugin-sdk/retry-runtime");
|
|
16
|
-
//#region extensions/msteams/src/channel-config.ts
|
|
17
|
-
const msteamsMeta = {
|
|
18
|
-
id: "msteams",
|
|
19
|
-
label: "Microsoft Teams",
|
|
20
|
-
selectionLabel: "Microsoft Teams (Bot Framework)",
|
|
21
|
-
docsPath: "/channels/msteams",
|
|
22
|
-
docsLabel: "msteams",
|
|
23
|
-
blurb: "Teams SDK; enterprise support.",
|
|
24
|
-
aliases: ["teams"],
|
|
25
|
-
order: 60
|
|
26
|
-
};
|
|
27
|
-
function resolveMSTeamsAccount(cfg) {
|
|
28
|
-
const config = cfg.channels?.msteams;
|
|
29
|
-
const credentials = require_token_config.resolveMSTeamsCredentials(config);
|
|
30
|
-
const certificatePath = credentials?.type === "federated" && !credentials.useManagedIdentity ? credentials.certificatePath : void 0;
|
|
31
|
-
const certificate = certificatePath ? (0, openclaw_plugin_sdk_secret_file_runtime.tryReadSecretFileSync)(certificatePath, "Microsoft Teams certificate", void 0, { configPath: config?.certificatePath?.trim() ? "channels.msteams.certificatePath" : "env.MSTEAMS_CERTIFICATE_PATH" }) : void 0;
|
|
32
|
-
const unavailable = certificate?.status === "configured_unavailable";
|
|
33
|
-
return {
|
|
34
|
-
accountId: openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID,
|
|
35
|
-
enabled: config?.enabled !== false,
|
|
36
|
-
configured: Boolean(credentials),
|
|
37
|
-
tokenStatus: !credentials ? "missing" : unavailable ? "configured_unavailable" : "available",
|
|
38
|
-
...unavailable ? { credentialDiagnostics: [certificate.diagnostic] } : {}
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const msteamsConfigAdapter = (0, openclaw_plugin_sdk_channel_config_helpers.createTopLevelChannelConfigAdapter)({
|
|
42
|
-
sectionKey: "msteams",
|
|
43
|
-
resolveAccount: resolveMSTeamsAccount,
|
|
44
|
-
resolveAccessorAccount: ({ cfg }) => ({
|
|
45
|
-
allowFrom: cfg.channels?.msteams?.allowFrom,
|
|
46
|
-
defaultTo: cfg.channels?.msteams?.defaultTo
|
|
47
|
-
}),
|
|
48
|
-
resolveAllowFrom: (account) => account.allowFrom,
|
|
49
|
-
formatAllowFrom: (allowFrom) => (0, openclaw_plugin_sdk_allow_from.formatAllowFromLowercase)({ allowFrom }),
|
|
50
|
-
resolveDefaultTo: (account) => account.defaultTo
|
|
51
|
-
});
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region extensions/msteams/src/setup-core.ts
|
|
54
|
-
const t$1 = (0, openclaw_plugin_sdk_setup.createSetupTranslator)();
|
|
55
|
-
const channel$1 = "msteams";
|
|
56
|
-
const msteamsSetupAdapter = {
|
|
57
|
-
resolveAccountId: () => openclaw_plugin_sdk_setup.DEFAULT_ACCOUNT_ID,
|
|
58
|
-
applyAccountConfig: ({ cfg }) => (0, openclaw_plugin_sdk_setup.setSetupChannelEnabled)(cfg, channel$1, true)
|
|
59
|
-
};
|
|
60
|
-
const msteamsSetupContract = (0, openclaw_plugin_sdk_channel_setup.defineChannelSetupContract)({
|
|
61
|
-
fields: {},
|
|
62
|
-
legacyAdapter: msteamsSetupAdapter
|
|
63
|
-
});
|
|
64
|
-
async function promptMSTeamsCredentials(prompter) {
|
|
65
|
-
const promptRequired = async (message) => (await prompter.text({
|
|
66
|
-
message,
|
|
67
|
-
validate: (value) => value?.trim() ? void 0 : t$1("common.required")
|
|
68
|
-
})).trim();
|
|
69
|
-
return {
|
|
70
|
-
appId: await promptRequired(t$1("wizard.msteams.appIdPrompt")),
|
|
71
|
-
appPassword: await promptRequired(t$1("wizard.msteams.appPasswordPrompt")),
|
|
72
|
-
tenantId: await promptRequired(t$1("wizard.msteams.tenantIdPrompt"))
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
async function noteMSTeamsCredentialHelp(prompter) {
|
|
76
|
-
await prompter.note([
|
|
77
|
-
t$1("wizard.msteams.helpAzureBot"),
|
|
78
|
-
t$1("wizard.msteams.helpClientSecret"),
|
|
79
|
-
t$1("wizard.msteams.helpWebhook"),
|
|
80
|
-
t$1("wizard.msteams.helpEnvTip"),
|
|
81
|
-
t$1("wizard.channels.docs", { link: (0, openclaw_plugin_sdk_setup_tools.formatDocsLink)("/channels/msteams", "msteams") })
|
|
82
|
-
].join("\n"), t$1("wizard.msteams.credentialsTitle"));
|
|
83
|
-
}
|
|
84
|
-
function createMSTeamsSetupWizardBase() {
|
|
85
|
-
return {
|
|
86
|
-
channel: channel$1,
|
|
87
|
-
resolveAccountIdForConfigure: () => openclaw_plugin_sdk_setup.DEFAULT_ACCOUNT_ID,
|
|
88
|
-
resolveShouldPromptAccountIds: () => false,
|
|
89
|
-
status: (0, openclaw_plugin_sdk_setup.createStandardChannelSetupStatus)({
|
|
90
|
-
channelLabel: "MS Teams",
|
|
91
|
-
configuredLabel: t$1("wizard.channels.statusConfigured"),
|
|
92
|
-
unconfiguredLabel: t$1("wizard.channels.statusNeedsAppCredentials"),
|
|
93
|
-
configuredHint: t$1("wizard.channels.statusConfigured"),
|
|
94
|
-
unconfiguredHint: t$1("wizard.channels.statusNeedsAppCreds"),
|
|
95
|
-
configuredScore: 2,
|
|
96
|
-
unconfiguredScore: 0,
|
|
97
|
-
includeStatusLine: true,
|
|
98
|
-
resolveConfigured: ({ cfg }) => Boolean(require_token_config.resolveMSTeamsCredentials(cfg.channels?.msteams)) || require_token_config.hasConfiguredMSTeamsCredentials(cfg.channels?.msteams)
|
|
99
|
-
}),
|
|
100
|
-
credentials: [],
|
|
101
|
-
finalize: async ({ cfg, prompter }) => {
|
|
102
|
-
const resolved = require_token_config.resolveMSTeamsCredentials(cfg.channels?.msteams);
|
|
103
|
-
const hasConfigCreds = require_token_config.hasConfiguredMSTeamsCredentials(cfg.channels?.msteams);
|
|
104
|
-
const canUseEnv = Boolean(!hasConfigCreds && (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_APP_ID) && (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_APP_PASSWORD) && (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_TENANT_ID));
|
|
105
|
-
let next = cfg;
|
|
106
|
-
if (!resolved && !hasConfigCreds) await noteMSTeamsCredentialHelp(prompter);
|
|
107
|
-
if ((canUseEnv || hasConfigCreds) && await prompter.confirm({
|
|
108
|
-
message: t$1(canUseEnv ? "wizard.msteams.envPrompt" : "wizard.msteams.credentialsKeep"),
|
|
109
|
-
initialValue: true
|
|
110
|
-
})) next = msteamsSetupAdapter.applyAccountConfig({
|
|
111
|
-
cfg: next,
|
|
112
|
-
accountId: openclaw_plugin_sdk_setup.DEFAULT_ACCOUNT_ID,
|
|
113
|
-
input: {}
|
|
114
|
-
});
|
|
115
|
-
else {
|
|
116
|
-
const { appId, appPassword, tenantId } = await promptMSTeamsCredentials(prompter);
|
|
117
|
-
if (appId && appPassword && tenantId) next = (0, openclaw_plugin_sdk_setup.patchTopLevelChannelConfigSection)({
|
|
118
|
-
cfg: next,
|
|
119
|
-
channel: channel$1,
|
|
120
|
-
enabled: true,
|
|
121
|
-
patch: {
|
|
122
|
-
appId,
|
|
123
|
-
appPassword,
|
|
124
|
-
tenantId
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
return {
|
|
129
|
-
cfg: next,
|
|
130
|
-
accountId: openclaw_plugin_sdk_setup.DEFAULT_ACCOUNT_ID
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
//#endregion
|
|
136
|
-
//#region extensions/msteams/src/errors.ts
|
|
137
|
-
const MAX_SAFE_RETRY_AFTER_SECONDS = Number.MAX_SAFE_INTEGER / 1e3;
|
|
138
|
-
function formatUnknownError(err) {
|
|
139
|
-
if (err instanceof Error) return err.message;
|
|
140
|
-
if (typeof err === "symbol") return err.description ?? err.toString();
|
|
141
|
-
if (typeof err === "function") return err.name ? `[function ${err.name}]` : "[function]";
|
|
142
|
-
if (err === null || typeof err !== "object") return String(err);
|
|
143
|
-
try {
|
|
144
|
-
return JSON.stringify(err) ?? "unknown error";
|
|
145
|
-
} catch {
|
|
146
|
-
return "unknown error";
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
function extractStatusCode(err) {
|
|
150
|
-
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(err)) return null;
|
|
151
|
-
const parseStatusCode = (value) => {
|
|
152
|
-
if (typeof value === "number") return Number.isInteger(value) && value >= 100 && value <= 599 ? value : null;
|
|
153
|
-
if (typeof value === "string") {
|
|
154
|
-
const trimmed = value.trim();
|
|
155
|
-
if (!/^\d{3}$/.test(trimmed)) return null;
|
|
156
|
-
const parsed = Number(trimmed);
|
|
157
|
-
return parsed >= 100 && parsed <= 599 ? parsed : null;
|
|
158
|
-
}
|
|
159
|
-
return null;
|
|
160
|
-
};
|
|
161
|
-
const directStatus = parseStatusCode(err.statusCode ?? err.status);
|
|
162
|
-
if (directStatus !== null) return directStatus;
|
|
163
|
-
const response = err.response;
|
|
164
|
-
if ((0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(response)) {
|
|
165
|
-
const responseStatus = parseStatusCode(response.status);
|
|
166
|
-
if (responseStatus !== null) return responseStatus;
|
|
167
|
-
}
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
function extractErrorCode(err) {
|
|
171
|
-
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(err)) return null;
|
|
172
|
-
const direct = err.code;
|
|
173
|
-
if (typeof direct === "string" && direct.trim()) return direct;
|
|
174
|
-
const response = err.response;
|
|
175
|
-
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(response)) return null;
|
|
176
|
-
const body = response.body;
|
|
177
|
-
if ((0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(body)) {
|
|
178
|
-
const error = body.error;
|
|
179
|
-
if ((0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(error) && typeof error.code === "string" && error.code.trim()) return error.code;
|
|
180
|
-
}
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
function extractRetryAfterMs(err) {
|
|
184
|
-
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(err)) return null;
|
|
185
|
-
const direct = err.retryAfterMs ?? err.retry_after_ms;
|
|
186
|
-
const directMs = (0, openclaw_plugin_sdk_number_runtime.asFiniteNumberInRange)(direct, {
|
|
187
|
-
min: 0,
|
|
188
|
-
max: Number.MAX_SAFE_INTEGER
|
|
189
|
-
});
|
|
190
|
-
if (directMs !== void 0) return directMs;
|
|
191
|
-
const retryAfter = err.retryAfter ?? err.retry_after;
|
|
192
|
-
const retryAfterSeconds = (0, openclaw_plugin_sdk_number_runtime.asFiniteNumberInRange)(retryAfter, {
|
|
193
|
-
min: 0,
|
|
194
|
-
max: MAX_SAFE_RETRY_AFTER_SECONDS
|
|
195
|
-
});
|
|
196
|
-
if (retryAfterSeconds !== void 0) return retryAfterSeconds * 1e3;
|
|
197
|
-
if (typeof retryAfter === "string") {
|
|
198
|
-
const parsed = parseNonNegativeRetryAfterSeconds(retryAfter);
|
|
199
|
-
if (parsed !== void 0) return parsed * 1e3;
|
|
200
|
-
}
|
|
201
|
-
const response = err.response;
|
|
202
|
-
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(response)) return null;
|
|
203
|
-
const headers = response.headers;
|
|
204
|
-
if (!headers) return null;
|
|
205
|
-
if ((0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(headers)) {
|
|
206
|
-
const raw = headers["retry-after"] ?? headers["Retry-After"];
|
|
207
|
-
if (typeof raw === "string") {
|
|
208
|
-
const parsed = (0, openclaw_plugin_sdk_retry_runtime.parseRetryAfterHeaderSeconds)(raw);
|
|
209
|
-
if (parsed !== void 0) return parsed * 1e3;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
if (typeof headers === "object" && headers !== null && "get" in headers && typeof headers.get === "function") {
|
|
213
|
-
const raw = headers.get("retry-after");
|
|
214
|
-
if (raw) {
|
|
215
|
-
const parsed = (0, openclaw_plugin_sdk_retry_runtime.parseRetryAfterHeaderSeconds)(raw);
|
|
216
|
-
if (parsed !== void 0) return parsed * 1e3;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
return null;
|
|
220
|
-
}
|
|
221
|
-
function parseNonNegativeRetryAfterSeconds(raw) {
|
|
222
|
-
const trimmed = raw.trim();
|
|
223
|
-
if (!/^\d+(?:\.\d+)?$/.test(trimmed)) return;
|
|
224
|
-
return (0, openclaw_plugin_sdk_number_runtime.asFiniteNumberInRange)((0, openclaw_plugin_sdk_number_runtime.parseStrictFiniteNumber)(trimmed), {
|
|
225
|
-
min: 0,
|
|
226
|
-
max: MAX_SAFE_RETRY_AFTER_SECONDS
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Owns retry safety and delivery ambiguity for Teams send failures.
|
|
231
|
-
* Only Teams rate-limit rejection proves this unkeyed POST safe to replay.
|
|
232
|
-
*/
|
|
233
|
-
function classifyMSTeamsSendError(err) {
|
|
234
|
-
const statusCode = extractStatusCode(err);
|
|
235
|
-
const retryAfterMs = extractRetryAfterMs(err);
|
|
236
|
-
const errorCode = extractErrorCode(err) ?? void 0;
|
|
237
|
-
if (statusCode === 401) return {
|
|
238
|
-
kind: "auth",
|
|
239
|
-
statusCode,
|
|
240
|
-
errorCode
|
|
241
|
-
};
|
|
242
|
-
if (statusCode === 403) {
|
|
243
|
-
if (errorCode === "ContentStreamNotAllowed") return {
|
|
244
|
-
kind: "permanent",
|
|
245
|
-
statusCode,
|
|
246
|
-
errorCode
|
|
247
|
-
};
|
|
248
|
-
return {
|
|
249
|
-
kind: "auth",
|
|
250
|
-
statusCode,
|
|
251
|
-
errorCode
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
if (statusCode === 429) return {
|
|
255
|
-
kind: "replay-safe",
|
|
256
|
-
statusCode,
|
|
257
|
-
retryAfterMs: retryAfterMs ?? void 0,
|
|
258
|
-
errorCode
|
|
259
|
-
};
|
|
260
|
-
if (statusCode === 408 || statusCode != null && statusCode >= 500) return {
|
|
261
|
-
kind: "ambiguous",
|
|
262
|
-
source: "http",
|
|
263
|
-
statusCode,
|
|
264
|
-
errorCode
|
|
265
|
-
};
|
|
266
|
-
if (statusCode != null && statusCode >= 400) return {
|
|
267
|
-
kind: "permanent",
|
|
268
|
-
statusCode,
|
|
269
|
-
errorCode
|
|
270
|
-
};
|
|
271
|
-
if (statusCode == null && (0, openclaw_plugin_sdk_retry_runtime.isTransientNetworkError)(err)) return {
|
|
272
|
-
kind: "ambiguous",
|
|
273
|
-
source: "transport",
|
|
274
|
-
errorCode
|
|
275
|
-
};
|
|
276
|
-
return {
|
|
277
|
-
kind: "unknown",
|
|
278
|
-
statusCode: statusCode ?? void 0,
|
|
279
|
-
errorCode
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Detect whether an error is caused by a revoked Proxy.
|
|
284
|
-
*
|
|
285
|
-
* The Bot Framework SDK wraps TurnContext in a Proxy that is revoked once the
|
|
286
|
-
* turn handler returns. Any later access (e.g. from a debounced callback)
|
|
287
|
-
* throws a TypeError whose message contains the distinctive "proxy that has
|
|
288
|
-
* been revoked" string.
|
|
289
|
-
*/
|
|
290
|
-
function isRevokedProxyError(err) {
|
|
291
|
-
if (!(err instanceof TypeError)) return false;
|
|
292
|
-
return /proxy that has been revoked/i.test(err.message);
|
|
293
|
-
}
|
|
294
|
-
function formatMSTeamsSendErrorHint(classification) {
|
|
295
|
-
if (classification.kind === "auth") return "check msteams appId/appPassword/tenantId (or env vars MSTEAMS_APP_ID/MSTEAMS_APP_PASSWORD/MSTEAMS_TENANT_ID)";
|
|
296
|
-
if (classification.errorCode === "ContentStreamNotAllowed") return "Teams expired the content stream; stop streaming earlier and fall back to normal message delivery";
|
|
297
|
-
if (classification.kind === "replay-safe") return "Teams throttled the bot; backing off may help";
|
|
298
|
-
if (classification.kind === "ambiguous") {
|
|
299
|
-
if (classification.source === "transport") return "transport-level failure sending to Teams Bot Connector (smba.trafficmanager.net); the outcome is unknown, so check egress and conversation history before taking further action";
|
|
300
|
-
return "Teams/Bot Framework delivery outcome is unknown; inspect the conversation history before taking further action";
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
function formatMSTeamsDeliveryFailureGuidance(classification) {
|
|
304
|
-
if (classification.kind === "replay-safe") return "The request was rate-limited before delivery; retrying later may succeed.";
|
|
305
|
-
if (classification.kind === "ambiguous") return "Delivery may already have succeeded; do not send the same content again without checking the conversation.";
|
|
306
|
-
}
|
|
307
|
-
//#endregion
|
|
308
|
-
//#region extensions/msteams/src/setup-surface.ts
|
|
309
|
-
const t = (0, openclaw_plugin_sdk_setup.createSetupTranslator)();
|
|
310
|
-
const channel = "msteams";
|
|
311
|
-
const setMSTeamsAllowFrom = (0, openclaw_plugin_sdk_setup.createTopLevelChannelAllowFromSetter)({ channel });
|
|
312
|
-
const setMSTeamsGroupPolicy = (0, openclaw_plugin_sdk_setup.createTopLevelChannelGroupPolicySetter)({
|
|
313
|
-
channel,
|
|
314
|
-
enabled: true
|
|
315
|
-
});
|
|
316
|
-
function openDelegatedOAuthUrl(url) {
|
|
317
|
-
return Promise.reject(/* @__PURE__ */ new Error(`Automatic browser launch is not available. Open this URL manually: ${url}`));
|
|
318
|
-
}
|
|
319
|
-
function looksLikeGuid(value) {
|
|
320
|
-
return /^[0-9a-fA-F-]{16,}$/.test(value);
|
|
321
|
-
}
|
|
322
|
-
async function promptMSTeamsAllowFrom(params) {
|
|
323
|
-
const existing = params.cfg.channels?.msteams?.allowFrom ?? [];
|
|
324
|
-
await params.prompter.note([
|
|
325
|
-
t("wizard.msteams.allowlistIntro"),
|
|
326
|
-
t("wizard.msteams.allowlistResolve"),
|
|
327
|
-
t("wizard.msteams.examples"),
|
|
328
|
-
"- alex@example.com",
|
|
329
|
-
"- Alex Johnson",
|
|
330
|
-
"- 00000000-0000-0000-0000-000000000000"
|
|
331
|
-
].join("\n"), t("wizard.msteams.allowlistTitle"));
|
|
332
|
-
while (true) {
|
|
333
|
-
const entry = await params.prompter.text({
|
|
334
|
-
message: t("wizard.msteams.allowFromPrompt"),
|
|
335
|
-
placeholder: "alex@example.com, Alex Johnson",
|
|
336
|
-
initialValue: existing[0] ? existing[0] : void 0,
|
|
337
|
-
validate: (value) => value.trim() ? void 0 : t("common.required")
|
|
338
|
-
});
|
|
339
|
-
const parts = (0, openclaw_plugin_sdk_setup.splitSetupEntries)(entry);
|
|
340
|
-
if (parts.length === 0) {
|
|
341
|
-
await params.prompter.note(t("wizard.msteams.enterAtLeastOneUser"), t("wizard.msteams.allowlistTitle"));
|
|
342
|
-
continue;
|
|
343
|
-
}
|
|
344
|
-
const resolved = await require_resolve_allowlist.resolveMSTeamsUserAllowlist({
|
|
345
|
-
cfg: params.cfg,
|
|
346
|
-
entries: parts
|
|
347
|
-
}).catch(() => null);
|
|
348
|
-
if (!resolved) {
|
|
349
|
-
const ids = parts.filter((part) => looksLikeGuid(part));
|
|
350
|
-
if (ids.length !== parts.length) {
|
|
351
|
-
await params.prompter.note(t("wizard.msteams.graphLookupUnavailable"), t("wizard.msteams.allowlistTitle"));
|
|
352
|
-
continue;
|
|
353
|
-
}
|
|
354
|
-
const unique = (0, openclaw_plugin_sdk_setup.mergeAllowFromEntries)(existing, ids);
|
|
355
|
-
return setMSTeamsAllowFrom(params.cfg, unique);
|
|
356
|
-
}
|
|
357
|
-
const unresolved = resolved.filter((item) => !item.resolved || !item.id);
|
|
358
|
-
if (unresolved.length > 0) {
|
|
359
|
-
await params.prompter.note(t("wizard.msteams.couldNotResolve", { entries: unresolved.map((item) => item.input).join(", ") }), t("wizard.msteams.allowlistTitle"));
|
|
360
|
-
continue;
|
|
361
|
-
}
|
|
362
|
-
const ids = resolved.map((item) => item.id);
|
|
363
|
-
const unique = (0, openclaw_plugin_sdk_setup.mergeAllowFromEntries)(existing, ids);
|
|
364
|
-
return setMSTeamsAllowFrom(params.cfg, unique);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
function setMSTeamsTeamsAllowlist(cfg, entries) {
|
|
368
|
-
const teams = { ...cfg.channels?.msteams?.teams ?? {} };
|
|
369
|
-
for (const entry of entries) {
|
|
370
|
-
const teamKey = entry.teamKey;
|
|
371
|
-
if (!teamKey) continue;
|
|
372
|
-
const existing = teams[teamKey] ?? {};
|
|
373
|
-
if (entry.channelKey) {
|
|
374
|
-
const channels = { ...existing.channels };
|
|
375
|
-
channels[entry.channelKey] = channels[entry.channelKey] ?? {};
|
|
376
|
-
teams[teamKey] = {
|
|
377
|
-
...existing,
|
|
378
|
-
channels
|
|
379
|
-
};
|
|
380
|
-
} else teams[teamKey] = existing;
|
|
381
|
-
}
|
|
382
|
-
return (0, openclaw_plugin_sdk_setup.patchTopLevelChannelConfigSection)({
|
|
383
|
-
cfg,
|
|
384
|
-
channel,
|
|
385
|
-
enabled: true,
|
|
386
|
-
patch: { teams }
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
function listMSTeamsGroupEntries(cfg) {
|
|
390
|
-
return Object.entries(cfg.channels?.msteams?.teams ?? {}).flatMap(([teamKey, value]) => {
|
|
391
|
-
const channels = value?.channels ?? {};
|
|
392
|
-
const channelKeys = Object.keys(channels);
|
|
393
|
-
if (channelKeys.length === 0) return [teamKey];
|
|
394
|
-
return channelKeys.map((channelKey) => `${teamKey}/${channelKey}`);
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
async function resolveMSTeamsGroupAllowlist(params) {
|
|
398
|
-
let resolvedEntries = params.entries.map((entry) => require_resolve_allowlist.parseMSTeamsTeamEntry(entry)).filter(Boolean);
|
|
399
|
-
if (params.entries.length === 0 || !require_token_config.resolveMSTeamsCredentials(params.cfg.channels?.msteams)) return resolvedEntries;
|
|
400
|
-
try {
|
|
401
|
-
const lookups = await require_resolve_allowlist.resolveMSTeamsChannelAllowlist({
|
|
402
|
-
cfg: params.cfg,
|
|
403
|
-
entries: params.entries
|
|
404
|
-
});
|
|
405
|
-
const resolvedChannels = lookups.filter((entry) => entry.resolved && entry.teamId && entry.channelId);
|
|
406
|
-
const resolvedTeams = lookups.filter((entry) => entry.resolved && entry.teamId && !entry.channelId);
|
|
407
|
-
const unresolved = lookups.filter((entry) => !entry.resolved).map((entry) => entry.input);
|
|
408
|
-
resolvedEntries = [
|
|
409
|
-
...resolvedChannels.map((entry) => ({
|
|
410
|
-
teamKey: entry.teamId,
|
|
411
|
-
channelKey: entry.channelId
|
|
412
|
-
})),
|
|
413
|
-
...resolvedTeams.map((entry) => ({ teamKey: entry.teamId })),
|
|
414
|
-
...unresolved.map((entry) => require_resolve_allowlist.parseMSTeamsTeamEntry(entry)).filter(Boolean)
|
|
415
|
-
];
|
|
416
|
-
const summary = [];
|
|
417
|
-
if (resolvedChannels.length > 0) summary.push(t("wizard.msteams.resolvedChannels", { entries: resolvedChannels.map((entry) => entry.channelId).filter(Boolean).join(", ") }));
|
|
418
|
-
if (resolvedTeams.length > 0) summary.push(t("wizard.msteams.resolvedTeams", { entries: resolvedTeams.map((entry) => entry.teamId).filter(Boolean).join(", ") }));
|
|
419
|
-
if (unresolved.length > 0) summary.push(t("wizard.msteams.unresolvedKept", { entries: unresolved.join(", ") }));
|
|
420
|
-
if (summary.length > 0) await params.prompter.note(summary.join("\n"), t("wizard.msteams.channelsLabel"));
|
|
421
|
-
return resolvedEntries;
|
|
422
|
-
} catch (err) {
|
|
423
|
-
await params.prompter.note(t("wizard.msteams.channelLookupFailed", { error: formatUnknownError(err) }), t("wizard.msteams.channelsLabel"));
|
|
424
|
-
return resolvedEntries;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
const msteamsGroupAccess = {
|
|
428
|
-
label: t("wizard.msteams.channelsLabel"),
|
|
429
|
-
placeholder: "Team Name/Channel Name, teamId/conversationId",
|
|
430
|
-
currentPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy ?? "allowlist",
|
|
431
|
-
currentEntries: ({ cfg }) => listMSTeamsGroupEntries(cfg),
|
|
432
|
-
updatePrompt: ({ cfg }) => Boolean(cfg.channels?.msteams?.teams),
|
|
433
|
-
setPolicy: ({ cfg, policy }) => setMSTeamsGroupPolicy(cfg, policy),
|
|
434
|
-
resolveAllowlist: ({ cfg, entries, prompter }) => resolveMSTeamsGroupAllowlist({
|
|
435
|
-
cfg,
|
|
436
|
-
entries,
|
|
437
|
-
prompter
|
|
438
|
-
}),
|
|
439
|
-
applyAllowlist: ({ cfg, resolved }) => setMSTeamsTeamsAllowlist(cfg, resolved)
|
|
440
|
-
};
|
|
441
|
-
const msteamsDmPolicy = (0, openclaw_plugin_sdk_setup.createTopLevelChannelDmPolicy)({
|
|
442
|
-
label: "MS Teams",
|
|
443
|
-
channel,
|
|
444
|
-
policyKey: "channels.msteams.dmPolicy",
|
|
445
|
-
allowFromKey: "channels.msteams.allowFrom",
|
|
446
|
-
getCurrent: (cfg) => cfg.channels?.msteams?.dmPolicy ?? "pairing",
|
|
447
|
-
promptAllowFrom: promptMSTeamsAllowFrom
|
|
448
|
-
});
|
|
449
|
-
const msteamsSetupWizardBase = createMSTeamsSetupWizardBase();
|
|
450
|
-
const msteamsSetupWizard = {
|
|
451
|
-
...msteamsSetupWizardBase,
|
|
452
|
-
finalize: async (params) => {
|
|
453
|
-
const baseFinalize = msteamsSetupWizardBase.finalize;
|
|
454
|
-
const baseResult = baseFinalize ? await baseFinalize(params) : void 0;
|
|
455
|
-
let next = baseResult?.cfg ?? params.cfg;
|
|
456
|
-
const finalCreds = require_token_config.resolveMSTeamsCredentials(next.channels?.msteams);
|
|
457
|
-
if (finalCreds?.type === "secret") {
|
|
458
|
-
if (await params.prompter.confirm({
|
|
459
|
-
message: t("wizard.msteams.delegatedAuthPrompt"),
|
|
460
|
-
initialValue: false
|
|
461
|
-
})) {
|
|
462
|
-
next = (0, openclaw_plugin_sdk_setup.patchTopLevelChannelConfigSection)({
|
|
463
|
-
cfg: next,
|
|
464
|
-
channel,
|
|
465
|
-
patch: { delegatedAuth: { enabled: true } }
|
|
466
|
-
});
|
|
467
|
-
const noteDelegatedAuthFailure = async (err) => {
|
|
468
|
-
await params.prompter.note(`Delegated auth setup failed: ${formatUnknownError(err)}\n` + t("wizard.msteams.delegatedAuthRetry"), t("wizard.msteams.delegatedAuthTitle"));
|
|
469
|
-
};
|
|
470
|
-
let oauthModule;
|
|
471
|
-
try {
|
|
472
|
-
oauthModule = await Promise.resolve().then(() => require("./oauth-CWJ85AMw.cjs"));
|
|
473
|
-
} catch (err) {
|
|
474
|
-
await noteDelegatedAuthFailure(err);
|
|
475
|
-
return {
|
|
476
|
-
...baseResult,
|
|
477
|
-
cfg: next
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
await params.options?.beforePersistentEffect?.();
|
|
481
|
-
const progress = params.prompter.progress(t("wizard.msteams.delegatedOAuthProgress"));
|
|
482
|
-
let tokens;
|
|
483
|
-
try {
|
|
484
|
-
tokens = await oauthModule.loginMSTeamsDelegated({
|
|
485
|
-
log: (msg) => {
|
|
486
|
-
params.prompter.note(msg);
|
|
487
|
-
},
|
|
488
|
-
note: (msg, title) => params.prompter.note(msg, title),
|
|
489
|
-
prompt: (msg) => params.prompter.text({ message: msg }),
|
|
490
|
-
progress
|
|
491
|
-
}, {
|
|
492
|
-
tenantId: finalCreds.tenantId,
|
|
493
|
-
clientId: finalCreds.appId,
|
|
494
|
-
clientSecret: finalCreds.appPassword
|
|
495
|
-
});
|
|
496
|
-
} catch (err) {
|
|
497
|
-
progress.stop();
|
|
498
|
-
await noteDelegatedAuthFailure(err);
|
|
499
|
-
return {
|
|
500
|
-
...baseResult,
|
|
501
|
-
cfg: next
|
|
502
|
-
};
|
|
503
|
-
}
|
|
504
|
-
try {
|
|
505
|
-
await params.options?.beforePersistentEffect?.();
|
|
506
|
-
} catch (err) {
|
|
507
|
-
progress.stop();
|
|
508
|
-
throw err;
|
|
509
|
-
}
|
|
510
|
-
await require_token_config.saveMSTeamsDelegatedTokens(tokens);
|
|
511
|
-
progress.stop(t("wizard.msteams.delegatedAuthConfigured"));
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
return {
|
|
515
|
-
...baseResult,
|
|
516
|
-
cfg: next
|
|
517
|
-
};
|
|
518
|
-
},
|
|
519
|
-
dmPolicy: msteamsDmPolicy,
|
|
520
|
-
groupAccess: msteamsGroupAccess,
|
|
521
|
-
disable: (cfg) => (0, openclaw_plugin_sdk_setup.setSetupChannelEnabled)(cfg, channel, false)
|
|
522
|
-
};
|
|
523
|
-
//#endregion
|
|
524
|
-
//#region extensions/msteams/src/channel.setup.ts
|
|
525
|
-
const msteamsSetupPlugin = {
|
|
526
|
-
id: "msteams",
|
|
527
|
-
meta: {
|
|
528
|
-
...msteamsMeta,
|
|
529
|
-
aliases: [...msteamsMeta.aliases]
|
|
530
|
-
},
|
|
531
|
-
capabilities: {
|
|
532
|
-
chatTypes: [
|
|
533
|
-
"direct",
|
|
534
|
-
"channel",
|
|
535
|
-
"group",
|
|
536
|
-
"thread"
|
|
537
|
-
],
|
|
538
|
-
polls: true,
|
|
539
|
-
threads: true,
|
|
540
|
-
media: true,
|
|
541
|
-
reactions: true
|
|
542
|
-
},
|
|
543
|
-
reload: {
|
|
544
|
-
configPrefixes: ["channels.msteams"],
|
|
545
|
-
noopPrefixes: ["messages.inbound"]
|
|
546
|
-
},
|
|
547
|
-
configSchema: require_config_schema.MSTeamsChannelConfigSchema,
|
|
548
|
-
config: {
|
|
549
|
-
...msteamsConfigAdapter,
|
|
550
|
-
isConfigured: (account) => account.configured,
|
|
551
|
-
describeAccount: (account) => (0, openclaw_plugin_sdk_account_helpers.describeAccountSnapshot)({
|
|
552
|
-
account,
|
|
553
|
-
configured: account.configured,
|
|
554
|
-
extra: { tokenStatus: account.tokenStatus }
|
|
555
|
-
})
|
|
556
|
-
},
|
|
557
|
-
setupWizard: msteamsSetupWizard,
|
|
558
|
-
setupContract: msteamsSetupContract
|
|
559
|
-
};
|
|
560
|
-
//#endregion
|
|
561
|
-
Object.defineProperty(exports, "classifyMSTeamsSendError", {
|
|
562
|
-
enumerable: true,
|
|
563
|
-
get: function() {
|
|
564
|
-
return classifyMSTeamsSendError;
|
|
565
|
-
}
|
|
566
|
-
});
|
|
567
|
-
Object.defineProperty(exports, "createMSTeamsSetupWizardBase", {
|
|
568
|
-
enumerable: true,
|
|
569
|
-
get: function() {
|
|
570
|
-
return createMSTeamsSetupWizardBase;
|
|
571
|
-
}
|
|
572
|
-
});
|
|
573
|
-
Object.defineProperty(exports, "formatMSTeamsDeliveryFailureGuidance", {
|
|
574
|
-
enumerable: true,
|
|
575
|
-
get: function() {
|
|
576
|
-
return formatMSTeamsDeliveryFailureGuidance;
|
|
577
|
-
}
|
|
578
|
-
});
|
|
579
|
-
Object.defineProperty(exports, "formatMSTeamsSendErrorHint", {
|
|
580
|
-
enumerable: true,
|
|
581
|
-
get: function() {
|
|
582
|
-
return formatMSTeamsSendErrorHint;
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
Object.defineProperty(exports, "formatUnknownError", {
|
|
586
|
-
enumerable: true,
|
|
587
|
-
get: function() {
|
|
588
|
-
return formatUnknownError;
|
|
589
|
-
}
|
|
590
|
-
});
|
|
591
|
-
Object.defineProperty(exports, "isRevokedProxyError", {
|
|
592
|
-
enumerable: true,
|
|
593
|
-
get: function() {
|
|
594
|
-
return isRevokedProxyError;
|
|
595
|
-
}
|
|
596
|
-
});
|
|
597
|
-
Object.defineProperty(exports, "msteamsConfigAdapter", {
|
|
598
|
-
enumerable: true,
|
|
599
|
-
get: function() {
|
|
600
|
-
return msteamsConfigAdapter;
|
|
601
|
-
}
|
|
602
|
-
});
|
|
603
|
-
Object.defineProperty(exports, "msteamsSetupAdapter", {
|
|
604
|
-
enumerable: true,
|
|
605
|
-
get: function() {
|
|
606
|
-
return msteamsSetupAdapter;
|
|
607
|
-
}
|
|
608
|
-
});
|
|
609
|
-
Object.defineProperty(exports, "msteamsSetupPlugin", {
|
|
610
|
-
enumerable: true,
|
|
611
|
-
get: function() {
|
|
612
|
-
return msteamsSetupPlugin;
|
|
613
|
-
}
|
|
614
|
-
});
|
|
615
|
-
Object.defineProperty(exports, "msteamsSetupWizard", {
|
|
616
|
-
enumerable: true,
|
|
617
|
-
get: function() {
|
|
618
|
-
return msteamsSetupWizard;
|
|
619
|
-
}
|
|
620
|
-
});
|
|
621
|
-
Object.defineProperty(exports, "openDelegatedOAuthUrl", {
|
|
622
|
-
enumerable: true,
|
|
623
|
-
get: function() {
|
|
624
|
-
return openDelegatedOAuthUrl;
|
|
625
|
-
}
|
|
626
|
-
});
|
|
627
|
-
Object.defineProperty(exports, "resolveMSTeamsAccount", {
|
|
628
|
-
enumerable: true,
|
|
629
|
-
get: function() {
|
|
630
|
-
return resolveMSTeamsAccount;
|
|
631
|
-
}
|
|
632
|
-
});
|