@openclaw/msteams 2026.7.2-beta.7 → 2026.8.1-beta.3
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/adapter.runtime-8g-MOPfb.cjs +311 -0
- package/dist/api.cjs +6 -6
- package/dist/{channel-C7QxRjBW.cjs → channel-KpWENcgK.cjs} +222 -265
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/{channel.runtime-DjY6d_hd.cjs → channel.runtime-Bkzj8jZ0.cjs} +131 -88
- package/dist/{setup-surface-ByWjaXEn.cjs → channel.setup-mOFtsfYz.cjs} +91 -50
- package/dist/directory-contract-api.cjs +1 -1
- package/dist/doctor-contract-api.cjs +18 -17
- package/dist/{messenger-DTiaLTDO.cjs → messenger-IISPSOvj.cjs} +61 -46
- package/dist/{oauth-CW6jVGp8.cjs → oauth-C9So7uld.cjs} +13 -26
- package/dist/{polls-BWKNpBSg.cjs → polls-DvuJvaDG.cjs} +6 -39
- package/dist/qa-runner-api.cjs +36 -0
- package/dist/{resolve-allowlist-CEj9sABO.cjs → resolve-allowlist-CIfWUwuc.cjs} +182 -118
- package/dist/rolldown-runtime-D6vf50IK.cjs +28 -0
- package/dist/runtime-api.cjs +1 -1
- package/dist/secret-contract-api.cjs +6 -30
- package/dist/setup-plugin-api.cjs +2 -37
- package/dist/{src-B_BdEvcr.cjs → src-C127-DcQ.cjs} +439 -269
- package/dist/{sso-token-store-TKYk_Ms7.cjs → sso-token-store-ChhO1f4i.cjs} +1 -1
- package/openclaw.plugin.json +34 -8
- package/package.json +4 -5
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
require("./runtime-api.cjs");
|
|
2
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
let openclaw_plugin_sdk_account_helpers = require("openclaw/plugin-sdk/account-helpers");
|
|
2
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CIfWUwuc.cjs");
|
|
3
|
+
const require_directory_contract_api = require("./directory-contract-api.cjs");
|
|
4
|
+
const require_channel_setup = require("./channel.setup-mOFtsfYz.cjs");
|
|
6
5
|
let openclaw_plugin_sdk_channel_core = require("openclaw/plugin-sdk/channel-core");
|
|
7
6
|
let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
|
|
8
7
|
let openclaw_plugin_sdk_channel_pairing = require("openclaw/plugin-sdk/channel-pairing");
|
|
@@ -13,6 +12,7 @@ let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime
|
|
|
13
12
|
let openclaw_plugin_sdk_status_helpers = require("openclaw/plugin-sdk/status-helpers");
|
|
14
13
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
15
14
|
let typebox = require("typebox");
|
|
15
|
+
let openclaw_plugin_sdk_reply_reference = require("openclaw/plugin-sdk/reply-reference");
|
|
16
16
|
let openclaw_plugin_sdk_approval_auth_runtime = require("openclaw/plugin-sdk/approval-auth-runtime");
|
|
17
17
|
let openclaw_plugin_sdk_channel_actions = require("openclaw/plugin-sdk/channel-actions");
|
|
18
18
|
let openclaw_plugin_sdk_routing = require("openclaw/plugin-sdk/routing");
|
|
@@ -23,46 +23,6 @@ let openclaw_plugin_sdk_runtime_group_policy = require("openclaw/plugin-sdk/runt
|
|
|
23
23
|
let openclaw_plugin_sdk_text_chunking = require("openclaw/plugin-sdk/text-chunking");
|
|
24
24
|
let openclaw_plugin_sdk_channel_status = require("openclaw/plugin-sdk/channel-status");
|
|
25
25
|
let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
|
|
26
|
-
//#region extensions/msteams/src/approval-auth.ts
|
|
27
|
-
const MSTEAMS_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
28
|
-
function normalizeMSTeamsApproverId(value) {
|
|
29
|
-
const normalized = require_resolve_allowlist.normalizeMSTeamsMessagingTarget(String(value));
|
|
30
|
-
if (!normalized?.startsWith("user:")) return;
|
|
31
|
-
const id = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(normalized.slice(5));
|
|
32
|
-
if (!id) return;
|
|
33
|
-
return MSTEAMS_ID_RE.test(id) ? id : void 0;
|
|
34
|
-
}
|
|
35
|
-
function resolveMSTeamsChannelConfig(cfg) {
|
|
36
|
-
return cfg.channels?.msteams;
|
|
37
|
-
}
|
|
38
|
-
const msTeamsApprovalAuth = (0, openclaw_plugin_sdk_approval_auth_runtime.createChannelApprovalAuth)({
|
|
39
|
-
channelLabel: "Microsoft Teams",
|
|
40
|
-
resolveInputs: ({ cfg }) => {
|
|
41
|
-
const channel = resolveMSTeamsChannelConfig(cfg);
|
|
42
|
-
return {
|
|
43
|
-
allowFrom: channel?.allowFrom,
|
|
44
|
-
defaultTo: channel?.defaultTo
|
|
45
|
-
};
|
|
46
|
-
},
|
|
47
|
-
normalizeApprover: normalizeMSTeamsApproverId,
|
|
48
|
-
normalizeSenderId: (value) => {
|
|
49
|
-
const trimmed = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(value);
|
|
50
|
-
if (!trimmed) return;
|
|
51
|
-
return MSTEAMS_ID_RE.test(trimmed) ? trimmed : void 0;
|
|
52
|
-
}
|
|
53
|
-
}).approvalAuth;
|
|
54
|
-
//#endregion
|
|
55
|
-
//#region extensions/msteams/src/doctor.ts
|
|
56
|
-
const isMSTeamsMutableAllowEntry = (0, openclaw_plugin_sdk_channel_policy.buildMutableAllowEntryDetector)({
|
|
57
|
-
prefixes: ["msteams:", "user:"],
|
|
58
|
-
stableIdPattern: /^[^\s@]+$/
|
|
59
|
-
});
|
|
60
|
-
const collectMSTeamsMutableAllowlistWarnings = (0, openclaw_plugin_sdk_channel_policy.createDangerousNameMatchingMutableAllowlistWarningCollector)({
|
|
61
|
-
channel: "msteams",
|
|
62
|
-
detector: isMSTeamsMutableAllowEntry,
|
|
63
|
-
collectLists: (scope) => (0, openclaw_plugin_sdk_channel_policy.collectStandardAllowlistLists)(scope)
|
|
64
|
-
});
|
|
65
|
-
//#endregion
|
|
66
26
|
//#region extensions/msteams/src/policy.ts
|
|
67
27
|
const teamScopeKey = (teamKey) => (0, openclaw_plugin_sdk_channel_policy.scopeKey)(["team", teamKey]);
|
|
68
28
|
const channelScopeKey = (teamKey, channelKey) => (0, openclaw_plugin_sdk_channel_policy.scopeKey)(["team", teamKey], ["channel", channelKey]);
|
|
@@ -218,6 +178,115 @@ function resolveMSTeamsReplyPolicy(params) {
|
|
|
218
178
|
};
|
|
219
179
|
}
|
|
220
180
|
//#endregion
|
|
181
|
+
//#region extensions/msteams/src/action-threading.ts
|
|
182
|
+
function stripConversationPrefix(raw) {
|
|
183
|
+
const trimmed = raw.trim();
|
|
184
|
+
if (/^conversation:/i.test(trimmed)) return trimmed.slice(13).trim();
|
|
185
|
+
return trimmed;
|
|
186
|
+
}
|
|
187
|
+
/** Normalize Teams conversation targets for equality (strips `conversation:` and `;messageid=`). */
|
|
188
|
+
function normalizeMSTeamsThreadingTarget(raw) {
|
|
189
|
+
const value = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(raw);
|
|
190
|
+
if (!value) return;
|
|
191
|
+
return require_resolve_allowlist.normalizeMSTeamsConversationId(stripConversationPrefix(value));
|
|
192
|
+
}
|
|
193
|
+
function extractMSTeamsResultConversationId(value) {
|
|
194
|
+
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value)) return;
|
|
195
|
+
const direct = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(value.conversationId);
|
|
196
|
+
if (direct) return direct;
|
|
197
|
+
const receipt = (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value.receipt) ? value.receipt : void 0;
|
|
198
|
+
if (!receipt) return;
|
|
199
|
+
const candidates = [...Array.isArray(receipt.raw) ? receipt.raw : [], ...Array.isArray(receipt.parts) ? receipt.parts.map((part) => (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(part) ? part.raw : void 0) : []];
|
|
200
|
+
for (const candidate of candidates) {
|
|
201
|
+
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(candidate)) continue;
|
|
202
|
+
const conversationId = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(candidate.conversationId);
|
|
203
|
+
if (conversationId) return conversationId;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/** Recover the actual Teams conversation resolved by a successful tool send. */
|
|
207
|
+
function extractMSTeamsToolSendResult(result, _send) {
|
|
208
|
+
const details = (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(result) && (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(result.details) ? result.details : void 0;
|
|
209
|
+
const conversationId = extractMSTeamsResultConversationId(details && (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(details.result) ? details.result : void 0);
|
|
210
|
+
if (!conversationId) return null;
|
|
211
|
+
const normalizedConversationId = require_resolve_allowlist.normalizeMSTeamsConversationId(stripConversationPrefix(conversationId));
|
|
212
|
+
return normalizedConversationId ? { to: `conversation:${normalizedConversationId}` } : null;
|
|
213
|
+
}
|
|
214
|
+
function msteamsContextTargetsMatch(target, context) {
|
|
215
|
+
const normalizedTarget = normalizeMSTeamsThreadingTarget(target);
|
|
216
|
+
if (!normalizedTarget) return false;
|
|
217
|
+
const currentChannel = normalizeMSTeamsThreadingTarget(context.currentChannelId);
|
|
218
|
+
if (currentChannel && currentChannel === normalizedTarget) return true;
|
|
219
|
+
const currentMessaging = normalizeMSTeamsThreadingTarget(context.currentMessagingTarget);
|
|
220
|
+
return Boolean(currentMessaging && currentMessaging === normalizedTarget);
|
|
221
|
+
}
|
|
222
|
+
function resolveMSTeamsAutoThreadId(params) {
|
|
223
|
+
const explicitThreadId = require_resolve_allowlist.extractMSTeamsConversationMessageId(params.to);
|
|
224
|
+
if (explicitThreadId) return explicitThreadId;
|
|
225
|
+
const context = params.toolContext;
|
|
226
|
+
if (!context?.currentChannelId && !context?.currentMessagingTarget) return;
|
|
227
|
+
if (!msteamsContextTargetsMatch(params.to, context)) return;
|
|
228
|
+
const graphTarget = context.currentGraphChannelId ?? context.currentMessagingTarget;
|
|
229
|
+
const { team, channel } = graphTarget ? require_resolve_allowlist.parseMSTeamsTeamChannelInput(graphTarget) : {
|
|
230
|
+
team: void 0,
|
|
231
|
+
channel: void 0
|
|
232
|
+
};
|
|
233
|
+
const routeConfig = resolveMSTeamsRouteConfig({
|
|
234
|
+
cfg: params.cfg,
|
|
235
|
+
teamId: team,
|
|
236
|
+
conversationId: channel,
|
|
237
|
+
allowNameMatching: false
|
|
238
|
+
});
|
|
239
|
+
const { replyStyle } = resolveMSTeamsReplyPolicy({
|
|
240
|
+
isDirectMessage: false,
|
|
241
|
+
globalConfig: params.cfg,
|
|
242
|
+
teamConfig: routeConfig.teamConfig,
|
|
243
|
+
channelConfig: routeConfig.channelConfig
|
|
244
|
+
});
|
|
245
|
+
if (replyStyle === "top-level") return;
|
|
246
|
+
if (!context.currentThreadTs) return;
|
|
247
|
+
if (context.replyToMode !== "all" && !(0, openclaw_plugin_sdk_reply_reference.isSingleUseReplyToMode)(context.replyToMode ?? "off")) return;
|
|
248
|
+
if ((0, openclaw_plugin_sdk_reply_reference.isSingleUseReplyToMode)(context.replyToMode ?? "off") && context.hasRepliedRef?.value) return;
|
|
249
|
+
return context.currentThreadTs;
|
|
250
|
+
}
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region extensions/msteams/src/approval-auth.ts
|
|
253
|
+
const MSTEAMS_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
254
|
+
function normalizeMSTeamsApproverId(value) {
|
|
255
|
+
const normalized = require_resolve_allowlist.normalizeMSTeamsMessagingTarget(String(value));
|
|
256
|
+
const id = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(normalized?.startsWith("user:") ? normalized.slice(5) : normalized);
|
|
257
|
+
return id && MSTEAMS_ID_RE.test(id) ? id : void 0;
|
|
258
|
+
}
|
|
259
|
+
function resolveMSTeamsChannelConfig(cfg) {
|
|
260
|
+
return cfg.channels?.msteams;
|
|
261
|
+
}
|
|
262
|
+
const msTeamsApprovalAuth = (0, openclaw_plugin_sdk_approval_auth_runtime.createChannelApprovalAuth)({
|
|
263
|
+
channelLabel: "Microsoft Teams",
|
|
264
|
+
resolveInputs: ({ cfg }) => {
|
|
265
|
+
const channel = resolveMSTeamsChannelConfig(cfg);
|
|
266
|
+
return {
|
|
267
|
+
allowFrom: channel?.allowFrom,
|
|
268
|
+
defaultTo: channel?.defaultTo
|
|
269
|
+
};
|
|
270
|
+
},
|
|
271
|
+
normalizeApprover: normalizeMSTeamsApproverId,
|
|
272
|
+
normalizeSenderId: (value) => {
|
|
273
|
+
const trimmed = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(value);
|
|
274
|
+
if (!trimmed) return;
|
|
275
|
+
return MSTEAMS_ID_RE.test(trimmed) ? trimmed : void 0;
|
|
276
|
+
}
|
|
277
|
+
}).approvalAuth;
|
|
278
|
+
//#endregion
|
|
279
|
+
//#region extensions/msteams/src/doctor.ts
|
|
280
|
+
const isMSTeamsMutableAllowEntry = (0, openclaw_plugin_sdk_channel_policy.buildMutableAllowEntryDetector)({
|
|
281
|
+
prefixes: ["msteams:", "user:"],
|
|
282
|
+
stableIdPattern: /^[^\s@]+$/
|
|
283
|
+
});
|
|
284
|
+
const collectMSTeamsMutableAllowlistWarnings = (0, openclaw_plugin_sdk_channel_policy.createDangerousNameMatchingMutableAllowlistWarningCollector)({
|
|
285
|
+
channel: "msteams",
|
|
286
|
+
detector: isMSTeamsMutableAllowEntry,
|
|
287
|
+
collectLists: (scope) => (0, openclaw_plugin_sdk_channel_policy.collectStandardAllowlistLists)(scope)
|
|
288
|
+
});
|
|
289
|
+
//#endregion
|
|
221
290
|
//#region extensions/msteams/src/presentation.ts
|
|
222
291
|
const MSTEAMS_PRESENTATION_CAPABILITIES = {
|
|
223
292
|
supported: true,
|
|
@@ -434,8 +503,8 @@ async function resolveAllowedChannelTarget(cfg, target) {
|
|
|
434
503
|
allowNameMatching: (0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(teams)
|
|
435
504
|
});
|
|
436
505
|
const stableTarget = await resolveStableChannelTarget(cfg, target);
|
|
506
|
+
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\".");
|
|
437
507
|
if (directRoute.allowed) return stableTarget;
|
|
438
|
-
if (!directRoute.allowlistConfigured) return groupPolicy === "open" ? stableTarget : void 0;
|
|
439
508
|
if (!stableTarget || !teams?.teams) return;
|
|
440
509
|
const [stableTeamId, stableChannelId] = stableTarget.split("/", 2);
|
|
441
510
|
if (!stableTeamId || !stableChannelId) return;
|
|
@@ -545,20 +614,32 @@ function resolveMSTeamsRouteSessionKey(params) {
|
|
|
545
614
|
}
|
|
546
615
|
//#endregion
|
|
547
616
|
//#region extensions/msteams/src/session-route.ts
|
|
617
|
+
function inferMSTeamsTargetChatType(raw) {
|
|
618
|
+
const target = (0, openclaw_plugin_sdk_channel_core.stripChannelTargetPrefix)(raw, "msteams", "teams");
|
|
619
|
+
if (!target) return;
|
|
620
|
+
const lower = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(target);
|
|
621
|
+
const rawId = (0, openclaw_plugin_sdk_channel_core.stripTargetKindPrefix)(target);
|
|
622
|
+
if (!rawId) return;
|
|
623
|
+
const conversationId = require_resolve_allowlist.normalizeMSTeamsConversationId(rawId);
|
|
624
|
+
if (lower.startsWith("user:") || /^[0-9a-f-]{16,}$/i.test(conversationId)) return "direct";
|
|
625
|
+
if (/@thread\.tacv2/i.test(conversationId)) return "channel";
|
|
626
|
+
return /^19:.+@thread\.(?:skype|v2)$/i.test(conversationId) ? "group" : void 0;
|
|
627
|
+
}
|
|
548
628
|
function resolveMSTeamsOutboundSessionRoute(params) {
|
|
549
629
|
const trimmed = (0, openclaw_plugin_sdk_channel_core.stripChannelTargetPrefix)(params.target, "msteams", "teams");
|
|
550
630
|
if (!trimmed) return null;
|
|
551
|
-
const
|
|
631
|
+
const resolvedKind = params.resolvedTarget?.kind;
|
|
632
|
+
const targetChatType = inferMSTeamsTargetChatType(trimmed);
|
|
633
|
+
const isUser = resolvedKind === "user" || targetChatType === "direct";
|
|
552
634
|
const rawId = (0, openclaw_plugin_sdk_channel_core.stripTargetKindPrefix)(trimmed);
|
|
553
635
|
if (!rawId) return null;
|
|
554
636
|
const conversationId = require_resolve_allowlist.normalizeMSTeamsConversationId(rawId);
|
|
555
|
-
const isChannel = !isUser &&
|
|
637
|
+
const isChannel = !isUser && targetChatType === "channel";
|
|
556
638
|
const embeddedThreadId = require_resolve_allowlist.extractMSTeamsConversationMessageId(rawId);
|
|
557
639
|
const explicitThreadId = params.threadId ?? params.replyToId;
|
|
558
640
|
const channelThreadId = embeddedThreadId ?? (explicitThreadId !== void 0 && explicitThreadId !== null ? String(explicitThreadId) : void 0);
|
|
559
|
-
const resolvedKind = params.resolvedTarget?.kind;
|
|
560
641
|
const isCanonicalUserId = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(conversationId);
|
|
561
|
-
const recipientSessionExact =
|
|
642
|
+
const recipientSessionExact = isUser && isCanonicalUserId || (isChannel ? channelThreadId !== void 0 : resolvedKind === "group");
|
|
562
643
|
const route = (0, openclaw_plugin_sdk_channel_core.buildChannelOutboundSessionRoute)({
|
|
563
644
|
cfg: params.cfg,
|
|
564
645
|
agentId: params.agentId,
|
|
@@ -604,7 +685,13 @@ const collectMSTeamsSecurityWarnings = (0, openclaw_plugin_sdk_channel_policy.cr
|
|
|
604
685
|
resolveGroupPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy,
|
|
605
686
|
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."] : []
|
|
606
687
|
});
|
|
607
|
-
const
|
|
688
|
+
const collectMSTeamsSecurityFindings = openclaw_plugin_sdk_channel_policy.createConditionalWarningCollector.findings({
|
|
689
|
+
collectWarnings: collectMSTeamsSecurityWarnings,
|
|
690
|
+
checkId: "channels.msteams.groups.open",
|
|
691
|
+
severity: "critical",
|
|
692
|
+
title: "MS Teams security warning"
|
|
693
|
+
});
|
|
694
|
+
const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-Bkzj8jZ0.cjs")), "msTeamsChannelRuntime");
|
|
608
695
|
function jsonActionResult(data) {
|
|
609
696
|
return {
|
|
610
697
|
content: [{
|
|
@@ -700,7 +787,7 @@ function resolveActionContent(params) {
|
|
|
700
787
|
return typeof params.text === "string" ? params.text : typeof params.content === "string" ? params.content : typeof params.message === "string" ? params.message : "";
|
|
701
788
|
}
|
|
702
789
|
function readOptionalTrimmedString(params, key) {
|
|
703
|
-
return
|
|
790
|
+
return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(params[key]);
|
|
704
791
|
}
|
|
705
792
|
function resolveActionUploadFilePath(params) {
|
|
706
793
|
for (const key of [
|
|
@@ -712,67 +799,35 @@ function resolveActionUploadFilePath(params) {
|
|
|
712
799
|
if (value.trim()) return value;
|
|
713
800
|
}
|
|
714
801
|
}
|
|
715
|
-
function
|
|
716
|
-
|
|
802
|
+
function resolveMSTeamsActionTarget(params) {
|
|
803
|
+
return params.graphOnly ? resolveGraphActionTarget(params.toolParams, params.currentChannelId, params.currentGraphChannelId, params.currentChatType) : resolveActionTarget(params.toolParams, params.currentChannelId);
|
|
804
|
+
}
|
|
805
|
+
async function runWithRequiredActionTarget(params) {
|
|
806
|
+
const to = resolveMSTeamsActionTarget(params);
|
|
717
807
|
if (!to) return actionError(`${params.actionLabel} requires a target (to).`);
|
|
718
|
-
return to;
|
|
808
|
+
return await params.run(to);
|
|
719
809
|
}
|
|
720
|
-
function
|
|
721
|
-
const to =
|
|
810
|
+
async function runWithRequiredActionMessageTarget(params) {
|
|
811
|
+
const to = resolveMSTeamsActionTarget(params);
|
|
722
812
|
const messageId = resolveActionMessageId(params.toolParams);
|
|
723
813
|
if (!to || !messageId) return actionError(`${params.actionLabel} requires a target (to) and messageId.`);
|
|
724
|
-
return {
|
|
814
|
+
return await params.run({
|
|
725
815
|
to,
|
|
726
816
|
messageId
|
|
727
|
-
};
|
|
817
|
+
});
|
|
728
818
|
}
|
|
729
|
-
function
|
|
730
|
-
const to =
|
|
819
|
+
async function runWithRequiredActionPinnedMessageTarget(params) {
|
|
820
|
+
const to = resolveMSTeamsActionTarget(params);
|
|
731
821
|
const pinnedMessageId = resolveActionPinnedMessageId(params.toolParams);
|
|
732
822
|
if (!to || !pinnedMessageId) return actionError(`${params.actionLabel} requires a target (to) and pinnedMessageId.`);
|
|
733
|
-
return {
|
|
823
|
+
return await params.run({
|
|
734
824
|
to,
|
|
735
825
|
pinnedMessageId
|
|
736
|
-
};
|
|
737
|
-
}
|
|
738
|
-
async function runWithRequiredActionTarget(params) {
|
|
739
|
-
const to = resolveRequiredActionTarget({
|
|
740
|
-
actionLabel: params.actionLabel,
|
|
741
|
-
toolParams: params.toolParams,
|
|
742
|
-
currentChannelId: params.currentChannelId,
|
|
743
|
-
currentGraphChannelId: params.currentGraphChannelId,
|
|
744
|
-
currentChatType: params.currentChatType,
|
|
745
|
-
graphOnly: params.graphOnly
|
|
746
826
|
});
|
|
747
|
-
if (typeof to !== "string") return to;
|
|
748
|
-
return await params.run(to);
|
|
749
|
-
}
|
|
750
|
-
async function runWithRequiredActionMessageTarget(params) {
|
|
751
|
-
const target = resolveRequiredActionMessageTarget({
|
|
752
|
-
actionLabel: params.actionLabel,
|
|
753
|
-
toolParams: params.toolParams,
|
|
754
|
-
currentChannelId: params.currentChannelId,
|
|
755
|
-
currentGraphChannelId: params.currentGraphChannelId,
|
|
756
|
-
currentChatType: params.currentChatType,
|
|
757
|
-
graphOnly: params.graphOnly
|
|
758
|
-
});
|
|
759
|
-
if ("isError" in target) return target;
|
|
760
|
-
return await params.run(target);
|
|
761
|
-
}
|
|
762
|
-
async function runWithRequiredActionPinnedMessageTarget(params) {
|
|
763
|
-
const target = resolveRequiredActionPinnedMessageTarget({
|
|
764
|
-
actionLabel: params.actionLabel,
|
|
765
|
-
toolParams: params.toolParams,
|
|
766
|
-
currentChannelId: params.currentChannelId,
|
|
767
|
-
currentGraphChannelId: params.currentGraphChannelId,
|
|
768
|
-
currentChatType: params.currentChatType,
|
|
769
|
-
graphOnly: params.graphOnly
|
|
770
|
-
});
|
|
771
|
-
if ("isError" in target) return target;
|
|
772
|
-
return await params.run(target);
|
|
773
827
|
}
|
|
774
828
|
function describeMSTeamsMessageTool({ cfg }) {
|
|
775
|
-
const
|
|
829
|
+
const account = require_channel_setup.resolveMSTeamsAccount(cfg);
|
|
830
|
+
const enabled = account.enabled && account.configured && account.tokenStatus === "available";
|
|
776
831
|
return {
|
|
777
832
|
actions: enabled ? [
|
|
778
833
|
"upload-file",
|
|
@@ -842,38 +897,13 @@ const msteamsMessageAdapter = (0, openclaw_plugin_sdk_channel_outbound.createCha
|
|
|
842
897
|
});
|
|
843
898
|
const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlugin)({
|
|
844
899
|
base: {
|
|
845
|
-
|
|
846
|
-
meta: {
|
|
847
|
-
...require_setup_surface.msteamsMeta,
|
|
848
|
-
aliases: [...require_setup_surface.msteamsMeta.aliases]
|
|
849
|
-
},
|
|
850
|
-
setupWizard: require_setup_surface.msteamsSetupWizard,
|
|
851
|
-
capabilities: {
|
|
852
|
-
chatTypes: [
|
|
853
|
-
"direct",
|
|
854
|
-
"channel",
|
|
855
|
-
"thread"
|
|
856
|
-
],
|
|
857
|
-
polls: true,
|
|
858
|
-
threads: true,
|
|
859
|
-
media: true
|
|
860
|
-
},
|
|
900
|
+
...require_channel_setup.msteamsSetupPlugin,
|
|
861
901
|
streaming: { blockStreamingCoalesceDefaults: {
|
|
862
902
|
minChars: 1500,
|
|
863
903
|
idleMs: 1e3
|
|
864
904
|
} },
|
|
865
905
|
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."] },
|
|
866
906
|
groups: { resolveToolPolicy: resolveMSTeamsGroupToolPolicy },
|
|
867
|
-
reload: { configPrefixes: ["channels.msteams"] },
|
|
868
|
-
configSchema: require_config_schema.MSTeamsChannelConfigSchema,
|
|
869
|
-
config: {
|
|
870
|
-
...require_setup_surface.msteamsConfigAdapter,
|
|
871
|
-
isConfigured: (_account, cfg) => Boolean(require_resolve_allowlist.resolveMSTeamsCredentials(cfg.channels?.msteams)),
|
|
872
|
-
describeAccount: (account) => (0, openclaw_plugin_sdk_account_helpers.describeAccountSnapshot)({
|
|
873
|
-
account,
|
|
874
|
-
configured: account.configured
|
|
875
|
-
})
|
|
876
|
-
},
|
|
877
907
|
approvalCapability: msTeamsApprovalAuth,
|
|
878
908
|
doctor: {
|
|
879
909
|
dmAllowFromMode: "topOnly",
|
|
@@ -882,12 +912,11 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
882
912
|
warnOnEmptyGroupSenderAllowlist: true,
|
|
883
913
|
collectMutableAllowlistWarnings: collectMSTeamsMutableAllowlistWarnings
|
|
884
914
|
},
|
|
885
|
-
setup: require_setup_surface.msteamsSetupAdapter,
|
|
886
|
-
setupContract: require_setup_surface.msteamsSetupContract,
|
|
887
915
|
messaging: {
|
|
888
916
|
targetPrefixes: ["msteams", "teams"],
|
|
889
917
|
directTargetStyle: "user-prefixed",
|
|
890
918
|
normalizeTarget: require_resolve_allowlist.normalizeMSTeamsMessagingTarget,
|
|
919
|
+
inferTargetChatType: ({ to }) => inferMSTeamsTargetChatType(to),
|
|
891
920
|
resolveOutboundSessionRoute: (params) => resolveMSTeamsOutboundSessionRoute(params),
|
|
892
921
|
targetResolver: {
|
|
893
922
|
looksLikeId: (raw) => require_resolve_allowlist.looksLikeMSTeamsTargetId(raw),
|
|
@@ -896,34 +925,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
896
925
|
},
|
|
897
926
|
message: msteamsMessageAdapter,
|
|
898
927
|
directory: (0, openclaw_plugin_sdk_directory_runtime.createChannelDirectoryAdapter)({
|
|
899
|
-
|
|
900
|
-
const creds = require_resolve_allowlist.resolveMSTeamsCredentials(cfg.channels?.msteams);
|
|
901
|
-
if (!creds) return null;
|
|
902
|
-
return {
|
|
903
|
-
kind: "user",
|
|
904
|
-
id: creds.appId,
|
|
905
|
-
name: creds.appId
|
|
906
|
-
};
|
|
907
|
-
},
|
|
908
|
-
listPeers: async ({ cfg, query, limit }) => (0, openclaw_plugin_sdk_directory_runtime.listDirectoryEntriesFromSources)({
|
|
909
|
-
kind: "user",
|
|
910
|
-
sources: [cfg.channels?.msteams?.allowFrom ?? [], Object.keys(cfg.channels?.msteams?.dms ?? {})],
|
|
911
|
-
query,
|
|
912
|
-
limit,
|
|
913
|
-
normalizeId: (raw) => {
|
|
914
|
-
const normalized = require_resolve_allowlist.normalizeMSTeamsMessagingTarget(raw) ?? raw;
|
|
915
|
-
const lowered = normalized.toLowerCase();
|
|
916
|
-
if (lowered.startsWith("user:") || lowered.startsWith("conversation:")) return normalized;
|
|
917
|
-
return `user:${normalized}`;
|
|
918
|
-
}
|
|
919
|
-
}),
|
|
920
|
-
listGroups: async ({ cfg, query, limit }) => (0, openclaw_plugin_sdk_directory_runtime.listDirectoryEntriesFromSources)({
|
|
921
|
-
kind: "group",
|
|
922
|
-
sources: [Object.values(cfg.channels?.msteams?.teams ?? {}).flatMap((team) => Object.keys(team.channels ?? {}))],
|
|
923
|
-
query,
|
|
924
|
-
limit,
|
|
925
|
-
normalizeId: (raw) => `conversation:${raw.replace(/^conversation:/i, "").trim()}`
|
|
926
|
-
}),
|
|
928
|
+
...require_directory_contract_api.msteamsDirectoryContractPlugin.directory,
|
|
927
929
|
...(0, openclaw_plugin_sdk_directory_runtime.createRuntimeDirectoryLiveAdapter)({
|
|
928
930
|
getRuntime: loadMSTeamsChannelRuntime,
|
|
929
931
|
listPeersLive: (runtime) => runtime.listMSTeamsDirectoryPeersLive,
|
|
@@ -1038,13 +1040,20 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1038
1040
|
return results;
|
|
1039
1041
|
} },
|
|
1040
1042
|
actions: {
|
|
1043
|
+
providerOwnedReadGates: true,
|
|
1041
1044
|
describeMessageTool: describeMSTeamsMessageTool,
|
|
1045
|
+
extractToolSendResult: ({ result, send }) => extractMSTeamsToolSendResult(result, send),
|
|
1042
1046
|
requiresTrustedRequesterSender: ({ action, toolContext }) => (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(toolContext?.currentChannelProvider)?.toLowerCase() === "msteams" && MSTEAMS_GROUP_MANAGEMENT_ACTIONS.has(action),
|
|
1043
1047
|
handleAction: async (ctx) => {
|
|
1044
1048
|
if (MSTEAMS_GROUP_MANAGEMENT_ACTIONS.has(ctx.action)) {
|
|
1045
1049
|
const authError = requireMSTeamsGroupManagementAuthorization(ctx);
|
|
1046
1050
|
if (authError) return authError;
|
|
1047
1051
|
}
|
|
1052
|
+
const authorizeActionTarget = (target) => assertMSTeamsReadTargetAllowed({
|
|
1053
|
+
cfg: ctx.cfg,
|
|
1054
|
+
ctx,
|
|
1055
|
+
target
|
|
1056
|
+
});
|
|
1048
1057
|
const presentation = ctx.action === "send" ? (0, openclaw_plugin_sdk_interactive_runtime.normalizeMessagePresentation)(ctx.params.presentation) : void 0;
|
|
1049
1058
|
if (ctx.action === "send" && presentation) {
|
|
1050
1059
|
const card = buildMSTeamsPresentationCard({
|
|
@@ -1089,6 +1098,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1089
1098
|
text: resolveActionContent(ctx.params),
|
|
1090
1099
|
mediaUrl,
|
|
1091
1100
|
filename: readOptionalTrimmedString(ctx.params, "filename") ?? readOptionalTrimmedString(ctx.params, "title"),
|
|
1101
|
+
mediaAccess: ctx.mediaAccess,
|
|
1092
1102
|
mediaLocalRoots: ctx.mediaLocalRoots,
|
|
1093
1103
|
mediaReadFile: ctx.mediaReadFile
|
|
1094
1104
|
});
|
|
@@ -1116,11 +1126,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1116
1126
|
toolParams: ctx.params,
|
|
1117
1127
|
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1118
1128
|
run: async (target) => {
|
|
1119
|
-
const to = await
|
|
1120
|
-
cfg: ctx.cfg,
|
|
1121
|
-
ctx,
|
|
1122
|
-
target: target.to
|
|
1123
|
-
});
|
|
1129
|
+
const to = await authorizeActionTarget(target.to);
|
|
1124
1130
|
const { editMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1125
1131
|
return jsonMSTeamsConversationResult((await editMessageMSTeams({
|
|
1126
1132
|
cfg: ctx.cfg,
|
|
@@ -1136,11 +1142,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1136
1142
|
toolParams: ctx.params,
|
|
1137
1143
|
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1138
1144
|
run: async (target) => {
|
|
1139
|
-
const to = await
|
|
1140
|
-
cfg: ctx.cfg,
|
|
1141
|
-
ctx,
|
|
1142
|
-
target: target.to
|
|
1143
|
-
});
|
|
1145
|
+
const to = await authorizeActionTarget(target.to);
|
|
1144
1146
|
const { deleteMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1145
1147
|
return jsonMSTeamsConversationResult((await deleteMessageMSTeams({
|
|
1146
1148
|
cfg: ctx.cfg,
|
|
@@ -1149,19 +1151,18 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1149
1151
|
})).conversationId);
|
|
1150
1152
|
}
|
|
1151
1153
|
});
|
|
1152
|
-
|
|
1153
|
-
actionLabel: "Read",
|
|
1154
|
+
const graphActionTarget = {
|
|
1154
1155
|
toolParams: ctx.params,
|
|
1155
1156
|
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1156
1157
|
currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
|
|
1157
1158
|
currentChatType: ctx.toolContext?.currentChatType,
|
|
1158
|
-
graphOnly: true
|
|
1159
|
+
graphOnly: true
|
|
1160
|
+
};
|
|
1161
|
+
if (ctx.action === "read") return await runWithRequiredActionMessageTarget({
|
|
1162
|
+
actionLabel: "Read",
|
|
1163
|
+
...graphActionTarget,
|
|
1159
1164
|
run: async (target) => {
|
|
1160
|
-
const to = await
|
|
1161
|
-
cfg: ctx.cfg,
|
|
1162
|
-
ctx,
|
|
1163
|
-
target: target.to
|
|
1164
|
-
});
|
|
1165
|
+
const to = await authorizeActionTarget(target.to);
|
|
1165
1166
|
const { getMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1166
1167
|
return jsonMSTeamsOkActionResult("read", { message: await getMessageMSTeams({
|
|
1167
1168
|
cfg: ctx.cfg,
|
|
@@ -1172,17 +1173,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1172
1173
|
});
|
|
1173
1174
|
if (ctx.action === "pin") return await runWithRequiredActionMessageTarget({
|
|
1174
1175
|
actionLabel: "Pin",
|
|
1175
|
-
|
|
1176
|
-
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1177
|
-
currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
|
|
1178
|
-
currentChatType: ctx.toolContext?.currentChatType,
|
|
1179
|
-
graphOnly: true,
|
|
1176
|
+
...graphActionTarget,
|
|
1180
1177
|
run: async (target) => {
|
|
1181
|
-
const to = await
|
|
1182
|
-
cfg: ctx.cfg,
|
|
1183
|
-
ctx,
|
|
1184
|
-
target: target.to
|
|
1185
|
-
});
|
|
1178
|
+
const to = await authorizeActionTarget(target.to);
|
|
1186
1179
|
const { pinMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1187
1180
|
return jsonMSTeamsActionResult("pin", await pinMessageMSTeams({
|
|
1188
1181
|
cfg: ctx.cfg,
|
|
@@ -1193,17 +1186,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1193
1186
|
});
|
|
1194
1187
|
if (ctx.action === "unpin") return await runWithRequiredActionPinnedMessageTarget({
|
|
1195
1188
|
actionLabel: "Unpin",
|
|
1196
|
-
|
|
1197
|
-
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1198
|
-
currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
|
|
1199
|
-
currentChatType: ctx.toolContext?.currentChatType,
|
|
1200
|
-
graphOnly: true,
|
|
1189
|
+
...graphActionTarget,
|
|
1201
1190
|
run: async (target) => {
|
|
1202
|
-
const to = await
|
|
1203
|
-
cfg: ctx.cfg,
|
|
1204
|
-
ctx,
|
|
1205
|
-
target: target.to
|
|
1206
|
-
});
|
|
1191
|
+
const to = await authorizeActionTarget(target.to);
|
|
1207
1192
|
const { unpinMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1208
1193
|
return jsonMSTeamsActionResult("unpin", await unpinMessageMSTeams({
|
|
1209
1194
|
cfg: ctx.cfg,
|
|
@@ -1214,17 +1199,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1214
1199
|
});
|
|
1215
1200
|
if (ctx.action === "list-pins") return await runWithRequiredActionTarget({
|
|
1216
1201
|
actionLabel: "List-pins",
|
|
1217
|
-
|
|
1218
|
-
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1219
|
-
currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
|
|
1220
|
-
currentChatType: ctx.toolContext?.currentChatType,
|
|
1221
|
-
graphOnly: true,
|
|
1202
|
+
...graphActionTarget,
|
|
1222
1203
|
run: async (to) => {
|
|
1223
|
-
const allowedTarget = await
|
|
1224
|
-
cfg: ctx.cfg,
|
|
1225
|
-
ctx,
|
|
1226
|
-
target: to
|
|
1227
|
-
});
|
|
1204
|
+
const allowedTarget = await authorizeActionTarget(to);
|
|
1228
1205
|
const { listPinsMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1229
1206
|
return jsonMSTeamsOkActionResult("list-pins", await listPinsMSTeams({
|
|
1230
1207
|
cfg: ctx.cfg,
|
|
@@ -1234,11 +1211,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1234
1211
|
});
|
|
1235
1212
|
if (ctx.action === "react") return await runWithRequiredActionMessageTarget({
|
|
1236
1213
|
actionLabel: "React",
|
|
1237
|
-
|
|
1238
|
-
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1239
|
-
currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
|
|
1240
|
-
currentChatType: ctx.toolContext?.currentChatType,
|
|
1241
|
-
graphOnly: true,
|
|
1214
|
+
...graphActionTarget,
|
|
1242
1215
|
run: async (target) => {
|
|
1243
1216
|
const emoji = typeof ctx.params.emoji === "string" ? ctx.params.emoji.trim() : "";
|
|
1244
1217
|
const remove = typeof ctx.params.remove === "boolean" ? ctx.params.remove : false;
|
|
@@ -1253,11 +1226,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1253
1226
|
validTypes: [...MSTEAMS_REACTION_TYPES]
|
|
1254
1227
|
}
|
|
1255
1228
|
};
|
|
1256
|
-
const to = await
|
|
1257
|
-
cfg: ctx.cfg,
|
|
1258
|
-
ctx,
|
|
1259
|
-
target: target.to
|
|
1260
|
-
});
|
|
1229
|
+
const to = await authorizeActionTarget(target.to);
|
|
1261
1230
|
if (remove) {
|
|
1262
1231
|
const { unreactMessageMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1263
1232
|
return jsonMSTeamsActionResult("react", {
|
|
@@ -1285,17 +1254,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1285
1254
|
});
|
|
1286
1255
|
if (ctx.action === "reactions") return await runWithRequiredActionMessageTarget({
|
|
1287
1256
|
actionLabel: "Reactions",
|
|
1288
|
-
|
|
1289
|
-
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1290
|
-
currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
|
|
1291
|
-
currentChatType: ctx.toolContext?.currentChatType,
|
|
1292
|
-
graphOnly: true,
|
|
1257
|
+
...graphActionTarget,
|
|
1293
1258
|
run: async (target) => {
|
|
1294
|
-
const to = await
|
|
1295
|
-
cfg: ctx.cfg,
|
|
1296
|
-
ctx,
|
|
1297
|
-
target: target.to
|
|
1298
|
-
});
|
|
1259
|
+
const to = await authorizeActionTarget(target.to);
|
|
1299
1260
|
const { listReactionsMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1300
1261
|
return jsonMSTeamsOkActionResult("reactions", await listReactionsMSTeams({
|
|
1301
1262
|
cfg: ctx.cfg,
|
|
@@ -1306,17 +1267,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1306
1267
|
});
|
|
1307
1268
|
if (ctx.action === "search") return await runWithRequiredActionTarget({
|
|
1308
1269
|
actionLabel: "Search",
|
|
1309
|
-
|
|
1310
|
-
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1311
|
-
currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
|
|
1312
|
-
currentChatType: ctx.toolContext?.currentChatType,
|
|
1313
|
-
graphOnly: true,
|
|
1270
|
+
...graphActionTarget,
|
|
1314
1271
|
run: async (to) => {
|
|
1315
|
-
const allowedTarget = await
|
|
1316
|
-
cfg: ctx.cfg,
|
|
1317
|
-
ctx,
|
|
1318
|
-
target: to
|
|
1319
|
-
});
|
|
1272
|
+
const allowedTarget = await authorizeActionTarget(to);
|
|
1320
1273
|
const query = resolveActionQuery(ctx.params);
|
|
1321
1274
|
if (!query) return actionError("Search requires a target (to) and query.");
|
|
1322
1275
|
const limit = typeof ctx.params.limit === "number" ? ctx.params.limit : void 0;
|
|
@@ -1336,17 +1289,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1336
1289
|
if (!userId) return actionError("member-info requires a userId.");
|
|
1337
1290
|
return await runWithRequiredActionTarget({
|
|
1338
1291
|
actionLabel: "member-info",
|
|
1339
|
-
|
|
1340
|
-
currentChannelId: ctx.toolContext?.currentChannelId,
|
|
1341
|
-
currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
|
|
1342
|
-
currentChatType: ctx.toolContext?.currentChatType,
|
|
1343
|
-
graphOnly: true,
|
|
1292
|
+
...graphActionTarget,
|
|
1344
1293
|
run: async (target) => {
|
|
1345
|
-
const to = await
|
|
1346
|
-
cfg: ctx.cfg,
|
|
1347
|
-
ctx,
|
|
1348
|
-
target
|
|
1349
|
-
});
|
|
1294
|
+
const to = await authorizeActionTarget(target);
|
|
1350
1295
|
const currentRequesterId = isCurrentMSTeamsReadTarget({
|
|
1351
1296
|
ctx,
|
|
1352
1297
|
target: to
|
|
@@ -1379,11 +1324,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1379
1324
|
const teamId = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.teamId) ?? "";
|
|
1380
1325
|
const channelId = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.channelId) ?? "";
|
|
1381
1326
|
if (!teamId || !channelId) return actionError("channel-info requires teamId and channelId.");
|
|
1382
|
-
const [graphTeamId, graphChannelId] = (await
|
|
1383
|
-
cfg: ctx.cfg,
|
|
1384
|
-
ctx,
|
|
1385
|
-
target: `${teamId}/${channelId}`
|
|
1386
|
-
})).split("/", 2);
|
|
1327
|
+
const [graphTeamId, graphChannelId] = (await authorizeActionTarget(`${teamId}/${channelId}`)).split("/", 2);
|
|
1387
1328
|
if (!graphTeamId || !graphChannelId) throw new Error("Authorized Microsoft Teams channel target is invalid.");
|
|
1388
1329
|
const { getChannelInfoMSTeams } = await loadMSTeamsChannelRuntime();
|
|
1389
1330
|
return jsonMSTeamsOkActionResult("channel-info", { channelInfo: (await getChannelInfoMSTeams({
|
|
@@ -1480,25 +1421,30 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1480
1421
|
accountId: account.accountId,
|
|
1481
1422
|
enabled: account.enabled,
|
|
1482
1423
|
configured: account.configured,
|
|
1483
|
-
extra: {
|
|
1424
|
+
extra: {
|
|
1425
|
+
port: runtime?.port ?? null,
|
|
1426
|
+
tokenStatus: account.tokenStatus
|
|
1427
|
+
}
|
|
1484
1428
|
})
|
|
1485
1429
|
}),
|
|
1486
1430
|
gateway: { startAccount: async (ctx) => {
|
|
1487
|
-
const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./src-
|
|
1431
|
+
const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./src-C127-DcQ.cjs"));
|
|
1488
1432
|
const port = ctx.cfg.channels?.msteams?.webhook?.port ?? 3978;
|
|
1489
|
-
|
|
1433
|
+
const statusSink = (0, openclaw_plugin_sdk_channel_outbound.createAccountStatusSink)({
|
|
1490
1434
|
accountId: ctx.accountId,
|
|
1491
|
-
|
|
1435
|
+
setStatus: ctx.setStatus
|
|
1492
1436
|
});
|
|
1437
|
+
statusSink({ port });
|
|
1493
1438
|
ctx.log?.info(`starting provider (port ${port})`);
|
|
1494
1439
|
return monitorMSTeamsProvider({
|
|
1495
1440
|
cfg: ctx.cfg,
|
|
1496
1441
|
runtime: ctx.runtime,
|
|
1497
|
-
abortSignal: ctx.abortSignal
|
|
1442
|
+
abortSignal: ctx.abortSignal,
|
|
1443
|
+
statusSink
|
|
1498
1444
|
});
|
|
1499
1445
|
} }
|
|
1500
1446
|
},
|
|
1501
|
-
security: { collectWarnings: (
|
|
1447
|
+
security: { collectWarnings: ({ cfg }) => collectMSTeamsSecurityFindings({ cfg }) },
|
|
1502
1448
|
pairing: { text: {
|
|
1503
1449
|
idLabel: "msteamsUserId",
|
|
1504
1450
|
message: openclaw_plugin_sdk_channel_status.PAIRING_APPROVED_MESSAGE,
|
|
@@ -1512,18 +1458,29 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1512
1458
|
});
|
|
1513
1459
|
}
|
|
1514
1460
|
} },
|
|
1515
|
-
threading: {
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1461
|
+
threading: {
|
|
1462
|
+
matchesToolContextTarget: ({ target, toolContext }) => msteamsContextTargetsMatch(target, toolContext),
|
|
1463
|
+
buildToolContext: ({ context, hasRepliedRef }) => {
|
|
1464
|
+
const nativeChannelId = context.NativeChannelId?.trim();
|
|
1465
|
+
const hasChannelRoute = Boolean(nativeChannelId && nativeChannelId.includes("/"));
|
|
1466
|
+
const isChannel = context.ChatType === "channel";
|
|
1467
|
+
const currentThreadTs = (context.MessageThreadId != null ? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(String(context.MessageThreadId)) : void 0) ?? (isChannel ? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(context.ReplyToId) : void 0);
|
|
1468
|
+
return {
|
|
1469
|
+
currentChannelId: (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(context.To),
|
|
1470
|
+
currentChatType: context.ChatType === "direct" || context.ChatType === "group" || context.ChatType === "channel" ? context.ChatType : void 0,
|
|
1471
|
+
currentMessagingTarget: hasChannelRoute ? nativeChannelId : void 0,
|
|
1472
|
+
currentGraphChannelId: hasChannelRoute ? nativeChannelId : void 0,
|
|
1473
|
+
currentThreadTs,
|
|
1474
|
+
...currentThreadTs ? { replyToMode: "all" } : {},
|
|
1475
|
+
hasRepliedRef
|
|
1476
|
+
};
|
|
1477
|
+
},
|
|
1478
|
+
resolveAutoThreadId: ({ cfg, to, toolContext }) => resolveMSTeamsAutoThreadId({
|
|
1479
|
+
cfg: cfg.channels?.msteams,
|
|
1480
|
+
to,
|
|
1481
|
+
toolContext
|
|
1482
|
+
})
|
|
1483
|
+
},
|
|
1527
1484
|
outbound: msteamsChannelOutbound
|
|
1528
1485
|
});
|
|
1529
1486
|
//#endregion
|