@openclaw/msteams 2026.8.1-beta.3 → 2026.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapter.runtime-8g-MOPfb.cjs → adapter.runtime-DDuc7sKJ.cjs} +1 -1
- package/dist/api.cjs +2 -2
- package/dist/approval-card-BEblaIto.cjs +303 -0
- package/dist/approval-handler.runtime-C0AWNWXk.cjs +107 -0
- package/dist/{channel-KpWENcgK.cjs → channel-DLn4b6Qi.cjs} +168 -53
- package/dist/channel-config-api.cjs +1 -1
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/{channel.runtime-Bkzj8jZ0.cjs → channel.runtime-1mH99ZAm.cjs} +49 -608
- package/dist/{channel.setup-mOFtsfYz.cjs → channel.setup-BRbhaigB.cjs} +29 -18
- package/dist/{config-schema-C4CszdDi.cjs → config-schema-MyN2lamA.cjs} +12 -11
- package/dist/configured-state.cjs +20 -0
- package/dist/directory-contract-api.cjs +1 -1
- package/dist/doctor-contract-api.cjs +79 -42
- package/dist/{messenger-IISPSOvj.cjs → messenger-flkiAkkB.cjs} +29 -171
- package/dist/{oauth-C9So7uld.cjs → oauth-Bctn-WPI.cjs} +4 -3
- package/dist/{polls-DvuJvaDG.cjs → polls-P86qBpeV.cjs} +5 -4
- package/dist/qa-runner-api.cjs +1 -1
- package/dist/reaction-types-CL79V_5D.cjs +150 -0
- package/dist/{resolve-allowlist-CIfWUwuc.cjs → resolve-allowlist-BrdWKHE-.cjs} +26 -51
- package/dist/{rolldown-runtime-D6vf50IK.cjs → rolldown-runtime-VH7oDXx4.cjs} +1 -1
- package/dist/runtime-api.cjs +2 -1
- package/dist/secret-input-C65t6kjM.cjs +1 -0
- package/dist/send-C4BjzS1F.cjs +631 -0
- package/dist/setup-plugin-api.cjs +1 -1
- package/dist/{src-C127-DcQ.cjs → src-RSjkJRjI.cjs} +237 -99
- package/dist/{sso-token-store-ChhO1f4i.cjs → sso-token-store-CNbRhz-A.cjs} +1 -1
- package/dist/thread-session-DxOri69r.cjs +63 -0
- package/package.json +13 -11
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
2
1
|
require("./runtime-api.cjs");
|
|
3
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
4
|
-
const require_channel = require("./channel-
|
|
5
|
-
const require_channel_setup = require("./channel.setup-
|
|
6
|
-
const require_polls = require("./polls-
|
|
7
|
-
const
|
|
2
|
+
const require_resolve_allowlist = require("./resolve-allowlist-BrdWKHE-.cjs");
|
|
3
|
+
const require_channel = require("./channel-DLn4b6Qi.cjs");
|
|
4
|
+
const require_channel_setup = require("./channel.setup-BRbhaigB.cjs");
|
|
5
|
+
const require_polls = require("./polls-P86qBpeV.cjs");
|
|
6
|
+
const require_send = require("./send-C4BjzS1F.cjs");
|
|
7
|
+
const require_reaction_types = require("./reaction-types-CL79V_5D.cjs");
|
|
8
8
|
let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
|
|
9
9
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
10
10
|
let openclaw_plugin_sdk_reply_payload = require("openclaw/plugin-sdk/reply-payload");
|
|
11
11
|
let openclaw_plugin_sdk_number_runtime = require("openclaw/plugin-sdk/number-runtime");
|
|
12
12
|
let openclaw_plugin_sdk_channel_send_result = require("openclaw/plugin-sdk/channel-send-result");
|
|
13
|
-
let openclaw_plugin_sdk_markdown_table_runtime = require("openclaw/plugin-sdk/markdown-table-runtime");
|
|
14
|
-
let openclaw_plugin_sdk_media_runtime = require("openclaw/plugin-sdk/media-runtime");
|
|
15
|
-
let openclaw_plugin_sdk_outbound_media = require("openclaw/plugin-sdk/outbound-media");
|
|
16
13
|
let openclaw_plugin_sdk_text_chunking = require("openclaw/plugin-sdk/text-chunking");
|
|
17
14
|
let openclaw_plugin_sdk_string_normalization_runtime = require("openclaw/plugin-sdk/string-normalization-runtime");
|
|
18
15
|
//#region extensions/msteams/src/directory-live.ts
|
|
19
16
|
async function listMSTeamsDirectoryPeersLive(params) {
|
|
20
17
|
const query = require_resolve_allowlist.normalizeQuery(params.query);
|
|
21
18
|
if (!query) return [];
|
|
19
|
+
const token = await require_resolve_allowlist.resolveGraphToken(params.cfg);
|
|
20
|
+
const limit = typeof params.limit === "number" && params.limit > 0 ? params.limit : 20;
|
|
22
21
|
return (await require_resolve_allowlist.searchGraphUsers({
|
|
23
|
-
token
|
|
22
|
+
token,
|
|
24
23
|
query,
|
|
25
|
-
top:
|
|
24
|
+
top: limit
|
|
26
25
|
})).map((user) => {
|
|
27
26
|
const id = user.id?.trim();
|
|
28
27
|
if (!id) return null;
|
|
@@ -135,9 +134,10 @@ function resolveConversationPath(to) {
|
|
|
135
134
|
async function getMessageMSTeams(params) {
|
|
136
135
|
const token = await require_resolve_allowlist.resolveGraphToken(params.cfg);
|
|
137
136
|
const { basePath } = resolveConversationPath(await resolveGraphConversationId(params.to));
|
|
137
|
+
const path = `${basePath}/messages/${encodeURIComponent(params.messageId)}`;
|
|
138
138
|
const msg = await require_resolve_allowlist.fetchGraphJson({
|
|
139
139
|
token,
|
|
140
|
-
path
|
|
140
|
+
path
|
|
141
141
|
});
|
|
142
142
|
return {
|
|
143
143
|
id: msg.id ?? params.messageId,
|
|
@@ -185,9 +185,10 @@ async function unpinMessageMSTeams(params) {
|
|
|
185
185
|
const token = await require_resolve_allowlist.resolveGraphToken(params.cfg);
|
|
186
186
|
const conv = resolveConversationPath(await resolveGraphConversationId(params.to));
|
|
187
187
|
if (conv.kind === "channel") throw new Error("Pin/unpin is not supported for channel messages on Graph v1.0. Only chat conversations support pinned messages.");
|
|
188
|
+
const path = `${conv.basePath}/pinnedMessages/${encodeURIComponent(params.pinnedMessageId)}`;
|
|
188
189
|
await require_resolve_allowlist.deleteGraphRequest({
|
|
189
190
|
token,
|
|
190
|
-
path
|
|
191
|
+
path
|
|
191
192
|
});
|
|
192
193
|
return { ok: true };
|
|
193
194
|
}
|
|
@@ -237,12 +238,13 @@ async function listPinsMSTeams(params) {
|
|
|
237
238
|
* delegated-auth-enabled deployments hit the user-scoped endpoint.
|
|
238
239
|
*/
|
|
239
240
|
async function reactMessageMSTeams(params) {
|
|
240
|
-
const reactionType =
|
|
241
|
+
const reactionType = require_reaction_types.resolveMSTeamsReactionEmoji(params.reactionType);
|
|
241
242
|
const token = await require_resolve_allowlist.resolveGraphToken(params.cfg, { preferDelegated: true });
|
|
242
243
|
const { basePath } = resolveConversationPath(await resolveGraphConversationId(params.to));
|
|
244
|
+
const path = `${basePath}/messages/${encodeURIComponent(params.messageId)}/setReaction`;
|
|
243
245
|
await require_resolve_allowlist.mutateGraphJson({
|
|
244
246
|
token,
|
|
245
|
-
path
|
|
247
|
+
path,
|
|
246
248
|
method: "POST",
|
|
247
249
|
body: { reactionType },
|
|
248
250
|
beta: true
|
|
@@ -256,12 +258,13 @@ async function reactMessageMSTeams(params) {
|
|
|
256
258
|
* `preferDelegated: true`. See `reactMessageMSTeams` for fallback rules.
|
|
257
259
|
*/
|
|
258
260
|
async function unreactMessageMSTeams(params) {
|
|
259
|
-
const reactionType =
|
|
261
|
+
const reactionType = require_reaction_types.resolveMSTeamsReactionEmoji(params.reactionType);
|
|
260
262
|
const token = await require_resolve_allowlist.resolveGraphToken(params.cfg, { preferDelegated: true });
|
|
261
263
|
const { basePath } = resolveConversationPath(await resolveGraphConversationId(params.to));
|
|
264
|
+
const path = `${basePath}/messages/${encodeURIComponent(params.messageId)}/unsetReaction`;
|
|
262
265
|
await require_resolve_allowlist.mutateGraphJson({
|
|
263
266
|
token,
|
|
264
|
-
path
|
|
267
|
+
path,
|
|
265
268
|
method: "POST",
|
|
266
269
|
body: { reactionType },
|
|
267
270
|
beta: true
|
|
@@ -275,9 +278,10 @@ async function unreactMessageMSTeams(params) {
|
|
|
275
278
|
async function listReactionsMSTeams(params) {
|
|
276
279
|
const token = await require_resolve_allowlist.resolveGraphToken(params.cfg);
|
|
277
280
|
const { basePath } = resolveConversationPath(await resolveGraphConversationId(params.to));
|
|
281
|
+
const path = `${basePath}/messages/${encodeURIComponent(params.messageId)}`;
|
|
278
282
|
const msg = await require_resolve_allowlist.fetchGraphJson({
|
|
279
283
|
token,
|
|
280
|
-
path
|
|
284
|
+
path
|
|
281
285
|
});
|
|
282
286
|
const grouped = /* @__PURE__ */ new Map();
|
|
283
287
|
for (const reaction of msg.reactions ?? []) {
|
|
@@ -296,7 +300,7 @@ async function listReactionsMSTeams(params) {
|
|
|
296
300
|
return { reactions: Array.from(grouped.entries()).map(([type, group]) => ({
|
|
297
301
|
reactionType: type,
|
|
298
302
|
name: type,
|
|
299
|
-
emoji:
|
|
303
|
+
emoji: require_reaction_types.getMSTeamsReactionEmoji(type),
|
|
300
304
|
count: group.count,
|
|
301
305
|
users: group.users
|
|
302
306
|
})) };
|
|
@@ -307,7 +311,7 @@ const SEARCH_PAGE_SIZE = 50;
|
|
|
307
311
|
const SEARCH_MAX_PAGES = 10;
|
|
308
312
|
function normalizeSearchText(message) {
|
|
309
313
|
const content = message.body?.content ?? "";
|
|
310
|
-
return message.body?.contentType?.toLowerCase() === "html" ?
|
|
314
|
+
return message.body?.contentType?.toLowerCase() === "html" ? require_reaction_types.stripHtmlFromTeamsMessage(content) : content.trim();
|
|
311
315
|
}
|
|
312
316
|
function matchesSearchSender(message, from) {
|
|
313
317
|
const normalized = from?.trim().toLowerCase();
|
|
@@ -358,7 +362,7 @@ async function searchMessagesMSTeams(params) {
|
|
|
358
362
|
messages,
|
|
359
363
|
truncated: false
|
|
360
364
|
};
|
|
361
|
-
truncated = page ===
|
|
365
|
+
truncated = page === 9;
|
|
362
366
|
}
|
|
363
367
|
return {
|
|
364
368
|
messages,
|
|
@@ -439,9 +443,10 @@ async function removeParticipantMSTeams(params) {
|
|
|
439
443
|
userId: params.userId
|
|
440
444
|
});
|
|
441
445
|
if (!member?.id) throw new Error(`User ${params.userId} is not a member of this conversation`);
|
|
446
|
+
const conv = resolveConversationPath(conversationId);
|
|
442
447
|
await require_resolve_allowlist.deleteGraphRequest({
|
|
443
448
|
token,
|
|
444
|
-
path: `${
|
|
449
|
+
path: `${conv.basePath}/members/${encodeURIComponent(member.id)}`
|
|
445
450
|
});
|
|
446
451
|
return { removed: {
|
|
447
452
|
userId: params.userId,
|
|
@@ -563,9 +568,11 @@ async function listChannelsMSTeams(params) {
|
|
|
563
568
|
* Returns id, displayName, description, membershipType, webUrl, and createdDateTime.
|
|
564
569
|
*/
|
|
565
570
|
async function getChannelInfoMSTeams(params) {
|
|
571
|
+
const token = await require_resolve_allowlist.resolveGraphToken(params.cfg);
|
|
572
|
+
const path = `/teams/${encodeURIComponent(params.teamId)}/channels/${encodeURIComponent(params.channelId)}?$select=id,displayName,description,membershipType,webUrl,createdDateTime`;
|
|
566
573
|
const ch = await require_resolve_allowlist.fetchGraphJson({
|
|
567
|
-
token
|
|
568
|
-
path
|
|
574
|
+
token,
|
|
575
|
+
path
|
|
569
576
|
});
|
|
570
577
|
return { channel: {
|
|
571
578
|
id: ch.id,
|
|
@@ -577,576 +584,6 @@ async function getChannelInfoMSTeams(params) {
|
|
|
577
584
|
} };
|
|
578
585
|
}
|
|
579
586
|
//#endregion
|
|
580
|
-
//#region extensions/msteams/src/send-context.ts
|
|
581
|
-
function resolveMSTeamsProactiveReplyTarget(params) {
|
|
582
|
-
const threadRootId = params.ref.threadId ?? params.ref.activityId;
|
|
583
|
-
if (params.conversationType !== "channel" || !threadRootId) return { replyStyle: "top-level" };
|
|
584
|
-
const routeConfig = require_channel.resolveMSTeamsRouteConfig({
|
|
585
|
-
cfg: params.cfg,
|
|
586
|
-
teamId: params.ref.teamId,
|
|
587
|
-
conversationId: params.conversationId,
|
|
588
|
-
allowNameMatching: false
|
|
589
|
-
});
|
|
590
|
-
const { replyStyle } = require_channel.resolveMSTeamsReplyPolicy({
|
|
591
|
-
isDirectMessage: false,
|
|
592
|
-
globalConfig: params.cfg,
|
|
593
|
-
teamConfig: routeConfig.teamConfig,
|
|
594
|
-
channelConfig: routeConfig.channelConfig
|
|
595
|
-
});
|
|
596
|
-
return replyStyle === "thread" ? {
|
|
597
|
-
replyStyle,
|
|
598
|
-
threadActivityId: threadRootId
|
|
599
|
-
} : { replyStyle };
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Parse the target value into a conversation reference lookup key.
|
|
603
|
-
* Supported formats:
|
|
604
|
-
* - conversation:19:abc@thread.tacv2 → lookup by conversation ID
|
|
605
|
-
* - conversation:19:abc@thread.tacv2;messageid=root → lookup base ID, use root
|
|
606
|
-
* - user:aad-object-id → lookup by user AAD object ID
|
|
607
|
-
* - 19:abc@thread.tacv2 → direct conversation ID
|
|
608
|
-
*/
|
|
609
|
-
function parseRecipient(to) {
|
|
610
|
-
const trimmed = to.trim();
|
|
611
|
-
const finalize = (type, id) => {
|
|
612
|
-
const normalized = id.trim();
|
|
613
|
-
if (!normalized) throw new Error(`Invalid target value: missing ${type} id`);
|
|
614
|
-
if (type === "conversation") {
|
|
615
|
-
const threadId = require_resolve_allowlist.extractMSTeamsConversationMessageId(normalized);
|
|
616
|
-
const normalizedConversationId = require_resolve_allowlist.normalizeMSTeamsConversationId(normalized);
|
|
617
|
-
const slashIndex = normalizedConversationId.indexOf("/");
|
|
618
|
-
const graphChannelId = slashIndex > 0 ? normalizedConversationId.slice(slashIndex + 1) : void 0;
|
|
619
|
-
return {
|
|
620
|
-
type,
|
|
621
|
-
id: graphChannelId && (graphChannelId.startsWith("19:") || graphChannelId.includes("@thread")) ? graphChannelId : normalizedConversationId,
|
|
622
|
-
...threadId ? { threadId } : {}
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
return {
|
|
626
|
-
type,
|
|
627
|
-
id: normalized
|
|
628
|
-
};
|
|
629
|
-
};
|
|
630
|
-
if (trimmed.startsWith("conversation:")) return finalize("conversation", trimmed.slice(13));
|
|
631
|
-
if (trimmed.startsWith("user:")) return finalize("user", trimmed.slice(5));
|
|
632
|
-
if (trimmed.startsWith("19:") || trimmed.includes("@thread")) return finalize("conversation", trimmed);
|
|
633
|
-
return finalize("user", trimmed);
|
|
634
|
-
}
|
|
635
|
-
/**
|
|
636
|
-
* Find a stored conversation reference for the given recipient.
|
|
637
|
-
*/
|
|
638
|
-
async function findConversationReference(recipient) {
|
|
639
|
-
if (recipient.type === "conversation") {
|
|
640
|
-
const ref = await recipient.store.get(recipient.id);
|
|
641
|
-
if (ref) return {
|
|
642
|
-
conversationId: recipient.id,
|
|
643
|
-
ref
|
|
644
|
-
};
|
|
645
|
-
return null;
|
|
646
|
-
}
|
|
647
|
-
const found = await recipient.store.findPreferredDmByUserId(recipient.id);
|
|
648
|
-
if (!found) return null;
|
|
649
|
-
return {
|
|
650
|
-
conversationId: found.conversationId,
|
|
651
|
-
ref: found.reference
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
async function resolveMSTeamsSendContext(params) {
|
|
655
|
-
const msteamsCfg = params.cfg.channels?.msteams;
|
|
656
|
-
if (!msteamsCfg?.enabled) throw new Error("msteams provider is not enabled");
|
|
657
|
-
const account = require_channel_setup.resolveMSTeamsAccount(params.cfg);
|
|
658
|
-
if (account.tokenStatus === "configured_unavailable") throw new Error("msteams credential file is configured but unavailable");
|
|
659
|
-
if (!account.configured) throw new Error("msteams credentials not configured");
|
|
660
|
-
const creds = require_resolve_allowlist.resolveMSTeamsCredentials(msteamsCfg);
|
|
661
|
-
if (!creds) throw new Error("msteams credentials not configured");
|
|
662
|
-
const store = require_polls.createMSTeamsConversationStoreState();
|
|
663
|
-
const recipient = parseRecipient(params.to);
|
|
664
|
-
const found = await findConversationReference({
|
|
665
|
-
...recipient,
|
|
666
|
-
store
|
|
667
|
-
});
|
|
668
|
-
if (!found) throw new Error(`No conversation reference found for ${recipient.type}:${recipient.id}. The bot must receive a message from this conversation before it can send proactively.`);
|
|
669
|
-
const conversationId = found.conversationId;
|
|
670
|
-
const ref = recipient.threadId ? {
|
|
671
|
-
...found.ref,
|
|
672
|
-
threadId: recipient.threadId
|
|
673
|
-
} : found.ref;
|
|
674
|
-
const log = require_runtime.getMSTeamsRuntime().logging.getChildLogger({ name: "msteams:send" });
|
|
675
|
-
if (ref.serviceUrl && !require_resolve_allowlist.isAllowedBotFrameworkServiceUrl(ref.serviceUrl)) {
|
|
676
|
-
try {
|
|
677
|
-
await store.remove(conversationId);
|
|
678
|
-
} catch (err) {
|
|
679
|
-
log.warn?.("failed to remove blocked msteams conversation reference", {
|
|
680
|
-
conversationId,
|
|
681
|
-
error: require_channel_setup.formatUnknownError(err)
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
throw new Error(`Stored Microsoft Teams conversation reference has blocked serviceUrl host: ${require_resolve_allowlist.describeBotFrameworkServiceUrlHost(ref.serviceUrl)}. The bot must receive a new message from this conversation before it can send proactively.`);
|
|
685
|
-
}
|
|
686
|
-
const safeRef = ref.serviceUrl ? {
|
|
687
|
-
...ref,
|
|
688
|
-
serviceUrl: require_resolve_allowlist.normalizeBotFrameworkServiceUrl(ref.serviceUrl)
|
|
689
|
-
} : ref;
|
|
690
|
-
if (recipient.type === "user") {
|
|
691
|
-
const resolvedType = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(safeRef.conversation?.conversationType ?? "");
|
|
692
|
-
if (resolvedType && resolvedType !== "personal") throw new Error(`Conversation reference for user:${recipient.id} resolved to a ${resolvedType} conversation (${conversationId}) instead of a personal DM. The bot must receive a DM from this user before it can send proactively.`);
|
|
693
|
-
}
|
|
694
|
-
const sdkCloudOptions = require_resolve_allowlist.resolveMSTeamsSdkCloudOptions(msteamsCfg);
|
|
695
|
-
const { app } = await require_resolve_allowlist.loadMSTeamsSdkWithAuth(creds, sdkCloudOptions);
|
|
696
|
-
require_resolve_allowlist.validateMSTeamsProactiveServiceUrlBoundary({
|
|
697
|
-
cloud: sdkCloudOptions.cloud,
|
|
698
|
-
conversationId,
|
|
699
|
-
storedServiceUrl: safeRef.serviceUrl,
|
|
700
|
-
configuredServiceUrl: sdkCloudOptions.serviceUrl
|
|
701
|
-
});
|
|
702
|
-
const tokenProvider = require_resolve_allowlist.createMSTeamsTokenProvider(app);
|
|
703
|
-
const storedConversationType = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(safeRef.conversation?.conversationType ?? "");
|
|
704
|
-
let conversationType;
|
|
705
|
-
if (storedConversationType === "personal") conversationType = "personal";
|
|
706
|
-
else if (storedConversationType === "channel") conversationType = "channel";
|
|
707
|
-
else conversationType = "groupChat";
|
|
708
|
-
const replyTarget = recipient.threadId && conversationType === "channel" ? {
|
|
709
|
-
replyStyle: "thread",
|
|
710
|
-
threadActivityId: recipient.threadId
|
|
711
|
-
} : resolveMSTeamsProactiveReplyTarget({
|
|
712
|
-
cfg: msteamsCfg,
|
|
713
|
-
conversationId,
|
|
714
|
-
ref: safeRef,
|
|
715
|
-
conversationType
|
|
716
|
-
});
|
|
717
|
-
const sharePointSiteId = msteamsCfg.sharePointSiteId;
|
|
718
|
-
const mediaMaxBytes = (0, openclaw_plugin_sdk_media_runtime.resolveChannelMediaMaxBytes)({
|
|
719
|
-
cfg: params.cfg,
|
|
720
|
-
resolveChannelLimitMb: ({ cfg }) => cfg.channels?.msteams?.mediaMaxMb
|
|
721
|
-
});
|
|
722
|
-
return {
|
|
723
|
-
appId: creds.appId,
|
|
724
|
-
conversationId,
|
|
725
|
-
ref: safeRef,
|
|
726
|
-
app,
|
|
727
|
-
log,
|
|
728
|
-
conversationType,
|
|
729
|
-
...replyTarget,
|
|
730
|
-
sdkCloudOptions,
|
|
731
|
-
tokenProvider,
|
|
732
|
-
sharePointSiteId,
|
|
733
|
-
mediaMaxBytes
|
|
734
|
-
};
|
|
735
|
-
}
|
|
736
|
-
//#endregion
|
|
737
|
-
//#region extensions/msteams/src/send.ts
|
|
738
|
-
/** Threshold for large files that require FileConsentCard flow in personal chats */
|
|
739
|
-
const FILE_CONSENT_THRESHOLD_BYTES = 4 * 1024 * 1024;
|
|
740
|
-
/**
|
|
741
|
-
* MSTeams-specific media size limit (100MB).
|
|
742
|
-
* Higher than the default to support Teams file-consent and SharePoint uploads.
|
|
743
|
-
*/
|
|
744
|
-
const MSTEAMS_MAX_MEDIA_BYTES = 100 * 1024 * 1024;
|
|
745
|
-
function createMSTeamsSendReceipt(params) {
|
|
746
|
-
const receipt = (0, openclaw_plugin_sdk_channel_outbound.createMessageReceiptFromOutboundResults)({
|
|
747
|
-
kind: params.kind,
|
|
748
|
-
results: params.platformMessageIds.map((messageId) => ({
|
|
749
|
-
channel: "msteams",
|
|
750
|
-
messageId,
|
|
751
|
-
conversationId: params.conversationId
|
|
752
|
-
}))
|
|
753
|
-
});
|
|
754
|
-
if (!params.kinds) return receipt;
|
|
755
|
-
const kinds = params.kinds;
|
|
756
|
-
return {
|
|
757
|
-
...receipt,
|
|
758
|
-
parts: receipt.parts.map((part, index) => {
|
|
759
|
-
const nextPart = {
|
|
760
|
-
platformMessageId: part.platformMessageId,
|
|
761
|
-
kind: kinds[index] ?? params.kind,
|
|
762
|
-
index: part.index
|
|
763
|
-
};
|
|
764
|
-
if (part.threadId) nextPart.threadId = part.threadId;
|
|
765
|
-
if (part.replyToId) nextPart.replyToId = part.replyToId;
|
|
766
|
-
if (part.raw) nextPart.raw = part.raw;
|
|
767
|
-
return nextPart;
|
|
768
|
-
})
|
|
769
|
-
};
|
|
770
|
-
}
|
|
771
|
-
function createMSTeamsSendResult(params) {
|
|
772
|
-
const platformMessageIds = (params.platformMessageIds?.length ? [...params.platformMessageIds] : [params.messageId]).map((messageId) => messageId.trim()).filter((messageId) => messageId && messageId !== "unknown");
|
|
773
|
-
return {
|
|
774
|
-
messageId: params.messageId,
|
|
775
|
-
conversationId: params.conversationId,
|
|
776
|
-
receipt: createMSTeamsSendReceipt({
|
|
777
|
-
conversationId: params.conversationId,
|
|
778
|
-
platformMessageIds,
|
|
779
|
-
kind: params.kind
|
|
780
|
-
}),
|
|
781
|
-
...params.pendingUploadId ? { pendingUploadId: params.pendingUploadId } : {}
|
|
782
|
-
};
|
|
783
|
-
}
|
|
784
|
-
/**
|
|
785
|
-
* Send a message to a Teams conversation or user.
|
|
786
|
-
*
|
|
787
|
-
* Uses the stored ConversationReference from previous interactions.
|
|
788
|
-
* The bot must have received at least one message from the conversation
|
|
789
|
-
* before proactive messaging works.
|
|
790
|
-
*
|
|
791
|
-
* File handling by conversation type:
|
|
792
|
-
* - Personal (1:1) chats: small images (<4MB) use base64, large files and non-images use FileConsentCard
|
|
793
|
-
* - Group chats / channels: files require configured SharePoint storage
|
|
794
|
-
*/
|
|
795
|
-
async function sendMessageMSTeams(params) {
|
|
796
|
-
const { cfg, to, text, mediaUrl, filename, mediaAccess, mediaLocalRoots, mediaReadFile } = params;
|
|
797
|
-
const tableMode = (0, openclaw_plugin_sdk_markdown_table_runtime.resolveMarkdownTableMode)({
|
|
798
|
-
cfg,
|
|
799
|
-
channel: "msteams"
|
|
800
|
-
});
|
|
801
|
-
const messageText = require_messenger.formatMSTeamsMarkdown(text ?? "", tableMode);
|
|
802
|
-
const ctx = await resolveMSTeamsSendContext({
|
|
803
|
-
cfg,
|
|
804
|
-
to
|
|
805
|
-
});
|
|
806
|
-
const { conversationId, log, conversationType, tokenProvider, sharePointSiteId } = ctx;
|
|
807
|
-
log.debug?.("sending proactive message", {
|
|
808
|
-
conversationId,
|
|
809
|
-
conversationType,
|
|
810
|
-
textLength: messageText.length,
|
|
811
|
-
hasMedia: Boolean(mediaUrl)
|
|
812
|
-
});
|
|
813
|
-
if (mediaUrl) {
|
|
814
|
-
const media = await (0, openclaw_plugin_sdk_outbound_media.loadOutboundMediaFromUrl)(mediaUrl, {
|
|
815
|
-
maxBytes: ctx.mediaMaxBytes ?? MSTEAMS_MAX_MEDIA_BYTES,
|
|
816
|
-
mediaAccess,
|
|
817
|
-
mediaLocalRoots,
|
|
818
|
-
mediaReadFile
|
|
819
|
-
});
|
|
820
|
-
const isLargeFile = media.buffer.length >= FILE_CONSENT_THRESHOLD_BYTES;
|
|
821
|
-
const isImage = media.contentType?.startsWith("image/") ?? false;
|
|
822
|
-
const fallbackFileName = await require_messenger.extractFilename(mediaUrl);
|
|
823
|
-
const fileName = filename?.trim() || media.fileName || fallbackFileName;
|
|
824
|
-
log.debug?.("processing media", {
|
|
825
|
-
fileName,
|
|
826
|
-
contentType: media.contentType,
|
|
827
|
-
size: media.buffer.length,
|
|
828
|
-
isLargeFile,
|
|
829
|
-
isImage,
|
|
830
|
-
conversationType
|
|
831
|
-
});
|
|
832
|
-
if (require_messenger.requiresFileConsent({
|
|
833
|
-
conversationType,
|
|
834
|
-
contentType: media.contentType,
|
|
835
|
-
bufferSize: media.buffer.length,
|
|
836
|
-
thresholdBytes: FILE_CONSENT_THRESHOLD_BYTES
|
|
837
|
-
})) {
|
|
838
|
-
const { activity, uploadId } = await require_messenger.prepareFileConsentActivityFs({
|
|
839
|
-
media: {
|
|
840
|
-
buffer: media.buffer,
|
|
841
|
-
filename: fileName,
|
|
842
|
-
contentType: media.contentType
|
|
843
|
-
},
|
|
844
|
-
conversationId,
|
|
845
|
-
description: messageText || void 0
|
|
846
|
-
});
|
|
847
|
-
log.debug?.("sending file consent card", {
|
|
848
|
-
uploadId,
|
|
849
|
-
fileName,
|
|
850
|
-
size: media.buffer.length
|
|
851
|
-
});
|
|
852
|
-
const messageId = await sendProactiveActivity({
|
|
853
|
-
ctx,
|
|
854
|
-
activity,
|
|
855
|
-
errorPrefix: "msteams consent card send"
|
|
856
|
-
});
|
|
857
|
-
require_messenger.setPendingUploadActivityId(uploadId, messageId);
|
|
858
|
-
await require_messenger.setPendingUploadActivityIdFs(uploadId, messageId);
|
|
859
|
-
log.info("sent file consent card", {
|
|
860
|
-
conversationId,
|
|
861
|
-
messageId,
|
|
862
|
-
uploadId
|
|
863
|
-
});
|
|
864
|
-
return createMSTeamsSendResult({
|
|
865
|
-
messageId,
|
|
866
|
-
conversationId,
|
|
867
|
-
kind: "card",
|
|
868
|
-
pendingUploadId: uploadId
|
|
869
|
-
});
|
|
870
|
-
}
|
|
871
|
-
if (conversationType === "personal") {
|
|
872
|
-
const base64 = media.buffer.toString("base64");
|
|
873
|
-
return sendTextWithMedia(ctx, messageText, `data:${media.contentType};base64,${base64}`);
|
|
874
|
-
}
|
|
875
|
-
if (isImage && !sharePointSiteId) {
|
|
876
|
-
const base64 = media.buffer.toString("base64");
|
|
877
|
-
return sendTextWithMedia(ctx, messageText, `data:${media.contentType};base64,${base64}`);
|
|
878
|
-
}
|
|
879
|
-
try {
|
|
880
|
-
const siteId = require_messenger.requireMSTeamsSharePointSiteId(sharePointSiteId);
|
|
881
|
-
log.debug?.("uploading to SharePoint for native file card", {
|
|
882
|
-
fileName,
|
|
883
|
-
conversationType,
|
|
884
|
-
siteId
|
|
885
|
-
});
|
|
886
|
-
const uploaded = await require_messenger.uploadAndShareSharePoint({
|
|
887
|
-
buffer: media.buffer,
|
|
888
|
-
filename: fileName,
|
|
889
|
-
contentType: media.contentType,
|
|
890
|
-
tokenProvider,
|
|
891
|
-
siteId,
|
|
892
|
-
chatId: conversationId,
|
|
893
|
-
usePerUserSharing: conversationType === "groupChat"
|
|
894
|
-
});
|
|
895
|
-
log.debug?.("SharePoint upload complete", {
|
|
896
|
-
itemId: uploaded.itemId,
|
|
897
|
-
shareUrl: uploaded.shareUrl
|
|
898
|
-
});
|
|
899
|
-
const driveItem = await require_messenger.getDriveItemProperties({
|
|
900
|
-
siteId,
|
|
901
|
-
itemId: uploaded.itemId,
|
|
902
|
-
tokenProvider
|
|
903
|
-
});
|
|
904
|
-
log.debug?.("driveItem properties retrieved", {
|
|
905
|
-
eTag: driveItem.eTag,
|
|
906
|
-
webDavUrl: driveItem.webDavUrl
|
|
907
|
-
});
|
|
908
|
-
const fileCardAttachment = require_messenger.buildTeamsFileInfoCard(driveItem);
|
|
909
|
-
const messageId = await sendProactiveActivityRaw({
|
|
910
|
-
ctx,
|
|
911
|
-
activity: {
|
|
912
|
-
type: "message",
|
|
913
|
-
text: messageText || void 0,
|
|
914
|
-
attachments: [fileCardAttachment]
|
|
915
|
-
}
|
|
916
|
-
});
|
|
917
|
-
log.info("sent native file card", {
|
|
918
|
-
conversationId,
|
|
919
|
-
messageId,
|
|
920
|
-
fileName: driveItem.name
|
|
921
|
-
});
|
|
922
|
-
return createMSTeamsSendResult({
|
|
923
|
-
messageId,
|
|
924
|
-
conversationId,
|
|
925
|
-
kind: "media"
|
|
926
|
-
});
|
|
927
|
-
} catch (err) {
|
|
928
|
-
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
929
|
-
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
930
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
931
|
-
throw new Error(`msteams file send failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
return sendTextWithMedia(ctx, messageText, void 0);
|
|
935
|
-
}
|
|
936
|
-
/**
|
|
937
|
-
* Send a text message with optional base64 media URL.
|
|
938
|
-
*/
|
|
939
|
-
async function sendTextWithMedia(ctx, text, mediaUrl) {
|
|
940
|
-
const { app, appId, conversationId, ref, log, tokenProvider, sharePointSiteId, mediaMaxBytes, replyStyle } = ctx;
|
|
941
|
-
const messages = text && mediaUrl ? [{ text }, { mediaUrl }] : [{
|
|
942
|
-
text: text || void 0,
|
|
943
|
-
mediaUrl
|
|
944
|
-
}];
|
|
945
|
-
let platformMessageIds;
|
|
946
|
-
try {
|
|
947
|
-
platformMessageIds = await require_messenger.sendMSTeamsMessages({
|
|
948
|
-
replyStyle,
|
|
949
|
-
app,
|
|
950
|
-
appId,
|
|
951
|
-
conversationRef: ref,
|
|
952
|
-
messages,
|
|
953
|
-
retry: {},
|
|
954
|
-
onRetry: (event) => {
|
|
955
|
-
log.debug?.("retrying send", {
|
|
956
|
-
conversationId,
|
|
957
|
-
...event
|
|
958
|
-
});
|
|
959
|
-
},
|
|
960
|
-
tokenProvider,
|
|
961
|
-
sharePointSiteId,
|
|
962
|
-
mediaMaxBytes,
|
|
963
|
-
serviceUrlBoundary: ctx.sdkCloudOptions
|
|
964
|
-
});
|
|
965
|
-
} catch (err) {
|
|
966
|
-
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
967
|
-
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
968
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
969
|
-
throw new Error(`msteams send failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
970
|
-
}
|
|
971
|
-
const messageId = platformMessageIds[0] ?? "unknown";
|
|
972
|
-
log.info("sent proactive message", {
|
|
973
|
-
conversationId,
|
|
974
|
-
messageId
|
|
975
|
-
});
|
|
976
|
-
return {
|
|
977
|
-
messageId,
|
|
978
|
-
conversationId,
|
|
979
|
-
receipt: createMSTeamsSendReceipt({
|
|
980
|
-
conversationId,
|
|
981
|
-
platformMessageIds,
|
|
982
|
-
kind: mediaUrl ? "media" : "text",
|
|
983
|
-
...text && mediaUrl ? { kinds: ["text", "media"] } : {}
|
|
984
|
-
})
|
|
985
|
-
};
|
|
986
|
-
}
|
|
987
|
-
async function sendProactiveActivityRaw({ ctx, activity }) {
|
|
988
|
-
const baseRef = require_messenger.buildConversationReference(ctx.ref);
|
|
989
|
-
return require_messenger.extractMessageId(await require_messenger.sendMSTeamsActivityWithReference(ctx.app, baseRef, activity, {
|
|
990
|
-
...ctx.threadActivityId ? { threadActivityId: ctx.threadActivityId } : {},
|
|
991
|
-
serviceUrlBoundary: ctx.sdkCloudOptions
|
|
992
|
-
})) ?? "unknown";
|
|
993
|
-
}
|
|
994
|
-
async function sendProactiveActivity({ ctx, activity, errorPrefix }) {
|
|
995
|
-
try {
|
|
996
|
-
return await sendProactiveActivityRaw({
|
|
997
|
-
ctx,
|
|
998
|
-
activity
|
|
999
|
-
});
|
|
1000
|
-
} catch (err) {
|
|
1001
|
-
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
1002
|
-
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
1003
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1004
|
-
throw new Error(`${errorPrefix} failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
/**
|
|
1008
|
-
* Send a poll (Adaptive Card) to a Teams conversation or user.
|
|
1009
|
-
*/
|
|
1010
|
-
async function sendPollMSTeams(params) {
|
|
1011
|
-
const { cfg, to, question, options, maxSelections } = params;
|
|
1012
|
-
const ctx = await resolveMSTeamsSendContext({
|
|
1013
|
-
cfg,
|
|
1014
|
-
to
|
|
1015
|
-
});
|
|
1016
|
-
const { conversationId, log } = ctx;
|
|
1017
|
-
const pollCard = require_polls.buildMSTeamsPollCard({
|
|
1018
|
-
question,
|
|
1019
|
-
options,
|
|
1020
|
-
maxSelections
|
|
1021
|
-
});
|
|
1022
|
-
log.debug?.("sending poll", {
|
|
1023
|
-
conversationId,
|
|
1024
|
-
pollId: pollCard.pollId,
|
|
1025
|
-
optionCount: pollCard.options.length
|
|
1026
|
-
});
|
|
1027
|
-
const messageId = await sendProactiveActivity({
|
|
1028
|
-
ctx,
|
|
1029
|
-
activity: {
|
|
1030
|
-
type: "message",
|
|
1031
|
-
attachments: [{
|
|
1032
|
-
contentType: "application/vnd.microsoft.card.adaptive",
|
|
1033
|
-
content: pollCard.card
|
|
1034
|
-
}]
|
|
1035
|
-
},
|
|
1036
|
-
errorPrefix: "msteams poll send"
|
|
1037
|
-
});
|
|
1038
|
-
log.info("sent poll", {
|
|
1039
|
-
conversationId,
|
|
1040
|
-
pollId: pollCard.pollId,
|
|
1041
|
-
messageId
|
|
1042
|
-
});
|
|
1043
|
-
return {
|
|
1044
|
-
pollId: pollCard.pollId,
|
|
1045
|
-
messageId,
|
|
1046
|
-
conversationId
|
|
1047
|
-
};
|
|
1048
|
-
}
|
|
1049
|
-
/**
|
|
1050
|
-
* Send an arbitrary Adaptive Card to a Teams conversation or user.
|
|
1051
|
-
*/
|
|
1052
|
-
async function sendAdaptiveCardMSTeams(params) {
|
|
1053
|
-
const { cfg, to, card } = params;
|
|
1054
|
-
const ctx = await resolveMSTeamsSendContext({
|
|
1055
|
-
cfg,
|
|
1056
|
-
to
|
|
1057
|
-
});
|
|
1058
|
-
const { conversationId, log } = ctx;
|
|
1059
|
-
log.debug?.("sending adaptive card", {
|
|
1060
|
-
conversationId,
|
|
1061
|
-
cardType: card.type,
|
|
1062
|
-
cardVersion: card.version
|
|
1063
|
-
});
|
|
1064
|
-
const messageId = await sendProactiveActivity({
|
|
1065
|
-
ctx,
|
|
1066
|
-
activity: {
|
|
1067
|
-
type: "message",
|
|
1068
|
-
attachments: [{
|
|
1069
|
-
contentType: "application/vnd.microsoft.card.adaptive",
|
|
1070
|
-
content: card
|
|
1071
|
-
}]
|
|
1072
|
-
},
|
|
1073
|
-
errorPrefix: "msteams card send"
|
|
1074
|
-
});
|
|
1075
|
-
log.info("sent adaptive card", {
|
|
1076
|
-
conversationId,
|
|
1077
|
-
messageId
|
|
1078
|
-
});
|
|
1079
|
-
return {
|
|
1080
|
-
messageId,
|
|
1081
|
-
conversationId
|
|
1082
|
-
};
|
|
1083
|
-
}
|
|
1084
|
-
/**
|
|
1085
|
-
* Edit (update) a previously sent message in a Teams conversation.
|
|
1086
|
-
*
|
|
1087
|
-
* Uses the Bot Framework REST API for proactive edits outside of the
|
|
1088
|
-
* original turn context.
|
|
1089
|
-
*/
|
|
1090
|
-
async function editMessageMSTeams(params) {
|
|
1091
|
-
const { cfg, to, activityId, text } = params;
|
|
1092
|
-
const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({
|
|
1093
|
-
cfg,
|
|
1094
|
-
to
|
|
1095
|
-
});
|
|
1096
|
-
log.debug?.("editing proactive message", {
|
|
1097
|
-
conversationId,
|
|
1098
|
-
activityId,
|
|
1099
|
-
textLength: text.length
|
|
1100
|
-
});
|
|
1101
|
-
try {
|
|
1102
|
-
await require_messenger.updateMSTeamsActivityWithReference(app, require_messenger.buildConversationReference(ref), activityId, {
|
|
1103
|
-
type: "message",
|
|
1104
|
-
id: activityId,
|
|
1105
|
-
text
|
|
1106
|
-
}, { serviceUrlBoundary: sdkCloudOptions });
|
|
1107
|
-
} catch (err) {
|
|
1108
|
-
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
1109
|
-
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
1110
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1111
|
-
throw new Error(`msteams edit failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1112
|
-
}
|
|
1113
|
-
log.info("edited proactive message", {
|
|
1114
|
-
conversationId,
|
|
1115
|
-
activityId
|
|
1116
|
-
});
|
|
1117
|
-
return { conversationId };
|
|
1118
|
-
}
|
|
1119
|
-
/**
|
|
1120
|
-
* Delete a previously sent message in a Teams conversation.
|
|
1121
|
-
*
|
|
1122
|
-
* Uses the Bot Framework REST API for proactive deletes outside of the
|
|
1123
|
-
* original turn context.
|
|
1124
|
-
*/
|
|
1125
|
-
async function deleteMessageMSTeams(params) {
|
|
1126
|
-
const { cfg, to, activityId } = params;
|
|
1127
|
-
const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({
|
|
1128
|
-
cfg,
|
|
1129
|
-
to
|
|
1130
|
-
});
|
|
1131
|
-
log.debug?.("deleting proactive message", {
|
|
1132
|
-
conversationId,
|
|
1133
|
-
activityId
|
|
1134
|
-
});
|
|
1135
|
-
try {
|
|
1136
|
-
await require_messenger.deleteMSTeamsActivityWithReference(app, require_messenger.buildConversationReference(ref), activityId, { serviceUrlBoundary: sdkCloudOptions });
|
|
1137
|
-
} catch (err) {
|
|
1138
|
-
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
1139
|
-
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
1140
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1141
|
-
throw new Error(`msteams delete failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1142
|
-
}
|
|
1143
|
-
log.info("deleted proactive message", {
|
|
1144
|
-
conversationId,
|
|
1145
|
-
activityId
|
|
1146
|
-
});
|
|
1147
|
-
return { conversationId };
|
|
1148
|
-
}
|
|
1149
|
-
//#endregion
|
|
1150
587
|
//#region extensions/msteams/src/outbound.ts
|
|
1151
588
|
const MSTEAMS_TEXT_CHUNK_LIMIT = 4e3;
|
|
1152
589
|
function resolveMSTeamsEffectiveTextChunkLimit(configuredLimit) {
|
|
@@ -1170,14 +607,14 @@ function resolveMSTeamsThreadTarget(to, threadId) {
|
|
|
1170
607
|
return `${to};messageid=${normalizedThreadId}`;
|
|
1171
608
|
}
|
|
1172
609
|
function resolveMSTeamsTextSend(params) {
|
|
1173
|
-
return (0, openclaw_plugin_sdk_channel_outbound.resolveOutboundSendDep)(params.deps, "msteams") ?? ((to, text) => sendMessageMSTeams({
|
|
610
|
+
return (0, openclaw_plugin_sdk_channel_outbound.resolveOutboundSendDep)(params.deps, "msteams") ?? ((to, text) => require_send.sendMessageMSTeams({
|
|
1174
611
|
cfg: params.cfg,
|
|
1175
612
|
to,
|
|
1176
613
|
text
|
|
1177
614
|
}));
|
|
1178
615
|
}
|
|
1179
616
|
function resolveMSTeamsMediaSend(params) {
|
|
1180
|
-
return (0, openclaw_plugin_sdk_channel_outbound.resolveOutboundSendDep)(params.deps, "msteams") ?? ((to, text, opts) => sendMessageMSTeams({
|
|
617
|
+
return (0, openclaw_plugin_sdk_channel_outbound.resolveOutboundSendDep)(params.deps, "msteams") ?? ((to, text, opts) => require_send.sendMessageMSTeams({
|
|
1181
618
|
cfg: params.cfg,
|
|
1182
619
|
to,
|
|
1183
620
|
text,
|
|
@@ -1219,11 +656,14 @@ const msteamsOutbound = {
|
|
|
1219
656
|
sendPayload: async ({ cfg, to, text, mediaUrl, mediaAccess, mediaLocalRoots, mediaReadFile, payload, deps, onDeliveryResult, threadId }) => {
|
|
1220
657
|
const deliveryTarget = resolveMSTeamsThreadTarget(to, threadId);
|
|
1221
658
|
const presentationCard = (0, openclaw_plugin_sdk_string_coerce_runtime.asOptionalRecord)(payload.channelData?.msteams)?.presentationCard;
|
|
1222
|
-
if (presentationCard && typeof presentationCard === "object" && !Array.isArray(presentationCard))
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
659
|
+
if (presentationCard && typeof presentationCard === "object" && !Array.isArray(presentationCard)) {
|
|
660
|
+
const result = await require_send.sendAdaptiveCardMSTeams({
|
|
661
|
+
cfg,
|
|
662
|
+
to: deliveryTarget,
|
|
663
|
+
card: presentationCard
|
|
664
|
+
});
|
|
665
|
+
return (0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", toMSTeamsOutboundResult(result));
|
|
666
|
+
}
|
|
1227
667
|
const mediaUrls = (0, openclaw_plugin_sdk_string_normalization_runtime.normalizeStringEntries)((0, openclaw_plugin_sdk_reply_payload.resolvePayloadMediaUrls)({
|
|
1228
668
|
...payload,
|
|
1229
669
|
mediaUrl: payload.mediaUrl ?? mediaUrl
|
|
@@ -1284,7 +724,7 @@ const msteamsOutbound = {
|
|
|
1284
724
|
},
|
|
1285
725
|
sendPoll: async ({ cfg, to, poll, threadId }) => {
|
|
1286
726
|
const maxSelections = poll.maxSelections ?? 1;
|
|
1287
|
-
const result = await sendPollMSTeams({
|
|
727
|
+
const result = await require_send.sendPollMSTeams({
|
|
1288
728
|
cfg,
|
|
1289
729
|
to: resolveMSTeamsThreadTarget(to, threadId),
|
|
1290
730
|
question: poll.question,
|
|
@@ -1345,10 +785,11 @@ async function probeMSTeams(cfg) {
|
|
|
1345
785
|
})) throw new Error("Failed to acquire bot token");
|
|
1346
786
|
let graph;
|
|
1347
787
|
try {
|
|
1348
|
-
const
|
|
788
|
+
const graphTokenValue = await require_resolve_allowlist.withMSTeamsRequestDeadline({
|
|
1349
789
|
label: "MS Teams Graph probe token",
|
|
1350
790
|
work: () => tokenProvider.getAccessToken("https://graph.microsoft.com")
|
|
1351
|
-
})
|
|
791
|
+
});
|
|
792
|
+
const accessToken = require_resolve_allowlist.readAccessToken(graphTokenValue);
|
|
1352
793
|
const payload = accessToken ? decodeJwtPayload(accessToken) : null;
|
|
1353
794
|
graph = {
|
|
1354
795
|
ok: true,
|
|
@@ -1400,8 +841,8 @@ async function probeMSTeams(cfg) {
|
|
|
1400
841
|
//#region extensions/msteams/src/channel.runtime.ts
|
|
1401
842
|
const msTeamsChannelRuntime = {
|
|
1402
843
|
addParticipantMSTeams,
|
|
1403
|
-
deleteMessageMSTeams,
|
|
1404
|
-
editMessageMSTeams,
|
|
844
|
+
deleteMessageMSTeams: require_send.deleteMessageMSTeams,
|
|
845
|
+
editMessageMSTeams: require_send.editMessageMSTeams,
|
|
1405
846
|
getChannelInfoMSTeams,
|
|
1406
847
|
getMemberInfoMSTeams,
|
|
1407
848
|
getMessageMSTeams,
|
|
@@ -1419,8 +860,8 @@ const msTeamsChannelRuntime = {
|
|
|
1419
860
|
listMSTeamsDirectoryPeersLive,
|
|
1420
861
|
msteamsOutbound: { ...msteamsOutbound },
|
|
1421
862
|
probeMSTeams,
|
|
1422
|
-
sendAdaptiveCardMSTeams,
|
|
1423
|
-
sendMessageMSTeams
|
|
863
|
+
sendAdaptiveCardMSTeams: require_send.sendAdaptiveCardMSTeams,
|
|
864
|
+
sendMessageMSTeams: require_send.sendMessageMSTeams
|
|
1424
865
|
};
|
|
1425
866
|
//#endregion
|
|
1426
867
|
exports.msTeamsChannelRuntime = msTeamsChannelRuntime;
|