diff --git a/extensions/msteams/src/channel.ts b/extensions/msteams/src/channel.ts index 730d425f9a0..17c73cf1e61 100644 --- a/extensions/msteams/src/channel.ts +++ b/extensions/msteams/src/channel.ts @@ -31,6 +31,7 @@ import { resolveMSTeamsUserAllowlist, } from "./resolve-allowlist.js"; import { getMSTeamsRuntime } from "./runtime.js"; +import { resolveMSTeamsOutboundSessionRoute } from "./session-route.js"; import { msteamsSetupAdapter } from "./setup-core.js"; import { msteamsSetupWizard } from "./setup-surface.js"; import { resolveMSTeamsCredentials } from "./token.js"; @@ -181,6 +182,7 @@ export const msteamsPlugin: ChannelPlugin = { setup: msteamsSetupAdapter, messaging: { normalizeTarget: normalizeMSTeamsMessagingTarget, + resolveOutboundSessionRoute: (params) => resolveMSTeamsOutboundSessionRoute(params), targetResolver: { looksLikeId: (raw) => { const trimmed = raw.trim(); diff --git a/extensions/msteams/src/session-route.ts b/extensions/msteams/src/session-route.ts new file mode 100644 index 00000000000..95f778b0249 --- /dev/null +++ b/extensions/msteams/src/session-route.ts @@ -0,0 +1,39 @@ +import { + buildChannelOutboundSessionRoute, + stripChannelTargetPrefix, + stripTargetKindPrefix, + type ChannelOutboundSessionRouteParams, +} from "openclaw/plugin-sdk/core"; + +export function resolveMSTeamsOutboundSessionRoute(params: ChannelOutboundSessionRouteParams) { + let trimmed = stripChannelTargetPrefix(params.target, "msteams", "teams"); + if (!trimmed) { + return null; + } + + const lower = trimmed.toLowerCase(); + const isUser = lower.startsWith("user:"); + const rawId = stripTargetKindPrefix(trimmed); + if (!rawId) { + return null; + } + const conversationId = rawId.split(";")[0] ?? rawId; + const isChannel = !isUser && /@thread\.tacv2/i.test(conversationId); + return buildChannelOutboundSessionRoute({ + cfg: params.cfg, + agentId: params.agentId, + channel: "msteams", + accountId: params.accountId, + peer: { + kind: isUser ? "direct" : isChannel ? "channel" : "group", + id: conversationId, + }, + chatType: isUser ? "direct" : isChannel ? "channel" : "group", + from: isUser + ? `msteams:${conversationId}` + : isChannel + ? `msteams:channel:${conversationId}` + : `msteams:group:${conversationId}`, + to: isUser ? `user:${conversationId}` : `conversation:${conversationId}`, + }); +}