@openclaw/msteams 2026.9.5 → 2026.9.7
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/assets/icon.png +0 -0
- package/dist/.setup/{adapter.runtime-ChuVK6k_.cjs → adapter.runtime-BiWeMKXE.cjs} +24 -30
- package/dist/.setup/{approval-card-CPNH_q3P.cjs → approval-card-DWPDItvq.cjs} +6 -3
- package/dist/.setup/{approval-handler.runtime-DDxGPJDz.cjs → approval-handler.runtime-D1s7UR3U.cjs} +4 -4
- package/dist/.setup/bot-framework-service-url-BUhTe8F3.cjs +55 -0
- package/dist/.setup/{channel-Dzpbbht8.cjs → channel-ByzS7QJ0.cjs} +338 -220
- package/dist/.setup/{channel.runtime-TE49QvFv.cjs → channel.runtime-Baz8XDFs.cjs} +47 -144
- package/dist/.setup/{channel.setup-BVDfgdCc.cjs → channel.setup-DL8lcWT_.cjs} +6 -6
- package/dist/.setup/{config-schema-D22Lr1Qk.cjs → config-schema-0KoBzb0t.cjs} +24 -38
- package/dist/.setup/{messenger-BR1l4zw-.cjs → conversation-store-state-B7JuyZTm.cjs} +697 -297
- package/dist/.setup/{src-CpKfpP1m.cjs → monitor-BJ7IyH4y.cjs} +440 -663
- package/dist/.setup/{oauth-C6m7dvHj.cjs → oauth-DQjOnJ4l.cjs} +1 -1
- package/dist/.setup/{reaction-types-C7RA7Wxt.cjs → reaction-types-CQ4oSUe7.cjs} +2 -6
- package/dist/.setup/{resolve-allowlist-CHzaaWiC.cjs → resolve-allowlist-Pl_NQFYH.cjs} +55 -312
- package/dist/.setup/{rolldown-runtime-VH7oDXx4.cjs → rolldown-runtime-BloeesfJ.cjs} +22 -0
- package/dist/.setup/{send-D8ATH4QI.cjs → send-VUM7Sryb.cjs} +47 -97
- package/dist/.setup/{setup-plugin-api-DpiaA8z1.cjs → setup-plugin-api-Dyf8kF-l.cjs} +1 -1
- package/dist/.setup/{thread-session-CXgHK-yi.cjs → thread-session--rw3BTal.cjs} +2 -5
- package/dist/api.cjs +2 -2
- package/dist/channel-config-api.cjs +1 -1
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/configured-state.cjs +0 -1
- package/dist/directory-contract-api.cjs +1 -1
- package/dist/doctor-contract-api.cjs +201 -371
- package/dist/qa-runner-api.cjs +1 -1
- package/dist/runtime-api.cjs +0 -6
- package/dist/setup-entry.cjs +1 -1
- package/dist/setup-plugin-api.cjs +1 -1
- package/openclaw.plugin.json +46 -5
- package/package.json +10 -10
- package/dist/.setup/polls-BJ4-4uZm.cjs +0 -668
- package/dist/.setup/secret-input-C65t6kjM.cjs +0 -1
- package/dist/.setup/sso-token-store-YYLHXgFH.cjs +0 -111
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-BloeesfJ.cjs");
|
|
1
2
|
require("../runtime-api.cjs");
|
|
2
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
3
|
+
const require_resolve_allowlist = require("./resolve-allowlist-Pl_NQFYH.cjs");
|
|
3
4
|
const require_directory_contract_api = require("../directory-contract-api.cjs");
|
|
4
|
-
const require_thread_session = require("./thread-session
|
|
5
|
-
const require_channel_setup = require("./channel.setup-
|
|
5
|
+
const require_thread_session = require("./thread-session--rw3BTal.cjs");
|
|
6
|
+
const require_channel_setup = require("./channel.setup-DL8lcWT_.cjs");
|
|
6
7
|
let openclaw_plugin_sdk_approval_handler_adapter_runtime = require("openclaw/plugin-sdk/approval-handler-adapter-runtime");
|
|
7
8
|
let openclaw_plugin_sdk_channel_actions = require("openclaw/plugin-sdk/channel-actions");
|
|
8
9
|
let openclaw_plugin_sdk_channel_core = require("openclaw/plugin-sdk/channel-core");
|
|
@@ -21,7 +22,6 @@ let openclaw_plugin_sdk_reply_reference = require("openclaw/plugin-sdk/reply-ref
|
|
|
21
22
|
let openclaw_plugin_sdk_approval_delivery_runtime = require("openclaw/plugin-sdk/approval-delivery-runtime");
|
|
22
23
|
let openclaw_plugin_sdk_approval_native_runtime = require("openclaw/plugin-sdk/approval-native-runtime");
|
|
23
24
|
let openclaw_plugin_sdk_channel_targets = require("openclaw/plugin-sdk/channel-targets");
|
|
24
|
-
let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
|
|
25
25
|
let openclaw_plugin_sdk_dangerous_name_runtime = require("openclaw/plugin-sdk/dangerous-name-runtime");
|
|
26
26
|
let openclaw_plugin_sdk_runtime_group_policy = require("openclaw/plugin-sdk/runtime-group-policy");
|
|
27
27
|
let openclaw_plugin_sdk_text_chunking = require("openclaw/plugin-sdk/text-chunking");
|
|
@@ -42,6 +42,52 @@ function resolveActionUploadFilePath(params) {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
//#endregion
|
|
45
|
+
//#region extensions/msteams/src/action-results.ts
|
|
46
|
+
function jsonActionResult(data, details = data) {
|
|
47
|
+
return {
|
|
48
|
+
content: [{
|
|
49
|
+
type: "text",
|
|
50
|
+
text: JSON.stringify(data)
|
|
51
|
+
}],
|
|
52
|
+
details
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function jsonMSTeamsActionResult(action, data = {}) {
|
|
56
|
+
return jsonActionResult({
|
|
57
|
+
channel: "msteams",
|
|
58
|
+
action,
|
|
59
|
+
...data
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function jsonMSTeamsOkActionResult(action, data = {}) {
|
|
63
|
+
return jsonActionResult({
|
|
64
|
+
ok: true,
|
|
65
|
+
channel: "msteams",
|
|
66
|
+
action,
|
|
67
|
+
...data
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function jsonMSTeamsConversationResult(conversationId) {
|
|
71
|
+
return jsonActionResult({
|
|
72
|
+
ok: true,
|
|
73
|
+
channel: "msteams",
|
|
74
|
+
conversationId
|
|
75
|
+
}, {
|
|
76
|
+
ok: true,
|
|
77
|
+
channel: "msteams"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function actionError(message) {
|
|
81
|
+
return {
|
|
82
|
+
isError: true,
|
|
83
|
+
content: [{
|
|
84
|
+
type: "text",
|
|
85
|
+
text: message
|
|
86
|
+
}],
|
|
87
|
+
details: { error: message }
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
45
91
|
//#region extensions/msteams/src/policy.ts
|
|
46
92
|
const teamScopeKey = (teamKey) => (0, openclaw_plugin_sdk_channel_policy.scopeKey)(["team", teamKey]);
|
|
47
93
|
const channelScopeKey = (teamKey, channelKey) => (0, openclaw_plugin_sdk_channel_policy.scopeKey)(["team", teamKey], ["channel", channelKey]);
|
|
@@ -185,18 +231,18 @@ function resolveMSTeamsGroupToolPolicy(params) {
|
|
|
185
231
|
...senderScope
|
|
186
232
|
});
|
|
187
233
|
}
|
|
188
|
-
function resolveMSTeamsAllowlistMatch(params) {
|
|
189
|
-
return (0, openclaw_plugin_sdk_allow_from.resolveAllowlistMatchSimple)(params);
|
|
190
|
-
}
|
|
191
234
|
function resolveMSTeamsReplyPolicy(params) {
|
|
192
235
|
if (params.isDirectMessage) return {
|
|
193
236
|
requireMention: false,
|
|
194
237
|
replyStyle: "thread"
|
|
195
238
|
};
|
|
196
239
|
const requireMention = params.channelConfig?.requireMention ?? params.teamConfig?.requireMention ?? params.globalConfig?.requireMention ?? true;
|
|
240
|
+
const explicitReplyStyle = params.channelConfig?.replyStyle ?? params.teamConfig?.replyStyle ?? params.globalConfig?.replyStyle;
|
|
241
|
+
const requireMentionInBotThreads = params.channelConfig?.requireMentionInBotThreads ?? params.teamConfig?.requireMentionInBotThreads ?? params.globalConfig?.requireMentionInBotThreads;
|
|
197
242
|
return {
|
|
198
243
|
requireMention,
|
|
199
|
-
replyStyle:
|
|
244
|
+
replyStyle: explicitReplyStyle ?? (requireMention ? "thread" : "top-level"),
|
|
245
|
+
...requireMentionInBotThreads === void 0 ? {} : { requireMentionInBotThreads }
|
|
200
246
|
};
|
|
201
247
|
}
|
|
202
248
|
//#endregion
|
|
@@ -347,7 +393,7 @@ const msTeamsLazyApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handle
|
|
|
347
393
|
request
|
|
348
394
|
}),
|
|
349
395
|
load: async () => {
|
|
350
|
-
const { msTeamsApprovalNativeRuntime } = await Promise.resolve().then(() => require("./approval-handler.runtime-
|
|
396
|
+
const { msTeamsApprovalNativeRuntime } = await Promise.resolve().then(() => require("./approval-handler.runtime-D1s7UR3U.cjs"));
|
|
351
397
|
return msTeamsApprovalNativeRuntime;
|
|
352
398
|
}
|
|
353
399
|
});
|
|
@@ -363,7 +409,7 @@ const msTeamsApprovalCapability = {
|
|
|
363
409
|
...(0, openclaw_plugin_sdk_approval_delivery_runtime.createApproverRestrictedNativeApprovalCapability)({
|
|
364
410
|
channel: "msteams",
|
|
365
411
|
channelLabel: "Microsoft Teams",
|
|
366
|
-
describeExecApprovalSetup: () => "Approve it from the Web UI
|
|
412
|
+
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.",
|
|
367
413
|
listAccountIds: require_channel_setup.msteamsConfigAdapter.listAccountIds,
|
|
368
414
|
hasApprovers: ({ cfg, accountId }) => require_thread_session.getMSTeamsApprovalApprovers({
|
|
369
415
|
cfg,
|
|
@@ -394,6 +440,160 @@ const msTeamsApprovalCapability = {
|
|
|
394
440
|
authorizeActorAction: (params) => require_thread_session.msTeamsApprovalAuth.authorizeActorAction?.(params)
|
|
395
441
|
};
|
|
396
442
|
//#endregion
|
|
443
|
+
//#region src/gateway/gateway-http-route-contracts.ts
|
|
444
|
+
const GATEWAY_PROBE_ROUTES = /* @__PURE__ */ new Map([
|
|
445
|
+
["/health", "live"],
|
|
446
|
+
["/healthz", "live"],
|
|
447
|
+
["/ready", "ready"],
|
|
448
|
+
["/readyz", "ready"],
|
|
449
|
+
["/startup", "startup"],
|
|
450
|
+
["/startupz", "startup"]
|
|
451
|
+
]);
|
|
452
|
+
function classifyGatewayProbePath(pathname) {
|
|
453
|
+
for (const [root, status] of GATEWAY_PROBE_ROUTES) {
|
|
454
|
+
if (pathname === root) return status;
|
|
455
|
+
if (pathname.startsWith(`${root}/`)) return "namespace";
|
|
456
|
+
}
|
|
457
|
+
return "outside";
|
|
458
|
+
}
|
|
459
|
+
//#endregion
|
|
460
|
+
//#region packages/normalization-core/src/string-coerce.ts
|
|
461
|
+
/** Trims string input and returns null for non-strings or empty strings. */
|
|
462
|
+
function normalizeNullableString(value) {
|
|
463
|
+
if (typeof value !== "string") return null;
|
|
464
|
+
const trimmed = value.trim();
|
|
465
|
+
return trimmed ? trimmed : null;
|
|
466
|
+
}
|
|
467
|
+
/** Trims string input and returns undefined for non-strings or empty strings. */
|
|
468
|
+
function normalizeOptionalString$3(value) {
|
|
469
|
+
return normalizeNullableString(value) ?? void 0;
|
|
470
|
+
}
|
|
471
|
+
/** Lowercases a normalized optional string. */
|
|
472
|
+
function normalizeOptionalLowercaseString(value) {
|
|
473
|
+
return normalizeOptionalString$3(value)?.toLowerCase();
|
|
474
|
+
}
|
|
475
|
+
/** Lowercases a normalized string or returns an empty string when absent. */
|
|
476
|
+
function normalizeLowercaseStringOrEmpty$1(value) {
|
|
477
|
+
return normalizeOptionalLowercaseString(value) ?? "";
|
|
478
|
+
}
|
|
479
|
+
//#endregion
|
|
480
|
+
//#region src/plugins/http-path-prefix.ts
|
|
481
|
+
function prefixMatchPath(pathname, prefix) {
|
|
482
|
+
return pathname === prefix || pathname.startsWith(`${prefix}/`) || pathname.startsWith(`${prefix}%`);
|
|
483
|
+
}
|
|
484
|
+
//#endregion
|
|
485
|
+
//#region src/gateway/security-path.ts
|
|
486
|
+
const MAX_PATH_DECODE_PASSES = 32;
|
|
487
|
+
function normalizePathSeparators(pathname) {
|
|
488
|
+
const collapsed = pathname.replace(/\/{2,}/g, "/");
|
|
489
|
+
if (collapsed.length <= 1) return collapsed;
|
|
490
|
+
return collapsed.replace(/\/+$/, "");
|
|
491
|
+
}
|
|
492
|
+
function resolveDotSegments(pathname) {
|
|
493
|
+
try {
|
|
494
|
+
return new URL(pathname, "http://localhost").pathname;
|
|
495
|
+
} catch {
|
|
496
|
+
return pathname;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function normalizePathForSecurity(pathname) {
|
|
500
|
+
return normalizePathSeparators(normalizeLowercaseStringOrEmpty$1(resolveDotSegments(pathname))) || "/";
|
|
501
|
+
}
|
|
502
|
+
function buildCanonicalPathCandidates(pathname, maxDecodePasses = MAX_PATH_DECODE_PASSES) {
|
|
503
|
+
const candidates = /* @__PURE__ */ new Set([normalizePathForSecurity(pathname)]);
|
|
504
|
+
let decoded = pathname;
|
|
505
|
+
let malformedEncoding = false;
|
|
506
|
+
let decodePasses = 0;
|
|
507
|
+
for (let pass = 0; pass < maxDecodePasses; pass++) {
|
|
508
|
+
let nextDecoded;
|
|
509
|
+
try {
|
|
510
|
+
nextDecoded = decodeURIComponent(decoded);
|
|
511
|
+
} catch {
|
|
512
|
+
malformedEncoding = true;
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
if (nextDecoded === decoded) break;
|
|
516
|
+
decodePasses += 1;
|
|
517
|
+
decoded = nextDecoded;
|
|
518
|
+
candidates.add(normalizePathForSecurity(decoded));
|
|
519
|
+
}
|
|
520
|
+
let decodePassLimitReached = false;
|
|
521
|
+
if (!malformedEncoding) try {
|
|
522
|
+
decodePassLimitReached = decodeURIComponent(decoded) !== decoded;
|
|
523
|
+
} catch {
|
|
524
|
+
malformedEncoding = true;
|
|
525
|
+
}
|
|
526
|
+
return {
|
|
527
|
+
candidates: [...candidates],
|
|
528
|
+
decodePasses,
|
|
529
|
+
decodePassLimitReached,
|
|
530
|
+
malformedEncoding
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
function canonicalizePathForSecurity(pathname) {
|
|
534
|
+
const { candidates, decodePasses, decodePassLimitReached, malformedEncoding } = buildCanonicalPathCandidates(pathname);
|
|
535
|
+
return {
|
|
536
|
+
canonicalPath: candidates[candidates.length - 1] ?? "/",
|
|
537
|
+
candidates,
|
|
538
|
+
decodePasses,
|
|
539
|
+
decodePassLimitReached,
|
|
540
|
+
malformedEncoding,
|
|
541
|
+
rawNormalizedPath: normalizePathSeparators(normalizeLowercaseStringOrEmpty$1(pathname)) || "/"
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
const PROTECTED_PLUGIN_ROUTE_PREFIXES = ["/api/channels"];
|
|
545
|
+
//#endregion
|
|
546
|
+
//#region src/gateway/server/plugins-http/path-context.ts
|
|
547
|
+
function normalizeProtectedPrefix(prefix) {
|
|
548
|
+
const collapsed = normalizeLowercaseStringOrEmpty$1(prefix).replace(/\/{2,}/g, "/");
|
|
549
|
+
if (collapsed.length <= 1) return collapsed || "/";
|
|
550
|
+
return collapsed.replace(/\/+$/, "");
|
|
551
|
+
}
|
|
552
|
+
const NORMALIZED_PROTECTED_PLUGIN_ROUTE_PREFIXES = PROTECTED_PLUGIN_ROUTE_PREFIXES.map(normalizeProtectedPrefix);
|
|
553
|
+
/** Returns true when any decoded path candidate targets a protected route. */
|
|
554
|
+
function isProtectedPluginRoutePathFromContext(context) {
|
|
555
|
+
if (context.candidates.some((candidate) => NORMALIZED_PROTECTED_PLUGIN_ROUTE_PREFIXES.some((prefix) => prefixMatchPath(candidate, prefix)))) return true;
|
|
556
|
+
if (context.decodePassLimitReached) return true;
|
|
557
|
+
if (!context.malformedEncoding) return false;
|
|
558
|
+
return NORMALIZED_PROTECTED_PLUGIN_ROUTE_PREFIXES.some((prefix) => prefixMatchPath(context.rawNormalizedPath, prefix));
|
|
559
|
+
}
|
|
560
|
+
/** Builds all security-relevant decoded path candidates for a request path. */
|
|
561
|
+
function resolvePluginRoutePathContext(pathname) {
|
|
562
|
+
const canonical = canonicalizePathForSecurity(pathname);
|
|
563
|
+
return {
|
|
564
|
+
pathname,
|
|
565
|
+
canonicalPath: canonical.canonicalPath,
|
|
566
|
+
candidates: canonical.candidates,
|
|
567
|
+
malformedEncoding: canonical.malformedEncoding,
|
|
568
|
+
decodePassLimitReached: canonical.decodePassLimitReached,
|
|
569
|
+
rawNormalizedPath: canonical.rawNormalizedPath
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
//#endregion
|
|
573
|
+
//#region \0openclaw:bundled-sdk:openclaw/plugin-sdk/gateway-config-runtime
|
|
574
|
+
var gateway_config_runtime_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
575
|
+
classifyGatewayProbePath: () => classifyGatewayProbePath,
|
|
576
|
+
isProtectedPluginRoutePathFromContext: () => isProtectedPluginRoutePathFromContext,
|
|
577
|
+
resolvePluginRoutePathContext: () => resolvePluginRoutePathContext
|
|
578
|
+
});
|
|
579
|
+
require_rolldown_runtime.__reExport(gateway_config_runtime_exports, require("openclaw/plugin-sdk/gateway-config-runtime"));
|
|
580
|
+
//#endregion
|
|
581
|
+
//#region extensions/msteams/src/webhook-route.ts
|
|
582
|
+
function resolveMSTeamsLegacyWebhook(config) {
|
|
583
|
+
const listener = config?.legacyWebhook;
|
|
584
|
+
return listener === false ? void 0 : listener ?? { port: 3978 };
|
|
585
|
+
}
|
|
586
|
+
function resolveMSTeamsWebhookPathIssue({ cfg, env }) {
|
|
587
|
+
const channel = cfg.channels?.msteams;
|
|
588
|
+
const path = channel?.webhook?.path || "/api/messages";
|
|
589
|
+
const legacy = resolveMSTeamsLegacyWebhook(channel);
|
|
590
|
+
const pathname = URL.parse(path, "http://localhost")?.pathname ?? path;
|
|
591
|
+
const probe = classifyGatewayProbePath(pathname);
|
|
592
|
+
const reason = isProtectedPluginRoutePathFromContext(resolvePluginRoutePathContext(pathname)) ? "requires Gateway authentication on the main HTTP listener" : probe !== "namespace" && probe !== "outside" ? "is reserved for Gateway probes" : /[:*{}\\]/.test(path) ? "uses Express pattern syntax that requires the compatibility listener" : void 0;
|
|
593
|
+
if (!reason) return;
|
|
594
|
+
return `Microsoft Teams webhook path ${path} ${reason}. Set channels.msteams.webhook.path to /api/messages and update the Azure Bot messaging endpoint or reverse-proxy upstream to Gateway port ${(0, gateway_config_runtime_exports.resolveGatewayPort)(cfg, env)}/api/messages; verify delivery before setting channels.msteams.legacyWebhook=false.` + (legacy ? ` Compatibility port ${legacy.port} continues serving the current path.` : " The compatibility listener is disabled, so this path cannot receive Teams callbacks.");
|
|
595
|
+
}
|
|
596
|
+
//#endregion
|
|
397
597
|
//#region extensions/msteams/src/doctor.ts
|
|
398
598
|
const isMSTeamsMutableAllowEntry = (0, openclaw_plugin_sdk_channel_policy.buildMutableAllowEntryDetector)({
|
|
399
599
|
prefixes: ["msteams:", "user:"],
|
|
@@ -404,6 +604,39 @@ const collectMSTeamsMutableAllowlistWarnings = (0, openclaw_plugin_sdk_channel_p
|
|
|
404
604
|
detector: isMSTeamsMutableAllowEntry,
|
|
405
605
|
collectLists: (scope) => (0, openclaw_plugin_sdk_channel_policy.collectStandardAllowlistLists)(scope)
|
|
406
606
|
});
|
|
607
|
+
function runMSTeamsWebhookDoctorSequence({ cfg, env }) {
|
|
608
|
+
const channel = cfg.channels?.msteams;
|
|
609
|
+
if (!channel || channel.enabled === false) return {
|
|
610
|
+
changeNotes: [],
|
|
611
|
+
warningNotes: [],
|
|
612
|
+
infoNotes: []
|
|
613
|
+
};
|
|
614
|
+
const pathIssue = resolveMSTeamsWebhookPathIssue({
|
|
615
|
+
cfg,
|
|
616
|
+
env
|
|
617
|
+
});
|
|
618
|
+
if (pathIssue) return {
|
|
619
|
+
changeNotes: [],
|
|
620
|
+
warningNotes: [pathIssue],
|
|
621
|
+
infoNotes: []
|
|
622
|
+
};
|
|
623
|
+
const path = channel.webhook?.path || "/api/messages";
|
|
624
|
+
const port = (0, gateway_config_runtime_exports.resolveGatewayPort)(cfg, env);
|
|
625
|
+
const legacy = resolveMSTeamsLegacyWebhook(channel);
|
|
626
|
+
return {
|
|
627
|
+
changeNotes: [],
|
|
628
|
+
warningNotes: [],
|
|
629
|
+
infoNotes: [legacy ? `Microsoft Teams: 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 set channels.msteams.legacyWebhook=false to close the old port.` : `Microsoft Teams webhooks use Gateway port ${port}${path}; the compatibility listener is disabled by channels.msteams.legacyWebhook=false. Point the Azure Bot messaging endpoint or reverse-proxy upstream to this route.`]
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
const msteamsDoctor = {
|
|
633
|
+
dmAllowFromMode: "topOnly",
|
|
634
|
+
groupModel: "hybrid",
|
|
635
|
+
groupAllowFromFallbackToAllowFrom: true,
|
|
636
|
+
warnOnEmptyGroupSenderAllowlist: true,
|
|
637
|
+
collectMutableAllowlistWarnings: collectMSTeamsMutableAllowlistWarnings,
|
|
638
|
+
runConfigSequence: runMSTeamsWebhookDoctorSequence
|
|
639
|
+
};
|
|
407
640
|
//#endregion
|
|
408
641
|
//#region extensions/msteams/src/graph-action-context.ts
|
|
409
642
|
const MSTEAMS_GROUP_MANAGEMENT_ACTIONS = /* @__PURE__ */ new Set([
|
|
@@ -806,50 +1039,7 @@ const collectMSTeamsSecurityFindings = openclaw_plugin_sdk_channel_policy.create
|
|
|
806
1039
|
severity: "warn",
|
|
807
1040
|
title: "MS Teams security warning"
|
|
808
1041
|
});
|
|
809
|
-
const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-
|
|
810
|
-
function jsonActionResult(data) {
|
|
811
|
-
return {
|
|
812
|
-
content: [{
|
|
813
|
-
type: "text",
|
|
814
|
-
text: JSON.stringify(data)
|
|
815
|
-
}],
|
|
816
|
-
details: data
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
function jsonMSTeamsActionResult(action, data = {}) {
|
|
820
|
-
return jsonActionResult({
|
|
821
|
-
channel: "msteams",
|
|
822
|
-
action,
|
|
823
|
-
...data
|
|
824
|
-
});
|
|
825
|
-
}
|
|
826
|
-
function jsonMSTeamsOkActionResult(action, data = {}) {
|
|
827
|
-
return jsonActionResult({
|
|
828
|
-
ok: true,
|
|
829
|
-
channel: "msteams",
|
|
830
|
-
action,
|
|
831
|
-
...data
|
|
832
|
-
});
|
|
833
|
-
}
|
|
834
|
-
function jsonMSTeamsConversationResult(conversationId) {
|
|
835
|
-
return jsonActionResultWithDetails({
|
|
836
|
-
ok: true,
|
|
837
|
-
channel: "msteams",
|
|
838
|
-
conversationId
|
|
839
|
-
}, {
|
|
840
|
-
ok: true,
|
|
841
|
-
channel: "msteams"
|
|
842
|
-
});
|
|
843
|
-
}
|
|
844
|
-
function jsonActionResultWithDetails(contentData, details) {
|
|
845
|
-
return {
|
|
846
|
-
content: [{
|
|
847
|
-
type: "text",
|
|
848
|
-
text: JSON.stringify(contentData)
|
|
849
|
-
}],
|
|
850
|
-
details
|
|
851
|
-
};
|
|
852
|
-
}
|
|
1042
|
+
const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-Baz8XDFs.cjs")), "msTeamsChannelRuntime");
|
|
853
1043
|
const MSTEAMS_REACTION_TYPES = [
|
|
854
1044
|
"like",
|
|
855
1045
|
"heart",
|
|
@@ -858,16 +1048,6 @@ const MSTEAMS_REACTION_TYPES = [
|
|
|
858
1048
|
"sad",
|
|
859
1049
|
"angry"
|
|
860
1050
|
];
|
|
861
|
-
function actionError(message) {
|
|
862
|
-
return {
|
|
863
|
-
isError: true,
|
|
864
|
-
content: [{
|
|
865
|
-
type: "text",
|
|
866
|
-
text: message
|
|
867
|
-
}],
|
|
868
|
-
details: { error: message }
|
|
869
|
-
};
|
|
870
|
-
}
|
|
871
1051
|
function requireMSTeamsGroupManagementAuthorization(ctx) {
|
|
872
1052
|
if (ctx.senderIsOwner === true || ctx.gatewayClientScopes?.includes("operator.admin")) return null;
|
|
873
1053
|
return actionError("Microsoft Teams group management requires an owner or operator.admin requester.");
|
|
@@ -889,18 +1069,6 @@ function resolveGraphActionTarget(params, currentChannelId, currentGraphChannelI
|
|
|
889
1069
|
function resolveCurrentGraphActionTarget(toolContext) {
|
|
890
1070
|
return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(toolContext?.currentGraphChannelId) ?? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(toolContext?.currentMessagingTarget);
|
|
891
1071
|
}
|
|
892
|
-
function resolveActionMessageId(params) {
|
|
893
|
-
return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(params.messageId) ?? "";
|
|
894
|
-
}
|
|
895
|
-
function resolveActionPinnedMessageId(params) {
|
|
896
|
-
return typeof params.pinnedMessageId === "string" ? params.pinnedMessageId.trim() : typeof params.messageId === "string" ? params.messageId.trim() : "";
|
|
897
|
-
}
|
|
898
|
-
function resolveActionQuery(params) {
|
|
899
|
-
return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(params.query) ?? "";
|
|
900
|
-
}
|
|
901
|
-
function readOptionalTrimmedString(params, key) {
|
|
902
|
-
return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(params[key]);
|
|
903
|
-
}
|
|
904
1072
|
function resolveMSTeamsActionTarget(params) {
|
|
905
1073
|
return params.graphOnly ? resolveGraphActionTarget(params.toolParams, params.currentChannelId, params.currentGraphChannelId, params.currentChatType) : resolveActionTarget(params.toolParams, params.currentChannelId);
|
|
906
1074
|
}
|
|
@@ -911,7 +1079,14 @@ async function runWithRequiredActionTarget(params) {
|
|
|
911
1079
|
}
|
|
912
1080
|
async function runWithRequiredActionMessageTarget(params) {
|
|
913
1081
|
const to = resolveMSTeamsActionTarget(params);
|
|
914
|
-
const
|
|
1082
|
+
const messageIdRaw = params.allowCurrentMessageIdFallback === true && msteamsContextTargetsMatch(to, {
|
|
1083
|
+
currentChannelId: params.currentChannelId ?? void 0,
|
|
1084
|
+
currentMessagingTarget: params.currentGraphChannelId ?? void 0
|
|
1085
|
+
}) ? (0, openclaw_plugin_sdk_channel_actions.resolveReactionMessageId)({
|
|
1086
|
+
args: params.toolParams,
|
|
1087
|
+
toolContext: { currentMessageId: params.currentMessageId ?? void 0 }
|
|
1088
|
+
}) : (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(params.toolParams.messageId) ?? "";
|
|
1089
|
+
const messageId = messageIdRaw == null ? "" : String(messageIdRaw).trim();
|
|
915
1090
|
if (!to || !messageId) return actionError(`${params.actionLabel} requires a target (to) and messageId.`);
|
|
916
1091
|
return await params.run({
|
|
917
1092
|
to,
|
|
@@ -920,7 +1095,7 @@ async function runWithRequiredActionMessageTarget(params) {
|
|
|
920
1095
|
}
|
|
921
1096
|
async function runWithRequiredActionPinnedMessageTarget(params) {
|
|
922
1097
|
const to = resolveMSTeamsActionTarget(params);
|
|
923
|
-
const pinnedMessageId =
|
|
1098
|
+
const pinnedMessageId = typeof params.toolParams.pinnedMessageId === "string" ? params.toolParams.pinnedMessageId.trim() : (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(params.toolParams.messageId) ?? "";
|
|
924
1099
|
if (!to || !pinnedMessageId) return actionError(`${params.actionLabel} requires a target (to) and pinnedMessageId.`);
|
|
925
1100
|
return await params.run({
|
|
926
1101
|
to,
|
|
@@ -1013,21 +1188,15 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1013
1188
|
agentPrompt: { messageToolHints: () => ["- Adaptive Cards supported. Use `action=send` with `card={type,version,body}` to send rich cards.", "- MSTeams targeting: omit `target` to reply to the current conversation (auto-inferred). Explicit targets: `user:ID` or `user:Display Name` (requires Graph API) for DMs, `conversation:19:...@thread.tacv2` for groups/channels. Prefer IDs over display names for speed."] },
|
|
1014
1189
|
groups: { resolveToolPolicy: resolveMSTeamsGroupToolPolicy },
|
|
1015
1190
|
approvalCapability: msTeamsApprovalCapability,
|
|
1016
|
-
doctor:
|
|
1017
|
-
dmAllowFromMode: "topOnly",
|
|
1018
|
-
groupModel: "hybrid",
|
|
1019
|
-
groupAllowFromFallbackToAllowFrom: true,
|
|
1020
|
-
warnOnEmptyGroupSenderAllowlist: true,
|
|
1021
|
-
collectMutableAllowlistWarnings: collectMSTeamsMutableAllowlistWarnings
|
|
1022
|
-
},
|
|
1191
|
+
doctor: msteamsDoctor,
|
|
1023
1192
|
messaging: {
|
|
1024
1193
|
targetPrefixes: ["msteams", "teams"],
|
|
1025
1194
|
directTargetStyle: "user-prefixed",
|
|
1026
1195
|
normalizeTarget: require_resolve_allowlist.normalizeMSTeamsMessagingTarget,
|
|
1027
1196
|
inferTargetChatType: ({ to }) => inferMSTeamsTargetChatType(to),
|
|
1028
|
-
resolveOutboundSessionRoute:
|
|
1197
|
+
resolveOutboundSessionRoute: resolveMSTeamsOutboundSessionRoute,
|
|
1029
1198
|
targetResolver: {
|
|
1030
|
-
looksLikeId:
|
|
1199
|
+
looksLikeId: require_resolve_allowlist.looksLikeMSTeamsTargetId,
|
|
1031
1200
|
hint: "<conversationId|user:ID|conversation:ID>"
|
|
1032
1201
|
}
|
|
1033
1202
|
},
|
|
@@ -1048,7 +1217,6 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1048
1217
|
name: void 0,
|
|
1049
1218
|
note: void 0
|
|
1050
1219
|
}));
|
|
1051
|
-
const stripPrefix = (value) => require_resolve_allowlist.normalizeMSTeamsUserInput(value);
|
|
1052
1220
|
const markPendingLookupFailed = (pending) => {
|
|
1053
1221
|
pending.forEach(({ index }) => {
|
|
1054
1222
|
const entry = results[index];
|
|
@@ -1076,7 +1244,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1076
1244
|
entry.note = "empty input";
|
|
1077
1245
|
return;
|
|
1078
1246
|
}
|
|
1079
|
-
const cleaned =
|
|
1247
|
+
const cleaned = require_resolve_allowlist.normalizeMSTeamsUserInput(trimmed);
|
|
1080
1248
|
if (/^[0-9a-fA-F-]{16,}$/.test(cleaned) || cleaned.includes("@")) {
|
|
1081
1249
|
entry.resolved = true;
|
|
1082
1250
|
entry.id = cleaned;
|
|
@@ -1189,15 +1357,11 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1189
1357
|
assertDirectAdapterHandoff: ctx.assertDirectAdapterHandoff,
|
|
1190
1358
|
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
1191
1359
|
});
|
|
1192
|
-
return
|
|
1360
|
+
return jsonActionResult({
|
|
1193
1361
|
ok: true,
|
|
1194
1362
|
channel: "msteams",
|
|
1195
1363
|
messageId: result.messageId,
|
|
1196
1364
|
conversationId: result.conversationId
|
|
1197
|
-
}, {
|
|
1198
|
-
ok: true,
|
|
1199
|
-
channel: "msteams",
|
|
1200
|
-
messageId: result.messageId
|
|
1201
1365
|
});
|
|
1202
1366
|
}
|
|
1203
1367
|
});
|
|
@@ -1216,62 +1380,47 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1216
1380
|
to,
|
|
1217
1381
|
text: resolveActionContent(ctx.params),
|
|
1218
1382
|
mediaUrl,
|
|
1219
|
-
filename:
|
|
1383
|
+
filename: (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.filename) ?? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.title),
|
|
1220
1384
|
mediaAccess: ctx.mediaAccess,
|
|
1221
1385
|
mediaLocalRoots: ctx.mediaLocalRoots,
|
|
1222
1386
|
mediaReadFile: ctx.mediaReadFile,
|
|
1223
1387
|
assertDirectAdapterHandoff: ctx.assertDirectAdapterHandoff,
|
|
1224
1388
|
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
1225
1389
|
});
|
|
1226
|
-
return
|
|
1390
|
+
return jsonActionResult({
|
|
1227
1391
|
ok: true,
|
|
1228
1392
|
channel: "msteams",
|
|
1229
1393
|
action: "upload-file",
|
|
1230
1394
|
messageId: result.messageId,
|
|
1231
1395
|
conversationId: result.conversationId,
|
|
1232
1396
|
...result.pendingUploadId ? { pendingUploadId: result.pendingUploadId } : {}
|
|
1233
|
-
}, {
|
|
1234
|
-
ok: true,
|
|
1235
|
-
channel: "msteams",
|
|
1236
|
-
messageId: result.messageId,
|
|
1237
|
-
...result.pendingUploadId ? { pendingUploadId: result.pendingUploadId } : {}
|
|
1238
1397
|
});
|
|
1239
1398
|
}
|
|
1240
1399
|
});
|
|
1241
1400
|
}
|
|
1242
|
-
if (ctx.action === "edit") {
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1401
|
+
if (ctx.action === "edit" || ctx.action === "delete") {
|
|
1402
|
+
const action = ctx.action;
|
|
1403
|
+
const content = action === "edit" ? resolveActionContent(ctx.params) : "";
|
|
1404
|
+
if (action === "edit" && !content) return actionError("Edit requires content.");
|
|
1245
1405
|
return await runWithRequiredActionMessageTarget({
|
|
1246
|
-
actionLabel: "Edit",
|
|
1406
|
+
actionLabel: action === "edit" ? "Edit" : "Delete",
|
|
1247
1407
|
toolParams: ctx.params,
|
|
1248
1408
|
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1249
1409
|
run: async (target) => {
|
|
1250
1410
|
const to = await authorizeActionTarget(target.to);
|
|
1251
|
-
const
|
|
1252
|
-
|
|
1411
|
+
const runtime = await loadMSTeamsChannelRuntime();
|
|
1412
|
+
const params = {
|
|
1253
1413
|
cfg: ctx.cfg,
|
|
1254
1414
|
to,
|
|
1255
|
-
activityId: target.messageId
|
|
1415
|
+
activityId: target.messageId
|
|
1416
|
+
};
|
|
1417
|
+
return jsonMSTeamsConversationResult((action === "edit" ? await runtime.editMessageMSTeams({
|
|
1418
|
+
...params,
|
|
1256
1419
|
text: content
|
|
1257
|
-
})).conversationId);
|
|
1420
|
+
}) : await runtime.deleteMessageMSTeams(params)).conversationId);
|
|
1258
1421
|
}
|
|
1259
1422
|
});
|
|
1260
1423
|
}
|
|
1261
|
-
if (ctx.action === "delete") return await runWithRequiredActionMessageTarget({
|
|
1262
|
-
actionLabel: "Delete",
|
|
1263
|
-
toolParams: ctx.params,
|
|
1264
|
-
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1265
|
-
run: async (target) => {
|
|
1266
|
-
const to = await authorizeActionTarget(target.to);
|
|
1267
|
-
const { deleteMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1268
|
-
return jsonMSTeamsConversationResult((await deleteMessageMSTeams({
|
|
1269
|
-
cfg: ctx.cfg,
|
|
1270
|
-
to,
|
|
1271
|
-
activityId: target.messageId
|
|
1272
|
-
})).conversationId);
|
|
1273
|
-
}
|
|
1274
|
-
});
|
|
1275
1424
|
const graphActionTarget = {
|
|
1276
1425
|
toolParams: ctx.action === "search" || ctx.action === "member-info" ? {
|
|
1277
1426
|
...ctx.params,
|
|
@@ -1280,34 +1429,36 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1280
1429
|
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1281
1430
|
currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
|
|
1282
1431
|
currentChatType: ctx.toolContext?.currentChatType,
|
|
1432
|
+
currentMessageId: ctx.toolContext?.currentMessageId,
|
|
1283
1433
|
graphOnly: true
|
|
1284
1434
|
};
|
|
1285
|
-
if (ctx.action === "read"
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1435
|
+
if (ctx.action === "read" || ctx.action === "pin" || ctx.action === "reactions") {
|
|
1436
|
+
const action = ctx.action;
|
|
1437
|
+
return await runWithRequiredActionMessageTarget({
|
|
1438
|
+
actionLabel: {
|
|
1439
|
+
read: "Read",
|
|
1440
|
+
pin: "Pin",
|
|
1441
|
+
reactions: "Reactions"
|
|
1442
|
+
}[action],
|
|
1443
|
+
...graphActionTarget,
|
|
1444
|
+
allowCurrentMessageIdFallback: action === "reactions",
|
|
1445
|
+
run: async (target) => {
|
|
1446
|
+
const to = await authorizeActionTarget(target.to);
|
|
1447
|
+
const runtime = await loadMSTeamsChannelRuntime();
|
|
1448
|
+
const params = {
|
|
1449
|
+
cfg: ctx.cfg,
|
|
1450
|
+
to,
|
|
1451
|
+
messageId: target.messageId
|
|
1452
|
+
};
|
|
1453
|
+
if (action === "read") {
|
|
1454
|
+
const message = await runtime.getMessageMSTeams(params);
|
|
1455
|
+
return jsonMSTeamsOkActionResult(action, { message });
|
|
1456
|
+
}
|
|
1457
|
+
if (action === "pin") return jsonMSTeamsActionResult(action, await runtime.pinMessageMSTeams(params));
|
|
1458
|
+
return jsonMSTeamsOkActionResult(action, await runtime.listReactionsMSTeams(params));
|
|
1459
|
+
}
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1311
1462
|
if (ctx.action === "unpin") return await runWithRequiredActionPinnedMessageTarget({
|
|
1312
1463
|
actionLabel: "Unpin",
|
|
1313
1464
|
...graphActionTarget,
|
|
@@ -1336,6 +1487,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1336
1487
|
if (ctx.action === "react") return await runWithRequiredActionMessageTarget({
|
|
1337
1488
|
actionLabel: "React",
|
|
1338
1489
|
...graphActionTarget,
|
|
1490
|
+
allowCurrentMessageIdFallback: true,
|
|
1339
1491
|
run: async (target) => {
|
|
1340
1492
|
const emoji = typeof ctx.params.emoji === "string" ? ctx.params.emoji.trim() : "";
|
|
1341
1493
|
const remove = typeof ctx.params.remove === "boolean" ? ctx.params.remove : false;
|
|
@@ -1351,50 +1503,26 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1351
1503
|
}
|
|
1352
1504
|
};
|
|
1353
1505
|
const to = await authorizeActionTarget(target.to);
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
to,
|
|
1362
|
-
messageId: target.messageId,
|
|
1363
|
-
reactionType: emoji
|
|
1364
|
-
})
|
|
1365
|
-
});
|
|
1366
|
-
}
|
|
1367
|
-
const { reactMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1506
|
+
const runtime = await loadMSTeamsChannelRuntime();
|
|
1507
|
+
const result = await (remove ? runtime.unreactMessageMSTeams : runtime.reactMessageMSTeams)({
|
|
1508
|
+
cfg: ctx.cfg,
|
|
1509
|
+
to,
|
|
1510
|
+
messageId: target.messageId,
|
|
1511
|
+
reactionType: emoji
|
|
1512
|
+
});
|
|
1368
1513
|
return jsonMSTeamsActionResult("react", {
|
|
1514
|
+
...remove ? { removed: true } : {},
|
|
1369
1515
|
reactionType: emoji,
|
|
1370
|
-
...
|
|
1371
|
-
cfg: ctx.cfg,
|
|
1372
|
-
to,
|
|
1373
|
-
messageId: target.messageId,
|
|
1374
|
-
reactionType: emoji
|
|
1375
|
-
})
|
|
1516
|
+
...result
|
|
1376
1517
|
});
|
|
1377
1518
|
}
|
|
1378
1519
|
});
|
|
1379
|
-
if (ctx.action === "reactions") return await runWithRequiredActionMessageTarget({
|
|
1380
|
-
actionLabel: "Reactions",
|
|
1381
|
-
...graphActionTarget,
|
|
1382
|
-
run: async (target) => {
|
|
1383
|
-
const to = await authorizeActionTarget(target.to);
|
|
1384
|
-
const { listReactionsMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1385
|
-
return jsonMSTeamsOkActionResult("reactions", await listReactionsMSTeams({
|
|
1386
|
-
cfg: ctx.cfg,
|
|
1387
|
-
to,
|
|
1388
|
-
messageId: target.messageId
|
|
1389
|
-
}));
|
|
1390
|
-
}
|
|
1391
|
-
});
|
|
1392
1520
|
if (ctx.action === "search") return await runWithRequiredActionTarget({
|
|
1393
1521
|
actionLabel: "Search",
|
|
1394
1522
|
...graphActionTarget,
|
|
1395
1523
|
run: async (to) => {
|
|
1396
1524
|
const allowedTarget = await authorizeActionTarget(to);
|
|
1397
|
-
const query =
|
|
1525
|
+
const query = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.query);
|
|
1398
1526
|
if (!query) return actionError("Search requires a target (to) and query.");
|
|
1399
1527
|
const limit = (0, openclaw_plugin_sdk_channel_actions.readPositiveIntegerParam)(ctx.params, "limit");
|
|
1400
1528
|
const from = typeof ctx.params.from === "string" ? ctx.params.from.trim() : void 0;
|
|
@@ -1457,39 +1585,27 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1457
1585
|
channelId: graphChannelId
|
|
1458
1586
|
})).channel });
|
|
1459
1587
|
}
|
|
1460
|
-
if (ctx.action === "addParticipant") {
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1588
|
+
if (ctx.action === "addParticipant" || ctx.action === "removeParticipant") {
|
|
1589
|
+
const action = ctx.action;
|
|
1590
|
+
const userId = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.userId);
|
|
1591
|
+
if (!userId) return actionError(`${action} requires a userId.`);
|
|
1463
1592
|
return await runWithRequiredActionTarget({
|
|
1464
|
-
actionLabel:
|
|
1593
|
+
actionLabel: action,
|
|
1465
1594
|
toolParams: ctx.params,
|
|
1466
1595
|
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1467
1596
|
run: async (to) => {
|
|
1468
|
-
const role =
|
|
1469
|
-
const
|
|
1470
|
-
|
|
1471
|
-
cfg: ctx.cfg,
|
|
1472
|
-
to,
|
|
1473
|
-
userId,
|
|
1474
|
-
role
|
|
1475
|
-
}));
|
|
1476
|
-
}
|
|
1477
|
-
});
|
|
1478
|
-
}
|
|
1479
|
-
if (ctx.action === "removeParticipant") {
|
|
1480
|
-
const userId = typeof ctx.params.userId === "string" ? ctx.params.userId.trim() : "";
|
|
1481
|
-
if (!userId) return actionError("removeParticipant requires a userId.");
|
|
1482
|
-
return await runWithRequiredActionTarget({
|
|
1483
|
-
actionLabel: "removeParticipant",
|
|
1484
|
-
toolParams: ctx.params,
|
|
1485
|
-
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1486
|
-
run: async (to) => {
|
|
1487
|
-
const { removeParticipantMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1488
|
-
return jsonMSTeamsOkActionResult("removeParticipant", await removeParticipantMSTeams({
|
|
1597
|
+
const role = action === "addParticipant" ? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.role) : void 0;
|
|
1598
|
+
const runtime = await loadMSTeamsChannelRuntime();
|
|
1599
|
+
const params = {
|
|
1489
1600
|
cfg: ctx.cfg,
|
|
1490
1601
|
to,
|
|
1491
1602
|
userId
|
|
1492
|
-
}
|
|
1603
|
+
};
|
|
1604
|
+
const result = action === "addParticipant" ? await runtime.addParticipantMSTeams({
|
|
1605
|
+
...params,
|
|
1606
|
+
role
|
|
1607
|
+
}) : await runtime.removeParticipantMSTeams(params);
|
|
1608
|
+
return jsonMSTeamsOkActionResult(action, result);
|
|
1493
1609
|
}
|
|
1494
1610
|
});
|
|
1495
1611
|
}
|
|
@@ -1541,25 +1657,21 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1541
1657
|
}
|
|
1542
1658
|
return lines;
|
|
1543
1659
|
},
|
|
1544
|
-
resolveAccountSnapshot: ({ account
|
|
1660
|
+
resolveAccountSnapshot: ({ account }) => ({
|
|
1545
1661
|
accountId: account.accountId,
|
|
1546
1662
|
enabled: account.enabled,
|
|
1547
1663
|
configured: account.configured,
|
|
1548
|
-
extra: {
|
|
1549
|
-
port: runtime?.port ?? null,
|
|
1550
|
-
tokenStatus: account.tokenStatus
|
|
1551
|
-
}
|
|
1664
|
+
extra: { tokenStatus: account.tokenStatus }
|
|
1552
1665
|
})
|
|
1553
1666
|
}),
|
|
1554
1667
|
gateway: { startAccount: async (ctx) => {
|
|
1555
|
-
const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./
|
|
1556
|
-
const
|
|
1668
|
+
const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./monitor-BJ7IyH4y.cjs"));
|
|
1669
|
+
const webhookPath = ctx.cfg.channels?.msteams?.webhook?.path || "/api/messages";
|
|
1557
1670
|
const statusSink = (0, openclaw_plugin_sdk_channel_outbound.createAccountStatusSink)({
|
|
1558
1671
|
accountId: ctx.accountId,
|
|
1559
1672
|
setStatus: ctx.setStatus
|
|
1560
1673
|
});
|
|
1561
|
-
|
|
1562
|
-
ctx.log?.info(`starting provider (port ${port})`);
|
|
1674
|
+
ctx.log?.info(`starting provider (Gateway route ${webhookPath})`);
|
|
1563
1675
|
if (isMSTeamsNativeApprovalClientEnabled({
|
|
1564
1676
|
cfg: ctx.cfg,
|
|
1565
1677
|
accountId: ctx.accountId
|
|
@@ -1649,10 +1761,10 @@ Object.defineProperty(exports, "msteamsPlugin", {
|
|
|
1649
1761
|
return msteamsPlugin;
|
|
1650
1762
|
}
|
|
1651
1763
|
});
|
|
1652
|
-
Object.defineProperty(exports, "
|
|
1764
|
+
Object.defineProperty(exports, "resolveMSTeamsLegacyWebhook", {
|
|
1653
1765
|
enumerable: true,
|
|
1654
1766
|
get: function() {
|
|
1655
|
-
return
|
|
1767
|
+
return resolveMSTeamsLegacyWebhook;
|
|
1656
1768
|
}
|
|
1657
1769
|
});
|
|
1658
1770
|
Object.defineProperty(exports, "resolveMSTeamsReplyPolicy", {
|
|
@@ -1667,6 +1779,12 @@ Object.defineProperty(exports, "resolveMSTeamsRouteConfig", {
|
|
|
1667
1779
|
return resolveMSTeamsRouteConfig;
|
|
1668
1780
|
}
|
|
1669
1781
|
});
|
|
1782
|
+
Object.defineProperty(exports, "resolveMSTeamsWebhookPathIssue", {
|
|
1783
|
+
enumerable: true,
|
|
1784
|
+
get: function() {
|
|
1785
|
+
return resolveMSTeamsWebhookPathIssue;
|
|
1786
|
+
}
|
|
1787
|
+
});
|
|
1670
1788
|
Object.defineProperty(exports, "shouldHandleMSTeamsNativeApprovalRequest", {
|
|
1671
1789
|
enumerable: true,
|
|
1672
1790
|
get: function() {
|