@openclaw/msteams 2026.10.5-beta.3 → 2026.10.10-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/.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,9 +1,9 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-BloeesfJ.cjs");
|
|
2
|
+
const require_resolve_allowlist = require("./resolve-allowlist-tYgAHx0t.cjs");
|
|
2
3
|
require("../runtime-api.cjs");
|
|
3
|
-
const require_resolve_allowlist = require("./resolve-allowlist-DdDBVCzl.cjs");
|
|
4
4
|
const require_directory_contract_api = require("../directory-contract-api.cjs");
|
|
5
|
-
const require_thread_session = require("./thread-session-
|
|
6
|
-
const require_channel_setup = require("./channel.setup-
|
|
5
|
+
const require_thread_session = require("./thread-session-C7KTMwLU.cjs");
|
|
6
|
+
const require_channel_setup = require("./channel.setup-B5ClEcNI.cjs");
|
|
7
7
|
let openclaw_plugin_sdk_approval_handler_adapter_runtime = require("openclaw/plugin-sdk/approval-handler-adapter-runtime");
|
|
8
8
|
let openclaw_plugin_sdk_channel_actions = require("openclaw/plugin-sdk/channel-actions");
|
|
9
9
|
let openclaw_plugin_sdk_channel_core = require("openclaw/plugin-sdk/channel-core");
|
|
@@ -17,12 +17,12 @@ let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime
|
|
|
17
17
|
let openclaw_plugin_sdk_status_helpers = require("openclaw/plugin-sdk/status-helpers");
|
|
18
18
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
19
19
|
let openclaw_plugin_sdk_tool_results = require("openclaw/plugin-sdk/tool-results");
|
|
20
|
-
let typebox = require("typebox");
|
|
21
20
|
let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
|
|
22
21
|
let openclaw_plugin_sdk_text_chunking = require("openclaw/plugin-sdk/text-chunking");
|
|
23
22
|
let openclaw_plugin_sdk_reply_reference = require("openclaw/plugin-sdk/reply-reference");
|
|
24
23
|
let openclaw_plugin_sdk_approval_delivery_runtime = require("openclaw/plugin-sdk/approval-delivery-runtime");
|
|
25
24
|
let openclaw_plugin_sdk_approval_native_runtime = require("openclaw/plugin-sdk/approval-native-runtime");
|
|
25
|
+
let typebox = require("typebox");
|
|
26
26
|
let openclaw_plugin_sdk_channel_targets = require("openclaw/plugin-sdk/channel-targets");
|
|
27
27
|
let openclaw_plugin_sdk_dangerous_name_runtime = require("openclaw/plugin-sdk/dangerous-name-runtime");
|
|
28
28
|
let openclaw_plugin_sdk_runtime_group_policy = require("openclaw/plugin-sdk/runtime-group-policy");
|
|
@@ -122,7 +122,7 @@ function resolveMSTeamsRouteConfig(params) {
|
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
function resolveMSTeamsGroupToolPolicy(params) {
|
|
125
|
-
const cfg = params.cfg.
|
|
125
|
+
const cfg = require_resolve_allowlist.resolveMSTeamsAccountConfig(params.cfg, params.accountId);
|
|
126
126
|
if (!cfg) return;
|
|
127
127
|
const teams = cfg.teams ?? {};
|
|
128
128
|
const team = selectMSTeamsPolicyEntry(teams, params.groupSpace);
|
|
@@ -229,8 +229,7 @@ function resolveMSTeamsAutoThreadId(params) {
|
|
|
229
229
|
//#endregion
|
|
230
230
|
//#region extensions/msteams/src/approval-native.ts
|
|
231
231
|
function isMSTeamsApprovalTransportEnabled(params) {
|
|
232
|
-
|
|
233
|
-
const account = require_channel_setup.resolveMSTeamsAccount(params.cfg);
|
|
232
|
+
const account = require_resolve_allowlist.resolveMSTeamsAccount(params);
|
|
234
233
|
return account.enabled && account.configured && account.tokenStatus === "available";
|
|
235
234
|
}
|
|
236
235
|
const msTeamsMessagingTargetResolvers = (0, openclaw_plugin_sdk_approval_native_runtime.createNativeApprovalMessagingTargetResolvers)({
|
|
@@ -254,12 +253,12 @@ const msTeamsApprovalTargetResolvers = {
|
|
|
254
253
|
} : null;
|
|
255
254
|
}
|
|
256
255
|
};
|
|
257
|
-
const msTeamsApprovalRouteGates = (0, openclaw_plugin_sdk_approval_native_runtime.
|
|
256
|
+
const msTeamsApprovalRouteGates = (0, openclaw_plugin_sdk_approval_native_runtime.createNativeApprovalChannelRouteGatesAsync)({
|
|
258
257
|
channel: "msteams",
|
|
259
258
|
defaultForwardingMode: "session",
|
|
260
259
|
isTransportEnabled: isMSTeamsApprovalTransportEnabled,
|
|
261
260
|
listAccountIds: require_channel_setup.msteamsConfigAdapter.listAccountIds,
|
|
262
|
-
resolveDefaultAccountId:
|
|
261
|
+
resolveDefaultAccountId: require_resolve_allowlist.resolveDefaultMSTeamsAccountId,
|
|
263
262
|
normalizeForwardTarget: msTeamsApprovalTargetResolvers.normalizeForwardTarget,
|
|
264
263
|
resolveTurnSourceTarget: msTeamsApprovalTargetResolvers.resolveTurnSourceTarget
|
|
265
264
|
});
|
|
@@ -269,8 +268,8 @@ function isMSTeamsNativeApprovalClientEnabled(params) {
|
|
|
269
268
|
nativeSessionOnly: true
|
|
270
269
|
}) && require_thread_session.getMSTeamsApprovalApprovers(params).length > 0;
|
|
271
270
|
}
|
|
272
|
-
function shouldHandleMSTeamsNativeApprovalRequest(params) {
|
|
273
|
-
return msTeamsApprovalRouteGates.shouldHandleApprovalRequest(params) && require_thread_session.getMSTeamsApprovalApprovers(params).length > 0 && Boolean(msTeamsApprovalTargetResolvers.resolveTurnSourceTarget(params.request));
|
|
271
|
+
async function shouldHandleMSTeamsNativeApprovalRequest(params) {
|
|
272
|
+
return await msTeamsApprovalRouteGates.shouldHandleApprovalRequest(params) && require_thread_session.getMSTeamsApprovalApprovers(params).length > 0 && Boolean(msTeamsApprovalTargetResolvers.resolveTurnSourceTarget(params.request));
|
|
274
273
|
}
|
|
275
274
|
function shouldSuppressLocalMSTeamsExecApprovalPrompt(params) {
|
|
276
275
|
return (0, openclaw_plugin_sdk_approval_native_runtime.shouldSuppressLocalNativeExecApprovalPrompt)({
|
|
@@ -278,14 +277,14 @@ function shouldSuppressLocalMSTeamsExecApprovalPrompt(params) {
|
|
|
278
277
|
isNativeDeliveryEnabled: isMSTeamsNativeApprovalClientEnabled
|
|
279
278
|
});
|
|
280
279
|
}
|
|
281
|
-
const resolveMSTeamsOriginTarget = (0, openclaw_plugin_sdk_approval_native_runtime.
|
|
280
|
+
const resolveMSTeamsOriginTarget = (0, openclaw_plugin_sdk_approval_native_runtime.createChannelNativeOriginTargetResolverAsync)({
|
|
282
281
|
channel: "msteams",
|
|
283
282
|
shouldHandleRequest: shouldHandleMSTeamsNativeApprovalRequest,
|
|
284
283
|
resolveTurnSourceTarget: msTeamsApprovalTargetResolvers.resolveTurnSourceTarget,
|
|
285
284
|
resolveSessionTarget: msTeamsApprovalTargetResolvers.resolveSessionTarget,
|
|
286
285
|
normalizeTarget: msTeamsApprovalTargetResolvers.normalizeTarget
|
|
287
286
|
});
|
|
288
|
-
const msTeamsLazyApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handler_adapter_runtime.
|
|
287
|
+
const msTeamsLazyApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handler_adapter_runtime.createLazyChannelApprovalNativeRuntimeAdapterAsync)({
|
|
289
288
|
capabilityBoundary: true,
|
|
290
289
|
eventKinds: [
|
|
291
290
|
"exec",
|
|
@@ -303,11 +302,11 @@ const msTeamsLazyApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handle
|
|
|
303
302
|
request
|
|
304
303
|
}),
|
|
305
304
|
load: async () => {
|
|
306
|
-
const { msTeamsApprovalNativeRuntime } = await Promise.resolve().then(() => require("./approval-handler.runtime-
|
|
305
|
+
const { msTeamsApprovalNativeRuntime } = await Promise.resolve().then(() => require("./approval-handler.runtime-DccVf5AY.cjs"));
|
|
307
306
|
return msTeamsApprovalNativeRuntime;
|
|
308
307
|
}
|
|
309
308
|
});
|
|
310
|
-
const resolveMSTeamsApproverDmTargets = (0, openclaw_plugin_sdk_approval_native_runtime.
|
|
309
|
+
const resolveMSTeamsApproverDmTargets = (0, openclaw_plugin_sdk_approval_native_runtime.createChannelApproverDmTargetResolverAsync)({
|
|
311
310
|
shouldHandleRequest: shouldHandleMSTeamsNativeApprovalRequest,
|
|
312
311
|
resolveApprovers: require_thread_session.getMSTeamsApprovalApprovers,
|
|
313
312
|
mapApprover: (approver, params) => ({
|
|
@@ -316,7 +315,7 @@ const resolveMSTeamsApproverDmTargets = (0, openclaw_plugin_sdk_approval_native_
|
|
|
316
315
|
})
|
|
317
316
|
});
|
|
318
317
|
const msTeamsApprovalCapability = {
|
|
319
|
-
...(0, openclaw_plugin_sdk_approval_delivery_runtime.
|
|
318
|
+
...(0, openclaw_plugin_sdk_approval_delivery_runtime.createApproverRestrictedNativeApprovalCapabilityAsync)({
|
|
320
319
|
channel: "msteams",
|
|
321
320
|
channelLabel: "Microsoft Teams",
|
|
322
321
|
describeExecApprovalSetup: () => "Approve it from the Web UI for now. Microsoft Teams supports native approvals when the bot is configured. Configure `channels.msteams.allowFrom` or `channels.msteams.defaultTo` with Microsoft Entra object ID approvers.",
|
|
@@ -339,17 +338,52 @@ const msTeamsApprovalCapability = {
|
|
|
339
338
|
action: "approve",
|
|
340
339
|
approvalKind: "plugin"
|
|
341
340
|
})?.authorized ?? false,
|
|
342
|
-
isNativeDeliveryEnabled: isMSTeamsNativeApprovalClientEnabled,
|
|
341
|
+
isNativeDeliveryEnabled: async (params) => isMSTeamsNativeApprovalClientEnabled(params),
|
|
343
342
|
resolveNativeDeliveryMode: () => "channel",
|
|
344
343
|
requireMatchingTurnSourceChannel: true,
|
|
345
344
|
resolveSuppressionAccountId: ({ target, request }) => (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(target.accountId) ?? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(request.request.turnSourceAccountId),
|
|
346
345
|
resolveOriginTarget: resolveMSTeamsOriginTarget,
|
|
347
346
|
resolveApproverDmTargets: resolveMSTeamsApproverDmTargets,
|
|
348
|
-
|
|
347
|
+
nativeRuntimeAsync: msTeamsLazyApprovalNativeRuntime
|
|
349
348
|
}),
|
|
350
|
-
|
|
349
|
+
authorizeActorActionAsync: async (params) => require_thread_session.msTeamsApprovalAuth.authorizeActorAction?.(params)
|
|
351
350
|
};
|
|
352
351
|
//#endregion
|
|
352
|
+
//#region extensions/msteams/src/channel-message-tool.ts
|
|
353
|
+
function describeMSTeamsMessageTool({ cfg, accountId }) {
|
|
354
|
+
const account = require_resolve_allowlist.resolveMSTeamsAccount({
|
|
355
|
+
cfg,
|
|
356
|
+
accountId
|
|
357
|
+
});
|
|
358
|
+
const enabled = account.enabled && account.configured && account.tokenStatus === "available";
|
|
359
|
+
return {
|
|
360
|
+
actions: enabled ? [
|
|
361
|
+
"upload-file",
|
|
362
|
+
"poll",
|
|
363
|
+
"edit",
|
|
364
|
+
"delete",
|
|
365
|
+
"pin",
|
|
366
|
+
"unpin",
|
|
367
|
+
"list-pins",
|
|
368
|
+
"read",
|
|
369
|
+
"react",
|
|
370
|
+
"reactions",
|
|
371
|
+
"search",
|
|
372
|
+
"member-info",
|
|
373
|
+
"channel-list",
|
|
374
|
+
"channel-info",
|
|
375
|
+
"addParticipant",
|
|
376
|
+
"removeParticipant",
|
|
377
|
+
"renameGroup"
|
|
378
|
+
] : [],
|
|
379
|
+
capabilities: enabled ? ["presentation"] : [],
|
|
380
|
+
schema: enabled ? {
|
|
381
|
+
actions: ["unpin"],
|
|
382
|
+
properties: { pinnedMessageId: typebox.Type.Optional(typebox.Type.String({ description: "Pinned message resource ID for unpin (from pin or list-pins, not the chat message ID)." })) }
|
|
383
|
+
} : null
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
//#endregion
|
|
353
387
|
//#region src/gateway/gateway-http-route-contracts.ts
|
|
354
388
|
const GATEWAY_PROBE_ROUTES = /* @__PURE__ */ new Map([
|
|
355
389
|
["/health", "live"],
|
|
@@ -482,18 +516,39 @@ var gateway_config_runtime_exports = /* @__PURE__ */ require_rolldown_runtime.__
|
|
|
482
516
|
require_rolldown_runtime.__reExport(gateway_config_runtime_exports, require("openclaw/plugin-sdk/gateway-config-runtime"));
|
|
483
517
|
//#endregion
|
|
484
518
|
//#region extensions/msteams/src/webhook-route.ts
|
|
519
|
+
function resolveMSTeamsWebhookCollisionIssue(cfg) {
|
|
520
|
+
const owners = /* @__PURE__ */ new Map();
|
|
521
|
+
for (const accountId of require_resolve_allowlist.listMSTeamsAccountIds(cfg)) {
|
|
522
|
+
const account = require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId);
|
|
523
|
+
if (account.enabled === false) continue;
|
|
524
|
+
const path = account.webhook?.path || "/api/messages";
|
|
525
|
+
const paths = accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID && path !== "/api/messages" ? [path, "/api/messages"] : [path];
|
|
526
|
+
for (const routePath of paths) {
|
|
527
|
+
const canonical = resolvePluginRoutePathContext(routePath).canonicalPath;
|
|
528
|
+
const owner = owners.get(canonical);
|
|
529
|
+
if (owner && owner !== accountId) return "Microsoft Teams webhook path " + routePath + " is shared by accounts " + owner + " and " + accountId + ". Configure distinct webhook.path values.";
|
|
530
|
+
owners.set(canonical, accountId);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
485
534
|
function resolveMSTeamsLegacyWebhook(config) {
|
|
486
535
|
return config?.legacyWebhook || void 0;
|
|
487
536
|
}
|
|
488
|
-
function
|
|
489
|
-
const
|
|
537
|
+
function resolveMSTeamsLegacyWebhookConfigPath(cfg, accountId) {
|
|
538
|
+
const accountKey = require_resolve_allowlist.resolveMSTeamsAccountEntryKey(cfg.channels?.msteams?.accounts, accountId);
|
|
539
|
+
return accountKey && cfg.channels?.msteams?.accounts?.[accountKey]?.legacyWebhook ? `${require_resolve_allowlist.resolveMSTeamsAccountConfigPath(cfg, accountId)}.legacyWebhook` : "channels.msteams.legacyWebhook";
|
|
540
|
+
}
|
|
541
|
+
function resolveMSTeamsWebhookPathIssue({ cfg, env, accountId = openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID, accountConfig = require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId) }) {
|
|
542
|
+
const channel = accountConfig;
|
|
490
543
|
const path = channel?.webhook?.path || "/api/messages";
|
|
491
544
|
const legacy = resolveMSTeamsLegacyWebhook(channel);
|
|
492
545
|
const pathname = URL.parse(path, "http://localhost")?.pathname ?? path;
|
|
493
546
|
const probe = classifyGatewayProbePath(pathname);
|
|
494
547
|
const reason = isProtectedPluginRoutePathFromContext(resolvePluginRoutePathContext(pathname)) ? "requires Gateway authentication on the main HTTP listener" : probe !== "namespace" && probe !== "outside" ? "is reserved for Gateway checks" : /[:*{}\\]/.test(path) ? "uses Express pattern syntax that requires the compatibility listener" : void 0;
|
|
495
548
|
if (!reason) return;
|
|
496
|
-
|
|
549
|
+
const configPath = require_resolve_allowlist.resolveMSTeamsAccountConfigPath(cfg, accountId);
|
|
550
|
+
const recoveryPath = accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? "/api/messages" : `/api/messages/${accountId}`;
|
|
551
|
+
return `Microsoft Teams webhook path ${path} ${reason}. Set ${configPath}.webhook.path to ${recoveryPath} and update the Azure Bot messaging endpoint or reverse-proxy upstream to Gateway port ${(0, gateway_config_runtime_exports.resolveGatewayPort)(cfg, env)}${recoveryPath}.` + (legacy ? ` Compatibility port ${legacy.port} continues serving the current path; verify delivery before removing ${resolveMSTeamsLegacyWebhookConfigPath(cfg, accountId)}.` : " The compatibility listener is disabled, so this path cannot receive Teams callbacks.");
|
|
497
552
|
}
|
|
498
553
|
//#endregion
|
|
499
554
|
//#region extensions/msteams/src/doctor.ts
|
|
@@ -513,22 +568,31 @@ function runMSTeamsWebhookDoctorSequence({ cfg, env }) {
|
|
|
513
568
|
warningNotes: [],
|
|
514
569
|
infoNotes: []
|
|
515
570
|
};
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
env
|
|
519
|
-
});
|
|
520
|
-
if (pathIssue) return {
|
|
521
|
-
changeNotes: [],
|
|
522
|
-
warningNotes: [pathIssue],
|
|
523
|
-
infoNotes: []
|
|
524
|
-
};
|
|
525
|
-
const path = channel.webhook?.path || "/api/messages";
|
|
571
|
+
const warningNotes = [];
|
|
572
|
+
const infoNotes = [];
|
|
526
573
|
const port = (0, gateway_config_runtime_exports.resolveGatewayPort)(cfg, env);
|
|
527
|
-
const
|
|
574
|
+
for (const accountId of require_resolve_allowlist.listMSTeamsAccountIds(cfg)) {
|
|
575
|
+
const accountConfig = require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId);
|
|
576
|
+
if (accountConfig.enabled === false) continue;
|
|
577
|
+
const pathIssue = resolveMSTeamsWebhookPathIssue({
|
|
578
|
+
cfg,
|
|
579
|
+
env,
|
|
580
|
+
accountId,
|
|
581
|
+
accountConfig
|
|
582
|
+
});
|
|
583
|
+
if (pathIssue) {
|
|
584
|
+
warningNotes.push(pathIssue);
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
const path = accountConfig.webhook?.path || "/api/messages";
|
|
588
|
+
const legacy = resolveMSTeamsLegacyWebhook(accountConfig);
|
|
589
|
+
const label = accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? "Microsoft Teams" : `Microsoft Teams (${accountId})`;
|
|
590
|
+
infoNotes.push(legacy ? `${label}: compatibility port ${legacy.port} continues forwarding to Gateway route ${path}. To use only the Gateway listener, update the Azure Bot messaging endpoint or reverse-proxy upstream to Gateway port ${port}${path}, verify delivery, then remove the ${resolveMSTeamsLegacyWebhookConfigPath(cfg, accountId)} pin to close the old port.` : `${label} webhooks use Gateway port ${port}${path}; no compatibility listener is configured. Point the Azure Bot messaging endpoint or reverse-proxy upstream to this route.`);
|
|
591
|
+
}
|
|
528
592
|
return {
|
|
529
593
|
changeNotes: [],
|
|
530
|
-
warningNotes
|
|
531
|
-
infoNotes
|
|
594
|
+
warningNotes,
|
|
595
|
+
infoNotes
|
|
532
596
|
};
|
|
533
597
|
}
|
|
534
598
|
const msteamsDoctor = {
|
|
@@ -678,6 +742,16 @@ function sameAccount(ctx) {
|
|
|
678
742
|
const requester = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.requesterAccountId);
|
|
679
743
|
return requester !== void 0 && requester === requested;
|
|
680
744
|
}
|
|
745
|
+
function resolveReadPolicyAccountId(cfg, ctx) {
|
|
746
|
+
return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx?.accountId) ?? require_resolve_allowlist.resolveDefaultMSTeamsAccountId(cfg);
|
|
747
|
+
}
|
|
748
|
+
function resolveReadPolicyConfig(cfg, accountId) {
|
|
749
|
+
return require_resolve_allowlist.withAccountScopedMSTeamsConfig({
|
|
750
|
+
cfg,
|
|
751
|
+
accountId,
|
|
752
|
+
accountConfig: require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId)
|
|
753
|
+
});
|
|
754
|
+
}
|
|
681
755
|
function isCurrentMSTeamsReadTarget(params) {
|
|
682
756
|
if ((0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(params.ctx.toolContext?.currentChannelProvider)?.toLowerCase() !== "msteams" || !sameAccount(params.ctx)) return false;
|
|
683
757
|
const candidates = [
|
|
@@ -694,7 +768,7 @@ function normalizeUserTarget(target) {
|
|
|
694
768
|
function isStableUserId(value) {
|
|
695
769
|
return /^[0-9a-f-]{16,}$/i.test(value);
|
|
696
770
|
}
|
|
697
|
-
async function resolveDmTarget(cfg, target, directOperator = false) {
|
|
771
|
+
async function resolveDmTarget(cfg, accountId, target, directOperator = false) {
|
|
698
772
|
const teams = cfg.channels?.msteams;
|
|
699
773
|
if (teams?.dmPolicy === "disabled") return;
|
|
700
774
|
const userId = normalizeUserTarget(target);
|
|
@@ -706,6 +780,7 @@ async function resolveDmTarget(cfg, target, directOperator = false) {
|
|
|
706
780
|
try {
|
|
707
781
|
const [resolvedTarget, ...resolvedEntries] = await require_resolve_allowlist.resolveMSTeamsUserAllowlist({
|
|
708
782
|
cfg,
|
|
783
|
+
accountId,
|
|
709
784
|
entries: [userId, ...normalizedEntries.filter((entry) => entry !== "*")]
|
|
710
785
|
});
|
|
711
786
|
if (!resolvedTarget?.resolved || !resolvedTarget.id) return;
|
|
@@ -735,24 +810,25 @@ function hasMutableChannelConfig(cfg) {
|
|
|
735
810
|
return Object.keys(teamConfig?.channels ?? {}).some((channelKey) => channelKey !== "*" && !isStableChannelKey(channelKey));
|
|
736
811
|
});
|
|
737
812
|
}
|
|
738
|
-
async function resolveConfiguredBotFrameworkTeamKey(cfg, graphTeamId) {
|
|
813
|
+
async function resolveConfiguredBotFrameworkTeamKey(cfg, accountId, graphTeamId) {
|
|
739
814
|
const configuredTeams = cfg.channels?.msteams?.teams;
|
|
740
815
|
if (!configuredTeams) return;
|
|
741
816
|
const stableConfiguredKeys = Object.keys(configuredTeams).filter((teamKey) => teamKey !== "*" && /^19:.+@thread\./i.test(teamKey));
|
|
742
817
|
if (stableConfiguredKeys.length === 0) return;
|
|
743
|
-
const token = await require_resolve_allowlist.resolveGraphToken(cfg);
|
|
818
|
+
const token = await require_resolve_allowlist.resolveGraphToken(cfg, { accountId });
|
|
744
819
|
const channelResult = await require_resolve_allowlist.listChannelsForTeamWithPageInfo(token, graphTeamId);
|
|
745
820
|
if (channelResult.truncated) return;
|
|
746
821
|
const channelIds = new Set(channelResult.items.map((channel) => channel.id?.trim()).filter((channelId) => Boolean(channelId)));
|
|
747
822
|
const matches = stableConfiguredKeys.filter((teamKey) => channelIds.has(teamKey));
|
|
748
823
|
return matches.length === 1 ? matches[0] : void 0;
|
|
749
824
|
}
|
|
750
|
-
async function resolveStableChannelTarget(cfg, target) {
|
|
825
|
+
async function resolveStableChannelTarget(cfg, accountId, target) {
|
|
751
826
|
if (isStableGraphChannelTarget(target)) return target;
|
|
752
827
|
if (!(0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(cfg.channels?.msteams)) return;
|
|
753
828
|
try {
|
|
754
829
|
const [resolved] = await require_resolve_allowlist.resolveMSTeamsChannelAllowlist({
|
|
755
830
|
cfg,
|
|
831
|
+
accountId,
|
|
756
832
|
entries: [target]
|
|
757
833
|
});
|
|
758
834
|
return resolved?.resolved && resolved.graphTeamId && resolved.channelId ? `${resolved.graphTeamId}/${resolved.channelId}` : void 0;
|
|
@@ -760,7 +836,7 @@ async function resolveStableChannelTarget(cfg, target) {
|
|
|
760
836
|
return;
|
|
761
837
|
}
|
|
762
838
|
}
|
|
763
|
-
async function resolveAllowedChannelTarget(cfg, target) {
|
|
839
|
+
async function resolveAllowedChannelTarget(cfg, accountId, target) {
|
|
764
840
|
const teams = cfg.channels?.msteams;
|
|
765
841
|
const groupPolicy = resolveMSTeamsReadGroupPolicy(cfg);
|
|
766
842
|
if (groupPolicy === "disabled") return;
|
|
@@ -774,19 +850,19 @@ async function resolveAllowedChannelTarget(cfg, target) {
|
|
|
774
850
|
channelName: channelId,
|
|
775
851
|
allowNameMatching: (0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(teams)
|
|
776
852
|
});
|
|
777
|
-
const stableTarget = await resolveStableChannelTarget(cfg, target);
|
|
853
|
+
const stableTarget = await resolveStableChannelTarget(cfg, accountId, target);
|
|
778
854
|
if (!directRoute.allowlistConfigured && groupPolicy !== "open" && stableTarget) throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams read target is not allowed. Configure channels.msteams.teams.<team>.channels for this channel, or deliberately set channels.msteams.groupPolicy to \"open\".");
|
|
779
855
|
if (directRoute.allowed) return stableTarget;
|
|
780
856
|
if (!stableTarget || !teams?.teams) return;
|
|
781
857
|
const [stableTeamId, stableChannelId] = stableTarget.split("/", 2);
|
|
782
858
|
if (!stableTeamId || !stableChannelId) return;
|
|
783
|
-
return await isMappedChannelAllowed(cfg, stableTeamId, stableChannelId) ? stableTarget : void 0;
|
|
859
|
+
return await isMappedChannelAllowed(cfg, accountId, stableTeamId, stableChannelId) ? stableTarget : void 0;
|
|
784
860
|
}
|
|
785
|
-
async function isMappedChannelAllowed(cfg, teamId, conversationId) {
|
|
861
|
+
async function isMappedChannelAllowed(cfg, accountId, teamId, conversationId) {
|
|
786
862
|
const teams = cfg.channels?.msteams;
|
|
787
863
|
if (!teams?.teams) return false;
|
|
788
864
|
try {
|
|
789
|
-
const botFrameworkTeamKey = await resolveConfiguredBotFrameworkTeamKey(cfg, teamId);
|
|
865
|
+
const botFrameworkTeamKey = await resolveConfiguredBotFrameworkTeamKey(cfg, accountId, teamId);
|
|
790
866
|
if (botFrameworkTeamKey && resolveMSTeamsRouteConfig({
|
|
791
867
|
cfg: teams,
|
|
792
868
|
teamId: botFrameworkTeamKey,
|
|
@@ -795,6 +871,7 @@ async function isMappedChannelAllowed(cfg, teamId, conversationId) {
|
|
|
795
871
|
if (!hasMutableChannelConfig(cfg)) return false;
|
|
796
872
|
const resolved = await require_resolve_allowlist.resolveMSTeamsTeamsConfig({
|
|
797
873
|
cfg,
|
|
874
|
+
accountId,
|
|
798
875
|
teamIdMode: "graph",
|
|
799
876
|
teams: teams.teams
|
|
800
877
|
});
|
|
@@ -815,25 +892,32 @@ function bothUnknownScopesAllowed(cfg) {
|
|
|
815
892
|
return resolveMSTeamsReadGroupPolicy(cfg) === "open" && (teams?.dmPolicy ?? "pairing") === "open";
|
|
816
893
|
}
|
|
817
894
|
async function assertMSTeamsReadTargetAllowed(params) {
|
|
895
|
+
const accountId = resolveReadPolicyAccountId(params.cfg, params.ctx);
|
|
896
|
+
const cfg = resolveReadPolicyConfig(params.cfg, accountId);
|
|
818
897
|
const target = normalizeTarget(params.target);
|
|
819
898
|
const isChannel = target.includes("/");
|
|
820
899
|
const isDm = /^user:/i.test(target);
|
|
821
900
|
const isChat = require_resolve_allowlist.looksLikeMSTeamsConversationId(target);
|
|
822
901
|
const current = isCurrentMSTeamsReadTarget({
|
|
823
|
-
ctx:
|
|
902
|
+
ctx: {
|
|
903
|
+
...params.ctx,
|
|
904
|
+
accountId
|
|
905
|
+
},
|
|
824
906
|
target
|
|
825
907
|
});
|
|
826
908
|
const directOperator = params.ctx.conversationReadOrigin === "direct-operator";
|
|
827
909
|
const currentChatType = params.ctx.toolContext?.currentChatType;
|
|
828
|
-
const groupEnabled = resolveMSTeamsReadGroupPolicy(
|
|
829
|
-
const dmEnabled =
|
|
830
|
-
const allowedTarget = directOperator ? isChannel ? groupEnabled ? await resolveStableChannelTarget(
|
|
910
|
+
const groupEnabled = resolveMSTeamsReadGroupPolicy(cfg) !== "disabled";
|
|
911
|
+
const dmEnabled = cfg.channels?.msteams?.dmPolicy !== "disabled";
|
|
912
|
+
const allowedTarget = directOperator ? isChannel ? groupEnabled ? await resolveStableChannelTarget(cfg, accountId, target) : void 0 : isDm ? await resolveDmTarget(cfg, accountId, target, true) : isChat && groupEnabled && dmEnabled ? target : void 0 : current ? (isChannel ? groupEnabled : isDm || currentChatType === "direct" ? dmEnabled : currentChatType === "group" || currentChatType === "channel" ? groupEnabled : groupEnabled && dmEnabled) ? target : void 0 : isChannel ? await resolveAllowedChannelTarget(cfg, accountId, target) : isDm ? await resolveDmTarget(cfg, accountId, target) : isChat ? bothUnknownScopesAllowed(cfg) ? target : void 0 : false;
|
|
831
913
|
if (!allowedTarget) throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams read target is not allowed.");
|
|
832
914
|
return allowedTarget;
|
|
833
915
|
}
|
|
834
916
|
async function assertMSTeamsTeamEnumerationAllowed(params) {
|
|
835
|
-
const
|
|
836
|
-
const
|
|
917
|
+
const accountId = resolveReadPolicyAccountId(params.cfg, params.ctx);
|
|
918
|
+
const cfg = resolveReadPolicyConfig(params.cfg, accountId);
|
|
919
|
+
const teams = cfg.channels?.msteams;
|
|
920
|
+
const groupPolicy = resolveMSTeamsReadGroupPolicy(cfg);
|
|
837
921
|
if (groupPolicy === "disabled") throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams channel list is not allowed.");
|
|
838
922
|
const directRoute = resolveMSTeamsRouteConfig({
|
|
839
923
|
cfg: teams,
|
|
@@ -843,12 +927,13 @@ async function assertMSTeamsTeamEnumerationAllowed(params) {
|
|
|
843
927
|
allowNameMatching: (0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(teams)
|
|
844
928
|
});
|
|
845
929
|
const stableTeamId = isStableGraphTeamId(params.teamId) ? params.teamId : (0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(teams) ? (await require_resolve_allowlist.resolveMSTeamsChannelAllowlist({
|
|
846
|
-
cfg
|
|
930
|
+
cfg,
|
|
931
|
+
accountId,
|
|
847
932
|
entries: [params.teamId]
|
|
848
933
|
}))[0]?.graphTeamId : void 0;
|
|
849
934
|
if (!stableTeamId) throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams channel list requires access to every channel in the team.");
|
|
850
935
|
if (params.ctx?.conversationReadOrigin === "direct-operator") return stableTeamId;
|
|
851
|
-
if (!((directRoute.allowlistConfigured ? directRoute.allowed : groupPolicy === "open") || await isMappedChannelAllowed(
|
|
936
|
+
if (!((directRoute.allowlistConfigured ? directRoute.allowed : groupPolicy === "open") || await isMappedChannelAllowed(cfg, accountId, stableTeamId, "__openclaw_all_channels__"))) throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams channel list requires access to every channel in the team.");
|
|
852
937
|
return stableTeamId;
|
|
853
938
|
}
|
|
854
939
|
//#endregion
|
|
@@ -914,18 +999,13 @@ const TEAMS_GRAPH_PERMISSION_HINTS = {
|
|
|
914
999
|
"Sites.Read.All": "files (SharePoint)",
|
|
915
1000
|
"Files.Read.All": "files (OneDrive)"
|
|
916
1001
|
};
|
|
917
|
-
const collectMSTeamsSecurityWarnings = (0, openclaw_plugin_sdk_channel_policy.createAllowlistProviderGroupPolicyWarningCollector)({
|
|
918
|
-
providerConfigPresent: (cfg) => cfg.channels?.msteams !== void 0,
|
|
919
|
-
resolveGroupPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy,
|
|
920
|
-
collect: ({ groupPolicy }) => groupPolicy === "open" ? ["- MS Teams groups: groupPolicy=\"open\" allows any member to trigger (mention-gated). Set channels.msteams.groupPolicy=\"allowlist\" + channels.msteams.groupAllowFrom to restrict senders."] : []
|
|
921
|
-
});
|
|
922
1002
|
const collectMSTeamsSecurityFindings = openclaw_plugin_sdk_channel_policy.createConditionalWarningCollector.findings({
|
|
923
|
-
collectWarnings: collectMSTeamsSecurityWarnings,
|
|
1003
|
+
collectWarnings: require_channel_setup.collectMSTeamsSecurityWarnings,
|
|
924
1004
|
checkId: "channels.msteams.groups.open",
|
|
925
1005
|
severity: "warn",
|
|
926
1006
|
title: "MS Teams security warning"
|
|
927
1007
|
});
|
|
928
|
-
const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-
|
|
1008
|
+
const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-DzKeQAqd.cjs")), "msTeamsChannelRuntime");
|
|
929
1009
|
const MSTEAMS_REACTION_TYPES = [
|
|
930
1010
|
"like",
|
|
931
1011
|
"heart",
|
|
@@ -952,44 +1032,21 @@ function resolveGraphActionTarget(params, currentChannelId, currentGraphChannelI
|
|
|
952
1032
|
if (currentGraphTarget) return currentGraphTarget;
|
|
953
1033
|
return currentChatType === "channel" ? "" : currentChannelTarget ?? "";
|
|
954
1034
|
}
|
|
955
|
-
function
|
|
956
|
-
const
|
|
1035
|
+
function resolveMSTeamsActionMessage(ctx, to, allowCurrentMessageIdFallback = false) {
|
|
1036
|
+
const canUseCurrentMessageId = allowCurrentMessageIdFallback && msteamsContextTargetsMatch(to, {
|
|
957
1037
|
currentChannelId: ctx.toolContext?.currentChannelId ?? void 0,
|
|
958
1038
|
currentMessagingTarget: (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext?.currentGraphChannelId) ?? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext?.currentMessagingTarget)
|
|
959
|
-
})
|
|
1039
|
+
});
|
|
1040
|
+
const resolved = canUseCurrentMessageId ? (0, openclaw_plugin_sdk_channel_actions.resolveReactionMessageId)({
|
|
960
1041
|
args: ctx.params,
|
|
961
1042
|
toolContext: { currentMessageId: ctx.toolContext?.currentMessageId ?? void 0 }
|
|
962
1043
|
}) : (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.messageId) ?? "";
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
const account = require_channel_setup.resolveMSTeamsAccount(cfg);
|
|
967
|
-
const enabled = account.enabled && account.configured && account.tokenStatus === "available";
|
|
1044
|
+
const messageId = resolved == null ? "" : String(resolved).trim();
|
|
1045
|
+
const currentMessageId = ctx.toolContext?.currentMessageId;
|
|
1046
|
+
const threadRootId = canUseCurrentMessageId && ctx.toolContext?.currentChatType === "channel" && currentMessageId != null && messageId === String(currentMessageId).trim() ? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext.currentThreadTs) : void 0;
|
|
968
1047
|
return {
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
"poll",
|
|
972
|
-
"edit",
|
|
973
|
-
"delete",
|
|
974
|
-
"pin",
|
|
975
|
-
"unpin",
|
|
976
|
-
"list-pins",
|
|
977
|
-
"read",
|
|
978
|
-
"react",
|
|
979
|
-
"reactions",
|
|
980
|
-
"search",
|
|
981
|
-
"member-info",
|
|
982
|
-
"channel-list",
|
|
983
|
-
"channel-info",
|
|
984
|
-
"addParticipant",
|
|
985
|
-
"removeParticipant",
|
|
986
|
-
"renameGroup"
|
|
987
|
-
] : [],
|
|
988
|
-
capabilities: enabled ? ["presentation"] : [],
|
|
989
|
-
schema: enabled ? {
|
|
990
|
-
actions: ["unpin"],
|
|
991
|
-
properties: { pinnedMessageId: typebox.Type.Optional(typebox.Type.String({ description: "Pinned message resource ID for unpin (from pin or list-pins, not the chat message ID)." })) }
|
|
992
|
-
} : null
|
|
1048
|
+
messageId,
|
|
1049
|
+
...threadRootId ? { threadRootId } : {}
|
|
993
1050
|
};
|
|
994
1051
|
}
|
|
995
1052
|
const msteamsChannelOutbound = {
|
|
@@ -1057,7 +1114,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1057
1114
|
listGroupsLive: (runtime) => runtime.listMSTeamsDirectoryGroupsLive
|
|
1058
1115
|
})
|
|
1059
1116
|
}),
|
|
1060
|
-
resolver: { resolveTargets: async ({ cfg, inputs, kind, runtime }) => {
|
|
1117
|
+
resolver: { resolveTargets: async ({ cfg, accountId, inputs, kind, runtime }) => {
|
|
1061
1118
|
const results = inputs.map((input) => ({
|
|
1062
1119
|
input,
|
|
1063
1120
|
resolved: false,
|
|
@@ -1065,94 +1122,85 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1065
1122
|
name: void 0,
|
|
1066
1123
|
note: void 0
|
|
1067
1124
|
}));
|
|
1068
|
-
const
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
applyResolvedEntry(target, entry);
|
|
1075
|
-
});
|
|
1076
|
-
} catch (err) {
|
|
1077
|
-
runtime.error?.(`msteams resolve failed: ${String(err)}`);
|
|
1078
|
-
for (const { index } of pending) results[index].note = "lookup failed";
|
|
1125
|
+
const pending = [];
|
|
1126
|
+
for (const entry of results) {
|
|
1127
|
+
const trimmed = entry.input.trim();
|
|
1128
|
+
if (!trimmed) {
|
|
1129
|
+
entry.note = "empty input";
|
|
1130
|
+
continue;
|
|
1079
1131
|
}
|
|
1080
|
-
|
|
1081
|
-
if (kind === "user") {
|
|
1082
|
-
const pending = [];
|
|
1083
|
-
results.forEach((entry, index) => {
|
|
1084
|
-
const trimmed = entry.input.trim();
|
|
1085
|
-
if (!trimmed) {
|
|
1086
|
-
entry.note = "empty input";
|
|
1087
|
-
return;
|
|
1088
|
-
}
|
|
1132
|
+
if (kind === "user") {
|
|
1089
1133
|
const cleaned = require_resolve_allowlist.normalizeMSTeamsUserInput(trimmed);
|
|
1090
1134
|
if (/^[0-9a-fA-F-]{16,}$/.test(cleaned) || cleaned.includes("@")) {
|
|
1091
1135
|
entry.resolved = true;
|
|
1092
1136
|
entry.id = cleaned;
|
|
1093
|
-
|
|
1094
|
-
}
|
|
1095
|
-
pending.push({
|
|
1137
|
+
} else pending.push({
|
|
1096
1138
|
query: cleaned,
|
|
1097
|
-
|
|
1139
|
+
target: entry
|
|
1098
1140
|
});
|
|
1099
|
-
|
|
1100
|
-
await resolvePending(pending, (entries) => require_resolve_allowlist.resolveMSTeamsUserAllowlist({
|
|
1101
|
-
cfg,
|
|
1102
|
-
entries
|
|
1103
|
-
}), (target, entry) => {
|
|
1104
|
-
target.resolved = entry.resolved;
|
|
1105
|
-
target.id = entry.id;
|
|
1106
|
-
target.name = entry.name;
|
|
1107
|
-
target.note = entry.note;
|
|
1108
|
-
});
|
|
1109
|
-
return results;
|
|
1110
|
-
}
|
|
1111
|
-
const pending = [];
|
|
1112
|
-
results.forEach((entry, index) => {
|
|
1113
|
-
const trimmed = entry.input.trim();
|
|
1114
|
-
if (!trimmed) {
|
|
1115
|
-
entry.note = "empty input";
|
|
1116
|
-
return;
|
|
1141
|
+
continue;
|
|
1117
1142
|
}
|
|
1118
1143
|
const conversationId = require_resolve_allowlist.parseMSTeamsConversationId(trimmed);
|
|
1119
1144
|
if (conversationId !== null) {
|
|
1120
1145
|
entry.resolved = Boolean(conversationId);
|
|
1121
1146
|
entry.id = conversationId || void 0;
|
|
1122
1147
|
entry.note = conversationId ? "conversation id" : "empty conversation id";
|
|
1123
|
-
|
|
1148
|
+
continue;
|
|
1124
1149
|
}
|
|
1125
1150
|
const parsed = require_resolve_allowlist.parseMSTeamsTeamChannelInput(trimmed);
|
|
1126
1151
|
if (!parsed.team) {
|
|
1127
1152
|
entry.note = "missing team";
|
|
1128
|
-
|
|
1153
|
+
continue;
|
|
1129
1154
|
}
|
|
1130
1155
|
const query = parsed.channel ? `${parsed.team}/${parsed.channel}` : parsed.team;
|
|
1131
1156
|
pending.push({
|
|
1132
1157
|
query,
|
|
1133
|
-
|
|
1158
|
+
target: entry
|
|
1134
1159
|
});
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1160
|
+
}
|
|
1161
|
+
if (pending.length === 0) return results;
|
|
1162
|
+
const entries = pending.map((entry) => entry.query);
|
|
1163
|
+
try {
|
|
1164
|
+
if (kind === "user") (await require_resolve_allowlist.resolveMSTeamsUserAllowlist({
|
|
1165
|
+
cfg,
|
|
1166
|
+
accountId,
|
|
1167
|
+
entries
|
|
1168
|
+
})).forEach((entry, index) => {
|
|
1169
|
+
const target = pending[index]?.target;
|
|
1170
|
+
if (target) {
|
|
1171
|
+
target.resolved = entry.resolved;
|
|
1172
|
+
target.id = entry.id;
|
|
1173
|
+
target.name = entry.name;
|
|
1174
|
+
target.note = entry.note;
|
|
1175
|
+
}
|
|
1176
|
+
});
|
|
1177
|
+
else (await require_resolve_allowlist.resolveMSTeamsChannelAllowlist({
|
|
1178
|
+
cfg,
|
|
1179
|
+
accountId,
|
|
1180
|
+
entries
|
|
1181
|
+
})).forEach((entry, index) => {
|
|
1182
|
+
const target = pending[index]?.target;
|
|
1183
|
+
if (!target) return;
|
|
1184
|
+
if (!entry.resolved || !entry.teamId) {
|
|
1185
|
+
target.resolved = false;
|
|
1186
|
+
target.note = entry.note;
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
target.resolved = true;
|
|
1190
|
+
if (entry.channelId) {
|
|
1191
|
+
target.id = `${entry.teamId}/${entry.channelId}`;
|
|
1192
|
+
target.name = entry.channelName && entry.teamName ? `${entry.teamName}/${entry.channelName}` : entry.channelName ?? entry.teamName;
|
|
1193
|
+
} else {
|
|
1194
|
+
target.id = entry.teamId;
|
|
1195
|
+
target.name = entry.teamName;
|
|
1196
|
+
target.note = "team id";
|
|
1197
|
+
}
|
|
1198
|
+
if (entry.note) target.note = entry.note;
|
|
1199
|
+
});
|
|
1200
|
+
} catch (err) {
|
|
1201
|
+
runtime.error?.(`msteams resolve failed: ${String(err)}`);
|
|
1202
|
+
for (const { target } of pending) target.note = "lookup failed";
|
|
1203
|
+
}
|
|
1156
1204
|
return results;
|
|
1157
1205
|
} },
|
|
1158
1206
|
actions: {
|
|
@@ -1174,9 +1222,15 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1174
1222
|
const authError = requireMSTeamsGroupManagementAuthorization(ctx);
|
|
1175
1223
|
if (authError) return authError;
|
|
1176
1224
|
}
|
|
1225
|
+
const accountId = ctx.accountId ?? require_resolve_allowlist.resolveDefaultMSTeamsAccountId(ctx.cfg);
|
|
1226
|
+
const actionAccountId = ctx.accountId ?? (accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? void 0 : accountId);
|
|
1227
|
+
const actionContext = {
|
|
1228
|
+
...ctx,
|
|
1229
|
+
accountId
|
|
1230
|
+
};
|
|
1177
1231
|
const authorizeActionTarget = (target) => assertMSTeamsReadTargetAllowed({
|
|
1178
1232
|
cfg: ctx.cfg,
|
|
1179
|
-
ctx,
|
|
1233
|
+
ctx: actionContext,
|
|
1180
1234
|
target
|
|
1181
1235
|
});
|
|
1182
1236
|
const presentation = ctx.action === "send" ? (0, openclaw_plugin_sdk_interactive_runtime.normalizeMessagePresentation)(ctx.params.presentation) : void 0;
|
|
@@ -1190,6 +1244,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1190
1244
|
const { sendAdaptiveCardMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1191
1245
|
const result = await sendAdaptiveCardMSTeams({
|
|
1192
1246
|
cfg: ctx.cfg,
|
|
1247
|
+
accountId: actionAccountId,
|
|
1193
1248
|
to,
|
|
1194
1249
|
card,
|
|
1195
1250
|
assertDirectAdapterHandoff: ctx.assertDirectAdapterHandoff,
|
|
@@ -1210,6 +1265,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1210
1265
|
const { sendMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1211
1266
|
const result = await sendMessageMSTeams({
|
|
1212
1267
|
cfg: ctx.cfg,
|
|
1268
|
+
accountId: actionAccountId,
|
|
1213
1269
|
to,
|
|
1214
1270
|
text: resolveActionContent(ctx.params),
|
|
1215
1271
|
mediaUrl,
|
|
@@ -1240,6 +1296,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1240
1296
|
const runtime = await loadMSTeamsChannelRuntime();
|
|
1241
1297
|
const params = {
|
|
1242
1298
|
cfg: ctx.cfg,
|
|
1299
|
+
accountId: actionAccountId,
|
|
1243
1300
|
to,
|
|
1244
1301
|
activityId: messageId
|
|
1245
1302
|
};
|
|
@@ -1254,7 +1311,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1254
1311
|
} : ctx.params, ctx.toolContext?.currentChannelId, (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext?.currentGraphChannelId) ?? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext?.currentMessagingTarget), ctx.toolContext?.currentChatType);
|
|
1255
1312
|
if (ctx.action === "read" || ctx.action === "pin" || ctx.action === "reactions") {
|
|
1256
1313
|
const action = ctx.action;
|
|
1257
|
-
const messageId =
|
|
1314
|
+
const { messageId, threadRootId } = resolveMSTeamsActionMessage(ctx, graphTo, action === "reactions");
|
|
1258
1315
|
if (!graphTo || !messageId) return actionError(`${{
|
|
1259
1316
|
read: "Read",
|
|
1260
1317
|
pin: "Pin",
|
|
@@ -1264,8 +1321,10 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1264
1321
|
const runtime = await loadMSTeamsChannelRuntime();
|
|
1265
1322
|
const params = {
|
|
1266
1323
|
cfg: ctx.cfg,
|
|
1324
|
+
accountId: actionAccountId,
|
|
1267
1325
|
to,
|
|
1268
|
-
messageId
|
|
1326
|
+
messageId,
|
|
1327
|
+
threadRootId
|
|
1269
1328
|
};
|
|
1270
1329
|
if (action === "read") return jsonMSTeamsOkActionResult(action, { message: await runtime.getMessageMSTeams(params) });
|
|
1271
1330
|
if (action === "pin") return jsonMSTeamsActionResult(action, await runtime.pinMessageMSTeams(params));
|
|
@@ -1278,6 +1337,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1278
1337
|
const { unpinMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1279
1338
|
return jsonMSTeamsActionResult("unpin", await unpinMessageMSTeams({
|
|
1280
1339
|
cfg: ctx.cfg,
|
|
1340
|
+
accountId: actionAccountId,
|
|
1281
1341
|
to,
|
|
1282
1342
|
pinnedMessageId
|
|
1283
1343
|
}));
|
|
@@ -1288,11 +1348,12 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1288
1348
|
const { listPinsMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1289
1349
|
return jsonMSTeamsOkActionResult("list-pins", await listPinsMSTeams({
|
|
1290
1350
|
cfg: ctx.cfg,
|
|
1351
|
+
accountId: actionAccountId,
|
|
1291
1352
|
to
|
|
1292
1353
|
}));
|
|
1293
1354
|
}
|
|
1294
1355
|
if (ctx.action === "react") {
|
|
1295
|
-
const messageId =
|
|
1356
|
+
const { messageId, threadRootId } = resolveMSTeamsActionMessage(ctx, graphTo, true);
|
|
1296
1357
|
if (!graphTo || !messageId) return actionError("React requires a target (to) and messageId.");
|
|
1297
1358
|
const emoji = typeof ctx.params.emoji === "string" ? ctx.params.emoji.trim() : "";
|
|
1298
1359
|
const remove = typeof ctx.params.remove === "boolean" ? ctx.params.remove : false;
|
|
@@ -1307,8 +1368,10 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1307
1368
|
const runtime = await loadMSTeamsChannelRuntime();
|
|
1308
1369
|
const result = await (remove ? runtime.unreactMessageMSTeams : runtime.reactMessageMSTeams)({
|
|
1309
1370
|
cfg: ctx.cfg,
|
|
1371
|
+
accountId: actionAccountId,
|
|
1310
1372
|
to,
|
|
1311
1373
|
messageId,
|
|
1374
|
+
threadRootId,
|
|
1312
1375
|
reactionType: emoji
|
|
1313
1376
|
});
|
|
1314
1377
|
return jsonMSTeamsActionResult("react", {
|
|
@@ -1327,6 +1390,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1327
1390
|
const { searchMessagesMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1328
1391
|
return jsonMSTeamsOkActionResult("search", await searchMessagesMSTeams({
|
|
1329
1392
|
cfg: ctx.cfg,
|
|
1393
|
+
accountId: actionAccountId,
|
|
1330
1394
|
to,
|
|
1331
1395
|
query,
|
|
1332
1396
|
from: from || void 0,
|
|
@@ -1339,12 +1403,13 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1339
1403
|
if (!graphTo) return actionError("member-info requires a target (to).");
|
|
1340
1404
|
const to = await authorizeActionTarget(graphTo);
|
|
1341
1405
|
const currentRequesterId = isCurrentMSTeamsReadTarget({
|
|
1342
|
-
ctx,
|
|
1406
|
+
ctx: actionContext,
|
|
1343
1407
|
target: to
|
|
1344
1408
|
}) ? ctx.requesterSenderId : void 0;
|
|
1345
1409
|
const { getMemberInfoMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1346
1410
|
return jsonMSTeamsOkActionResult("member-info", await getMemberInfoMSTeams({
|
|
1347
1411
|
cfg: ctx.cfg,
|
|
1412
|
+
accountId: actionAccountId,
|
|
1348
1413
|
to,
|
|
1349
1414
|
userId,
|
|
1350
1415
|
currentRequesterId
|
|
@@ -1355,12 +1420,13 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1355
1420
|
if (!teamId) return actionError("channel-list requires a teamId.");
|
|
1356
1421
|
const graphTeamId = await assertMSTeamsTeamEnumerationAllowed({
|
|
1357
1422
|
cfg: ctx.cfg,
|
|
1358
|
-
ctx,
|
|
1423
|
+
ctx: actionContext,
|
|
1359
1424
|
teamId
|
|
1360
1425
|
});
|
|
1361
1426
|
const { listChannelsMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1362
1427
|
return jsonMSTeamsOkActionResult("channel-list", await listChannelsMSTeams({
|
|
1363
1428
|
cfg: ctx.cfg,
|
|
1429
|
+
accountId: actionAccountId,
|
|
1364
1430
|
teamId: graphTeamId
|
|
1365
1431
|
}));
|
|
1366
1432
|
}
|
|
@@ -1373,6 +1439,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1373
1439
|
const { getChannelInfoMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1374
1440
|
return jsonMSTeamsOkActionResult("channel-info", { channelInfo: (await getChannelInfoMSTeams({
|
|
1375
1441
|
cfg: ctx.cfg,
|
|
1442
|
+
accountId: actionAccountId,
|
|
1376
1443
|
teamId: graphTeamId,
|
|
1377
1444
|
channelId: graphChannelId
|
|
1378
1445
|
})).channel });
|
|
@@ -1387,6 +1454,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1387
1454
|
const runtime = await loadMSTeamsChannelRuntime();
|
|
1388
1455
|
const params = {
|
|
1389
1456
|
cfg: ctx.cfg,
|
|
1457
|
+
accountId: actionAccountId,
|
|
1390
1458
|
to,
|
|
1391
1459
|
userId
|
|
1392
1460
|
};
|
|
@@ -1403,6 +1471,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1403
1471
|
const { renameGroupMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1404
1472
|
return jsonMSTeamsOkActionResult("renameGroup", await renameGroupMSTeams({
|
|
1405
1473
|
cfg: ctx.cfg,
|
|
1474
|
+
accountId: actionAccountId,
|
|
1406
1475
|
to,
|
|
1407
1476
|
name
|
|
1408
1477
|
}));
|
|
@@ -1413,7 +1482,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1413
1482
|
status: (0, openclaw_plugin_sdk_status_helpers.createComputedAccountStatusAdapter)({
|
|
1414
1483
|
defaultRuntime: (0, openclaw_plugin_sdk_channel_status.createDefaultChannelRuntimeState)(openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID, { port: null }),
|
|
1415
1484
|
buildChannelSummary: ({ snapshot }) => (0, openclaw_plugin_sdk_channel_status.buildProbeChannelStatusSummary)(snapshot, { port: snapshot.port ?? null }),
|
|
1416
|
-
probeAccount: async ({
|
|
1485
|
+
probeAccount: async ({ account }) => await (await loadMSTeamsChannelRuntime()).probeMSTeams(account.config, { accountId: account.accountId }),
|
|
1417
1486
|
formatCapabilitiesProbe: ({ probe }) => {
|
|
1418
1487
|
const lines = [];
|
|
1419
1488
|
const appId = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(probe?.appId);
|
|
@@ -1445,41 +1514,52 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1445
1514
|
})
|
|
1446
1515
|
}),
|
|
1447
1516
|
gateway: { startAccount: async (ctx) => {
|
|
1448
|
-
const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./monitor-
|
|
1449
|
-
const
|
|
1517
|
+
const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./monitor-CzRI-Hsc.cjs"));
|
|
1518
|
+
const account = require_resolve_allowlist.resolveMSTeamsAccount({
|
|
1519
|
+
cfg: ctx.cfg,
|
|
1520
|
+
accountId: ctx.accountId
|
|
1521
|
+
});
|
|
1522
|
+
const accountId = account.accountId;
|
|
1523
|
+
const webhookPath = account.config.webhook?.path || "/api/messages";
|
|
1450
1524
|
const statusSink = (0, openclaw_plugin_sdk_channel_outbound.createAccountStatusSink)({
|
|
1451
|
-
accountId
|
|
1525
|
+
accountId,
|
|
1452
1526
|
setStatus: ctx.setStatus
|
|
1453
1527
|
});
|
|
1454
|
-
ctx.log?.info(
|
|
1528
|
+
ctx.log?.info("starting provider account " + accountId + " (Gateway route " + webhookPath + ")");
|
|
1455
1529
|
if (isMSTeamsNativeApprovalClientEnabled({
|
|
1456
1530
|
cfg: ctx.cfg,
|
|
1457
|
-
accountId
|
|
1531
|
+
accountId
|
|
1458
1532
|
})) (0, openclaw_plugin_sdk_channel_runtime_context.registerChannelRuntimeContext)({
|
|
1459
1533
|
channelRuntime: ctx.channelRuntime,
|
|
1460
1534
|
channelId: "msteams",
|
|
1461
|
-
accountId
|
|
1535
|
+
accountId,
|
|
1462
1536
|
capability: openclaw_plugin_sdk_approval_handler_adapter_runtime.CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY,
|
|
1463
1537
|
context: {},
|
|
1464
1538
|
abortSignal: ctx.abortSignal
|
|
1465
1539
|
});
|
|
1466
1540
|
return monitorMSTeamsProvider({
|
|
1467
1541
|
cfg: ctx.cfg,
|
|
1542
|
+
accountId,
|
|
1543
|
+
msteamsCfg: account.config,
|
|
1468
1544
|
runtime: ctx.runtime,
|
|
1469
1545
|
abortSignal: ctx.abortSignal,
|
|
1470
1546
|
statusSink
|
|
1471
1547
|
});
|
|
1472
1548
|
} }
|
|
1473
1549
|
},
|
|
1474
|
-
security: { collectWarnings: ({ cfg }) => collectMSTeamsSecurityFindings({
|
|
1550
|
+
security: { collectWarnings: ({ cfg, accountId }) => collectMSTeamsSecurityFindings({
|
|
1551
|
+
cfg,
|
|
1552
|
+
accountId
|
|
1553
|
+
}) },
|
|
1475
1554
|
pairing: { text: {
|
|
1476
1555
|
idLabel: "msteamsUserId",
|
|
1477
1556
|
message: openclaw_plugin_sdk_channel_status.PAIRING_APPROVED_MESSAGE,
|
|
1478
1557
|
normalizeAllowEntry: (0, openclaw_plugin_sdk_channel_pairing.createPairingPrefixStripper)(/^(msteams|user):/i),
|
|
1479
|
-
notify: async ({ cfg, id, message }) => {
|
|
1558
|
+
notify: async ({ cfg, accountId, id, message }) => {
|
|
1480
1559
|
const { sendMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1481
1560
|
await sendMessageMSTeams({
|
|
1482
1561
|
cfg,
|
|
1562
|
+
accountId,
|
|
1483
1563
|
to: id,
|
|
1484
1564
|
text: message
|
|
1485
1565
|
});
|
|
@@ -1502,8 +1582,8 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1502
1582
|
hasRepliedRef
|
|
1503
1583
|
};
|
|
1504
1584
|
},
|
|
1505
|
-
resolveAutoThreadId: ({ cfg, to, toolContext }) => resolveMSTeamsAutoThreadId({
|
|
1506
|
-
cfg: cfg
|
|
1585
|
+
resolveAutoThreadId: ({ cfg, accountId, to, toolContext }) => resolveMSTeamsAutoThreadId({
|
|
1586
|
+
cfg: require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId),
|
|
1507
1587
|
to,
|
|
1508
1588
|
toolContext
|
|
1509
1589
|
})
|
|
@@ -1565,6 +1645,12 @@ Object.defineProperty(exports, "resolveMSTeamsRouteConfig", {
|
|
|
1565
1645
|
return resolveMSTeamsRouteConfig;
|
|
1566
1646
|
}
|
|
1567
1647
|
});
|
|
1648
|
+
Object.defineProperty(exports, "resolveMSTeamsWebhookCollisionIssue", {
|
|
1649
|
+
enumerable: true,
|
|
1650
|
+
get: function() {
|
|
1651
|
+
return resolveMSTeamsWebhookCollisionIssue;
|
|
1652
|
+
}
|
|
1653
|
+
});
|
|
1568
1654
|
Object.defineProperty(exports, "resolveMSTeamsWebhookPathIssue", {
|
|
1569
1655
|
enumerable: true,
|
|
1570
1656
|
get: function() {
|