@openclaw/msteams 2026.7.1 → 2026.7.2-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.cjs +8 -0
- package/dist/{channel-Cf5LJ4aO.js → channel-BSyPdpGN.cjs} +641 -227
- package/dist/channel-config-api.cjs +3 -0
- package/dist/channel-plugin-api.cjs +3 -0
- package/dist/channel.runtime-DQTOzzet.cjs +1372 -0
- package/dist/{config-schema-BL4qQZiA.js → config-schema-BSNLJUta.cjs} +13 -3
- package/dist/{directory-contract-api.js → directory-contract-api.cjs} +8 -7
- package/dist/{doctor-contract-api.js → doctor-contract-api.cjs} +73 -57
- package/dist/index.cjs +21 -0
- package/dist/{probe-BnyZRZsD.js → messenger-DtS9gqkV.cjs} +369 -861
- package/dist/{oauth-BifWxWzq.js → oauth-C5E5powI.cjs} +21 -21
- package/dist/{polls-B_hs4aKm.js → polls-BhoI4VaN.cjs} +188 -38
- package/dist/{resolve-allowlist-Dnw4aNOu.js → resolve-allowlist-CyQ57MfH.cjs} +817 -140
- package/dist/rolldown-runtime-D6vf50IK.cjs +28 -0
- package/dist/runtime-api.cjs +207 -0
- package/dist/runtime-gZTAuFux.cjs +24 -0
- package/dist/secret-contract-api.cjs +31 -0
- package/dist/setup-entry.cjs +14 -0
- package/dist/setup-plugin-api.cjs +65 -0
- package/dist/{setup-surface-qW-ECHL-.js → setup-surface-BDTPN3dX.cjs} +123 -49
- package/dist/{src-DZFs5XtZ.js → src-CUMz2B6f.cjs} +672 -740
- package/dist/{sso-token-store-DrVbnCUF.js → sso-token-store-CktCz88k.cjs} +51 -10
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +10 -31
- package/package.json +8 -7
- package/dist/api.js +0 -3
- package/dist/channel-config-api.js +0 -2
- package/dist/channel-plugin-api.js +0 -2
- package/dist/channel.runtime-Bwu6Tjhf.js +0 -664
- package/dist/index.js +0 -22
- package/dist/runtime-BS5AZrKK.js +0 -8
- package/dist/runtime-api.js +0 -20
- package/dist/secret-contract-api.js +0 -35
- package/dist/setup-entry.js +0 -15
- package/dist/setup-plugin-api.js +0 -64
|
@@ -1,24 +1,129 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-D6vf50IK.cjs");
|
|
2
|
+
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
3
|
+
require("./runtime-api.cjs");
|
|
4
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CyQ57MfH.cjs");
|
|
5
|
+
const require_setup_surface = require("./setup-surface-BDTPN3dX.cjs");
|
|
6
|
+
const require_polls = require("./polls-BhoI4VaN.cjs");
|
|
7
|
+
let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
|
|
8
|
+
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
9
|
+
let openclaw_plugin_sdk_reply_payload = require("openclaw/plugin-sdk/reply-payload");
|
|
10
|
+
let openclaw_plugin_sdk_provider_http = require("openclaw/plugin-sdk/provider-http");
|
|
11
|
+
let node_dns_promises = require("node:dns/promises");
|
|
12
|
+
let openclaw_plugin_sdk_ssrf_policy = require("openclaw/plugin-sdk/ssrf-policy");
|
|
13
|
+
let openclaw_plugin_sdk_text_utility_runtime = require("openclaw/plugin-sdk/text-utility-runtime");
|
|
14
|
+
let node_path = require("node:path");
|
|
15
|
+
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
16
|
+
let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
|
|
17
|
+
let node_crypto = require("node:crypto");
|
|
18
|
+
node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
|
|
19
|
+
let openclaw_plugin_sdk_reply_chunking = require("openclaw/plugin-sdk/reply-chunking");
|
|
20
|
+
let openclaw_plugin_sdk_web_media = require("openclaw/plugin-sdk/web-media");
|
|
21
|
+
let openclaw_plugin_sdk_media_runtime = require("openclaw/plugin-sdk/media-runtime");
|
|
22
|
+
//#region extensions/msteams/src/graph-thread.ts
|
|
23
|
+
/**
|
|
24
|
+
* Strip HTML tags from Teams message content, preserving @mention display names.
|
|
25
|
+
* Teams wraps mentions in <at>Name</at> tags.
|
|
26
|
+
*/
|
|
27
|
+
function stripHtmlFromTeamsMessage(html) {
|
|
28
|
+
let text = html.replace(/<at[^>]*>(.*?)<\/at>/gi, "@$1");
|
|
29
|
+
text = text.replace(/<[^>]*>/g, " ");
|
|
30
|
+
text = (0, openclaw_plugin_sdk_html_entity_runtime.decodeHtmlEntities)(text).replaceAll("\xA0", " ");
|
|
31
|
+
return text.replace(/\s+/g, " ").trim();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Fetch a single channel message (the parent/root of a thread).
|
|
35
|
+
* Returns undefined on error so callers can degrade gracefully.
|
|
36
|
+
*/
|
|
37
|
+
async function fetchChannelMessage(token, groupId, channelId, messageId, deadline) {
|
|
38
|
+
const path = `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}?$select=id,from,body,createdDateTime`;
|
|
39
|
+
try {
|
|
40
|
+
return await require_resolve_allowlist.fetchGraphJson({
|
|
41
|
+
token,
|
|
42
|
+
path,
|
|
43
|
+
...deadline ? { deadline } : {}
|
|
44
|
+
});
|
|
45
|
+
} catch {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Fetch a single chat message's full text via Graph and return plain text.
|
|
51
|
+
*
|
|
52
|
+
* Used to recover the complete quoted message for Teams quote replies: the
|
|
53
|
+
* inbound blockquote only carries a Teams-truncated `preview` snippet. The
|
|
54
|
+
* app-only `GET /chats/{chatId}/messages/{messageId}` endpoint IS permitted
|
|
55
|
+
* with the `Chat.Read.All` application permission.
|
|
56
|
+
*
|
|
57
|
+
* Returns undefined on any failure so callers degrade to the truncated preview.
|
|
58
|
+
*/
|
|
59
|
+
async function fetchChatMessageText(token, chatId, messageId, deadline) {
|
|
60
|
+
const path = `/chats/${encodeURIComponent(chatId)}/messages/${encodeURIComponent(messageId)}`;
|
|
61
|
+
try {
|
|
62
|
+
const msg = await require_resolve_allowlist.fetchGraphJson({
|
|
63
|
+
token,
|
|
64
|
+
path,
|
|
65
|
+
...deadline ? { deadline } : {}
|
|
66
|
+
});
|
|
67
|
+
const raw = msg.body?.content ?? "";
|
|
68
|
+
return (msg.body?.contentType === "html" ? stripHtmlFromTeamsMessage(raw) : raw.trim()) || void 0;
|
|
69
|
+
} catch {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Fetch thread replies for a channel message, ordered chronologically.
|
|
75
|
+
*
|
|
76
|
+
* **Limitation:** The Graph API replies endpoint (`/messages/{id}/replies`) does not
|
|
77
|
+
* support `$orderby`, so results are always returned in ascending (oldest-first) order.
|
|
78
|
+
* Combined with the `$top` cap of 50, this means only the **oldest 50 replies** are
|
|
79
|
+
* returned for long threads — newer replies are silently omitted. There is currently no
|
|
80
|
+
* Graph API workaround for this; pagination via `@odata.nextLink` can retrieve more
|
|
81
|
+
* replies but still in ascending order only.
|
|
82
|
+
*/
|
|
83
|
+
async function fetchThreadReplies(token, groupId, channelId, messageId, limit = 50, deadline) {
|
|
84
|
+
return (await require_resolve_allowlist.fetchGraphJson({
|
|
85
|
+
token,
|
|
86
|
+
path: `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}/replies?$top=${Math.min(Math.max(limit, 1), 50)}&$select=id,from,body,createdDateTime`,
|
|
87
|
+
...deadline ? { deadline } : {}
|
|
88
|
+
})).value ?? [];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Format thread messages into a context string for the agent.
|
|
92
|
+
* Skips the current message (by id) and blank messages.
|
|
93
|
+
*/
|
|
94
|
+
function formatThreadContext(messages, currentMessageId) {
|
|
95
|
+
const lines = [];
|
|
96
|
+
for (const msg of messages) {
|
|
97
|
+
if (msg.id && msg.id === currentMessageId) continue;
|
|
98
|
+
const sender = msg.from?.user?.displayName ?? msg.from?.application?.displayName ?? "unknown";
|
|
99
|
+
const contentType = msg.body?.contentType ?? "text";
|
|
100
|
+
const rawContent = msg.body?.content ?? "";
|
|
101
|
+
const content = contentType === "html" ? stripHtmlFromTeamsMessage(rawContent) : rawContent.trim();
|
|
102
|
+
if (!content) continue;
|
|
103
|
+
lines.push(`${sender}: ${content}`);
|
|
104
|
+
}
|
|
105
|
+
return lines.join("\n");
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region extensions/msteams/src/reaction-types.ts
|
|
109
|
+
const TEAMS_REACTION_EMOJI = {
|
|
110
|
+
like: "👍",
|
|
111
|
+
heart: "❤️",
|
|
112
|
+
laugh: "😆",
|
|
113
|
+
surprised: "😮",
|
|
114
|
+
sad: "😢",
|
|
115
|
+
angry: "😡"
|
|
116
|
+
};
|
|
117
|
+
const TEAMS_REACTION_TYPES = Object.keys(TEAMS_REACTION_EMOJI);
|
|
118
|
+
function getMSTeamsReactionEmoji(raw) {
|
|
119
|
+
return TEAMS_REACTION_EMOJI[raw.trim().toLowerCase()];
|
|
120
|
+
}
|
|
121
|
+
function resolveMSTeamsReactionEmoji(raw) {
|
|
122
|
+
const normalized = raw.trim();
|
|
123
|
+
if (!normalized) throw new Error(`Reaction type is required. Common types: ${TEAMS_REACTION_TYPES.join(", ")}`);
|
|
124
|
+
return getMSTeamsReactionEmoji(normalized) ?? normalized;
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
22
127
|
//#region extensions/msteams/src/file-consent.ts
|
|
23
128
|
/**
|
|
24
129
|
* FileConsentCard utilities for MS Teams large file uploads (>4MB) in personal chats.
|
|
@@ -52,7 +157,7 @@ const CONSENT_UPLOAD_HOST_ALLOWLIST = [
|
|
|
52
157
|
* Returns true if the given IPv4 or IPv6 address is private, internal, or
|
|
53
158
|
* special-use and must never be reached via consent uploads.
|
|
54
159
|
*/
|
|
55
|
-
const isPrivateOrReservedIP = isPrivateIpAddress;
|
|
160
|
+
const isPrivateOrReservedIP = openclaw_plugin_sdk_ssrf_policy.isPrivateIpAddress;
|
|
56
161
|
/**
|
|
57
162
|
* Validate that a consent upload URL is safe to PUT to.
|
|
58
163
|
* Checks:
|
|
@@ -70,9 +175,9 @@ async function validateConsentUploadUrl(url, opts) {
|
|
|
70
175
|
throw new Error("Consent upload URL is not a valid URL");
|
|
71
176
|
}
|
|
72
177
|
if (parsed.protocol !== "https:") throw new Error(`Consent upload URL must use HTTPS, got ${parsed.protocol}`);
|
|
73
|
-
const hostname = normalizeLowercaseStringOrEmpty(parsed.hostname);
|
|
178
|
+
const hostname = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(parsed.hostname);
|
|
74
179
|
if (!(opts?.allowlist ?? CONSENT_UPLOAD_HOST_ALLOWLIST).some((entry) => hostname === entry || hostname.endsWith(`.${entry}`))) throw new Error(`Consent upload URL hostname "${hostname}" is not in the allowed domains`);
|
|
75
|
-
const resolveFn = opts?.resolveFn ?? ((name) => lookup(name, { all: true }));
|
|
180
|
+
const resolveFn = opts?.resolveFn ?? ((name) => (0, node_dns_promises.lookup)(name, { all: true }));
|
|
76
181
|
let resolved;
|
|
77
182
|
try {
|
|
78
183
|
const result = await resolveFn(hostname);
|
|
@@ -141,15 +246,16 @@ function parseFileConsentInvoke(activity) {
|
|
|
141
246
|
*/
|
|
142
247
|
async function uploadToConsentUrl(params) {
|
|
143
248
|
await validateConsentUploadUrl(params.url, params.validationOpts);
|
|
144
|
-
const
|
|
249
|
+
const fetchFn = params.fetchFn ?? fetch;
|
|
250
|
+
const res = await (0, openclaw_plugin_sdk_text_utility_runtime.fetchWithTimeout)(params.url, {
|
|
145
251
|
method: "PUT",
|
|
146
252
|
headers: {
|
|
147
|
-
"User-Agent": buildUserAgent(),
|
|
253
|
+
"User-Agent": require_resolve_allowlist.buildUserAgent(),
|
|
148
254
|
"Content-Type": params.contentType ?? "application/octet-stream",
|
|
149
255
|
"Content-Range": `bytes 0-${params.buffer.length - 1}/${params.buffer.length}`
|
|
150
256
|
},
|
|
151
257
|
body: new Uint8Array(params.buffer)
|
|
152
|
-
});
|
|
258
|
+
}, params.timeoutMs ?? require_resolve_allowlist.resolveMSTeamsSharePointUploadTimeoutMs(params.buffer.length), fetchFn);
|
|
153
259
|
if (!res.ok) throw new Error(`File upload to consent URL failed: ${res.status} ${res.statusText}`);
|
|
154
260
|
}
|
|
155
261
|
//#endregion
|
|
@@ -166,21 +272,21 @@ const PENDING_UPLOAD_META_NAMESPACE = "pending-uploads";
|
|
|
166
272
|
const PENDING_UPLOAD_CHUNKS_NAMESPACE = "pending-upload-chunks";
|
|
167
273
|
const PENDING_UPLOAD_LOCK_FILENAME = "msteams-pending-uploads.sqlite.lock";
|
|
168
274
|
function createMetaStore(options) {
|
|
169
|
-
return getMSTeamsRuntime().state.openKeyedStore({
|
|
275
|
+
return require_runtime.getMSTeamsRuntime().state.openKeyedStore({
|
|
170
276
|
namespace: PENDING_UPLOAD_META_NAMESPACE,
|
|
171
277
|
maxEntries: PENDING_UPLOAD_META_MAX_ENTRIES,
|
|
172
|
-
env: resolveMSTeamsSqliteStateEnv(options)
|
|
278
|
+
env: require_polls.resolveMSTeamsSqliteStateEnv(options)
|
|
173
279
|
});
|
|
174
280
|
}
|
|
175
281
|
function createChunkStore(options) {
|
|
176
|
-
return getMSTeamsRuntime().state.openKeyedStore({
|
|
282
|
+
return require_runtime.getMSTeamsRuntime().state.openKeyedStore({
|
|
177
283
|
namespace: PENDING_UPLOAD_CHUNKS_NAMESPACE,
|
|
178
284
|
maxEntries: MAX_PENDING_UPLOAD_CHUNK_ROWS,
|
|
179
|
-
env: resolveMSTeamsSqliteStateEnv(options)
|
|
285
|
+
env: require_polls.resolveMSTeamsSqliteStateEnv(options)
|
|
180
286
|
});
|
|
181
287
|
}
|
|
182
288
|
function buildUploadKey(id) {
|
|
183
|
-
return `upload:${createHash("sha256").update(id).digest("hex")}`;
|
|
289
|
+
return `upload:${(0, node_crypto.createHash)("sha256").update(id).digest("hex")}`;
|
|
184
290
|
}
|
|
185
291
|
function buildMetaKey(id) {
|
|
186
292
|
return `${buildUploadKey(id)}:meta`;
|
|
@@ -215,13 +321,13 @@ async function registerUploadRows(record, metaStore, chunkStore, ttlMs, overwrit
|
|
|
215
321
|
await pruneUploadStore(metaStore, chunkStore, ttlMs, chunkCount);
|
|
216
322
|
for (let index = 0; index < chunkCount; index += 1) {
|
|
217
323
|
const chunk = buffer.subarray(index * RAW_CHUNK_BYTES, (index + 1) * RAW_CHUNK_BYTES);
|
|
218
|
-
await chunkStore.register(buildChunkKey(record.id, index), toPluginJsonValue({
|
|
324
|
+
await chunkStore.register(buildChunkKey(record.id, index), require_polls.toPluginJsonValue({
|
|
219
325
|
id: record.id,
|
|
220
326
|
index,
|
|
221
327
|
dataBase64: chunk.toString("base64")
|
|
222
328
|
}));
|
|
223
329
|
}
|
|
224
|
-
await metaStore.register(buildMetaKey(record.id), toPluginJsonValue({
|
|
330
|
+
await metaStore.register(buildMetaKey(record.id), require_polls.toPluginJsonValue({
|
|
225
331
|
id: record.id,
|
|
226
332
|
filename: record.filename,
|
|
227
333
|
contentType: record.contentType,
|
|
@@ -233,7 +339,7 @@ async function registerUploadRows(record, metaStore, chunkStore, ttlMs, overwrit
|
|
|
233
339
|
}));
|
|
234
340
|
}
|
|
235
341
|
async function withPendingUploadLock(options, run) {
|
|
236
|
-
return await withMSTeamsSqliteMutationLock(options, PENDING_UPLOAD_LOCK_FILENAME, run);
|
|
342
|
+
return await require_polls.withMSTeamsSqliteMutationLock(options, PENDING_UPLOAD_LOCK_FILENAME, run);
|
|
237
343
|
}
|
|
238
344
|
async function readUploadRows(id, metaStore, chunkStore) {
|
|
239
345
|
const meta = await metaStore.lookup(buildMetaKey(id));
|
|
@@ -326,7 +432,7 @@ async function setPendingUploadActivityIdFs(id, activityId, options) {
|
|
|
326
432
|
await withPendingUploadLock(options, async () => {
|
|
327
433
|
const record = await metaStore.lookup(buildMetaKey(id));
|
|
328
434
|
if (!record || Date.now() - record.createdAt > ttlMs) return;
|
|
329
|
-
await metaStore.register(buildMetaKey(id), toPluginJsonValue({
|
|
435
|
+
await metaStore.register(buildMetaKey(id), require_polls.toPluginJsonValue({
|
|
330
436
|
...record,
|
|
331
437
|
consentCardActivityId: activityId
|
|
332
438
|
}));
|
|
@@ -351,7 +457,7 @@ const PENDING_UPLOAD_TTL_MS = 300 * 1e3;
|
|
|
351
457
|
* Returns the upload ID to include in the FileConsentCard context.
|
|
352
458
|
*/
|
|
353
459
|
function storePendingUpload(upload) {
|
|
354
|
-
const id =
|
|
460
|
+
const id = node_crypto.default.randomUUID();
|
|
355
461
|
const entry = {
|
|
356
462
|
...upload,
|
|
357
463
|
id,
|
|
@@ -485,7 +591,7 @@ async function prepareFileConsentActivityFs(params) {
|
|
|
485
591
|
* True for: personal chat AND (large file OR non-image)
|
|
486
592
|
*/
|
|
487
593
|
function requiresFileConsent(params) {
|
|
488
|
-
const isPersonal = normalizeOptionalLowercaseString(params.conversationType) === "personal";
|
|
594
|
+
const isPersonal = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(params.conversationType) === "personal";
|
|
489
595
|
const isImage = params.contentType?.startsWith("image/") ?? false;
|
|
490
596
|
const isLargeFile = params.bufferSize >= params.thresholdBytes;
|
|
491
597
|
return isPersonal && (isLargeFile || !isImage);
|
|
@@ -496,7 +602,7 @@ function buildTeamsFileInfoCard(file) {
|
|
|
496
602
|
const rawETag = file.eTag;
|
|
497
603
|
const uniqueId = rawETag.replace(/^["']|["']$/g, "").replace(/[{}]/g, "").split(",")[0] ?? rawETag;
|
|
498
604
|
const lastDot = file.name.lastIndexOf(".");
|
|
499
|
-
const fileType = lastDot >= 0 ? normalizeLowercaseStringOrEmpty(file.name.slice(lastDot + 1)) : "";
|
|
605
|
+
const fileType = lastDot >= 0 ? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(file.name.slice(lastDot + 1)) : "";
|
|
500
606
|
return {
|
|
501
607
|
contentType: "application/vnd.microsoft.teams.card.file.info",
|
|
502
608
|
contentUrl: file.webDavUrl,
|
|
@@ -510,11 +616,10 @@ function buildTeamsFileInfoCard(file) {
|
|
|
510
616
|
//#endregion
|
|
511
617
|
//#region extensions/msteams/src/graph-upload.ts
|
|
512
618
|
/**
|
|
513
|
-
*
|
|
619
|
+
* SharePoint upload utilities for MS Teams file sending.
|
|
514
620
|
*
|
|
515
621
|
* For group chats and channels, files are uploaded to SharePoint and shared via a link.
|
|
516
622
|
* This module provides utilities for:
|
|
517
|
-
* - Uploading files to OneDrive (personal scope - now deprecated for bot use)
|
|
518
623
|
* - Uploading files to SharePoint (group/channel scope)
|
|
519
624
|
* - Creating sharing links (organization-wide or per-user)
|
|
520
625
|
* - Getting chat members for per-user sharing
|
|
@@ -522,80 +627,10 @@ function buildTeamsFileInfoCard(file) {
|
|
|
522
627
|
const GRAPH_ROOT = "https://graph.microsoft.com/v1.0";
|
|
523
628
|
const GRAPH_BETA = "https://graph.microsoft.com/beta";
|
|
524
629
|
const GRAPH_SCOPE = "https://graph.microsoft.com";
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
async function uploadToOneDrive(params) {
|
|
530
|
-
const fetchFn = params.fetchFn ?? fetch;
|
|
531
|
-
const token = await params.tokenProvider.getAccessToken(GRAPH_SCOPE);
|
|
532
|
-
const uploadPath = `/OpenClawShared/${encodeURIComponent(params.filename)}`;
|
|
533
|
-
const res = await fetchFn(`${GRAPH_ROOT}/me/drive/root:${uploadPath}:/content`, {
|
|
534
|
-
method: "PUT",
|
|
535
|
-
headers: {
|
|
536
|
-
"User-Agent": buildUserAgent(),
|
|
537
|
-
Authorization: `Bearer ${token}`,
|
|
538
|
-
"Content-Type": params.contentType ?? "application/octet-stream"
|
|
539
|
-
},
|
|
540
|
-
body: new Uint8Array(params.buffer)
|
|
541
|
-
});
|
|
542
|
-
if (!res.ok) throw await createMSTeamsHttpError(res, "OneDrive upload failed");
|
|
543
|
-
const data = await readProviderJsonResponse(res, "msteams.graph-upload.uploadOneDriveFile");
|
|
544
|
-
if (!data.id || !data.webUrl || !data.name) throw new Error("OneDrive upload response missing required fields");
|
|
545
|
-
return {
|
|
546
|
-
id: data.id,
|
|
547
|
-
webUrl: data.webUrl,
|
|
548
|
-
name: data.name
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
/**
|
|
552
|
-
* Create a sharing link for a OneDrive file.
|
|
553
|
-
* The link allows organization members to view the file.
|
|
554
|
-
*/
|
|
555
|
-
async function createSharingLink(params) {
|
|
556
|
-
const fetchFn = params.fetchFn ?? fetch;
|
|
557
|
-
const token = await params.tokenProvider.getAccessToken(GRAPH_SCOPE);
|
|
558
|
-
const res = await fetchFn(`${GRAPH_ROOT}/me/drive/items/${params.itemId}/createLink`, {
|
|
559
|
-
method: "POST",
|
|
560
|
-
headers: {
|
|
561
|
-
"User-Agent": buildUserAgent(),
|
|
562
|
-
Authorization: `Bearer ${token}`,
|
|
563
|
-
"Content-Type": "application/json"
|
|
564
|
-
},
|
|
565
|
-
body: JSON.stringify({
|
|
566
|
-
type: "view",
|
|
567
|
-
scope: params.scope ?? "organization"
|
|
568
|
-
})
|
|
569
|
-
});
|
|
570
|
-
if (!res.ok) throw await createMSTeamsHttpError(res, "Create sharing link failed");
|
|
571
|
-
const data = await readProviderJsonResponse(res, "msteams.graph-upload.createOneDriveSharingLink");
|
|
572
|
-
if (!data.link?.webUrl) throw new Error("Create sharing link response missing webUrl");
|
|
573
|
-
return { webUrl: data.link.webUrl };
|
|
574
|
-
}
|
|
575
|
-
/**
|
|
576
|
-
* Upload a file to OneDrive and create a sharing link.
|
|
577
|
-
* Convenience function for the common case.
|
|
578
|
-
*/
|
|
579
|
-
async function uploadAndShareOneDrive(params) {
|
|
580
|
-
const uploaded = await uploadToOneDrive({
|
|
581
|
-
buffer: params.buffer,
|
|
582
|
-
filename: params.filename,
|
|
583
|
-
contentType: params.contentType,
|
|
584
|
-
tokenProvider: params.tokenProvider,
|
|
585
|
-
fetchFn: params.fetchFn
|
|
586
|
-
});
|
|
587
|
-
const shareLink = await createSharingLink({
|
|
588
|
-
itemId: uploaded.id,
|
|
589
|
-
tokenProvider: params.tokenProvider,
|
|
590
|
-
scope: params.scope,
|
|
591
|
-
fetchFn: params.fetchFn
|
|
592
|
-
});
|
|
593
|
-
return {
|
|
594
|
-
itemId: uploaded.id,
|
|
595
|
-
webUrl: uploaded.webUrl,
|
|
596
|
-
shareUrl: shareLink.webUrl,
|
|
597
|
-
name: uploaded.name
|
|
598
|
-
};
|
|
630
|
+
function requireMSTeamsSharePointSiteId(siteId) {
|
|
631
|
+
const normalized = siteId?.trim();
|
|
632
|
+
if (!normalized) throw new Error("channels.msteams.sharePointSiteId is required to send files to group chats or channels");
|
|
633
|
+
return normalized;
|
|
599
634
|
}
|
|
600
635
|
/**
|
|
601
636
|
* Upload a file to a SharePoint site.
|
|
@@ -610,14 +645,14 @@ async function uploadToSharePoint(params) {
|
|
|
610
645
|
const res = await fetchFn(`${GRAPH_ROOT}/sites/${params.siteId}/drive/root:${uploadPath}:/content`, {
|
|
611
646
|
method: "PUT",
|
|
612
647
|
headers: {
|
|
613
|
-
"User-Agent": buildUserAgent(),
|
|
648
|
+
"User-Agent": require_resolve_allowlist.buildUserAgent(),
|
|
614
649
|
Authorization: `Bearer ${token}`,
|
|
615
650
|
"Content-Type": params.contentType ?? "application/octet-stream"
|
|
616
651
|
},
|
|
617
652
|
body: new Uint8Array(params.buffer)
|
|
618
653
|
});
|
|
619
|
-
if (!res.ok) throw await createMSTeamsHttpError(res, "SharePoint upload failed");
|
|
620
|
-
const data = await readProviderJsonResponse(res, "msteams.graph-upload.uploadSharePointFile");
|
|
654
|
+
if (!res.ok) throw await require_resolve_allowlist.createMSTeamsHttpError(res, "SharePoint upload failed");
|
|
655
|
+
const data = await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, "msteams.graph-upload.uploadSharePointFile");
|
|
621
656
|
if (!data.id || !data.webUrl || !data.name) throw new Error("SharePoint upload response missing required fields");
|
|
622
657
|
return {
|
|
623
658
|
id: data.id,
|
|
@@ -636,11 +671,11 @@ async function getDriveItemProperties(params) {
|
|
|
636
671
|
const fetchFn = params.fetchFn ?? fetch;
|
|
637
672
|
const token = await params.tokenProvider.getAccessToken(GRAPH_SCOPE);
|
|
638
673
|
const res = await fetchFn(`${GRAPH_ROOT}/sites/${params.siteId}/drive/items/${params.itemId}?$select=eTag,webDavUrl,name`, { headers: {
|
|
639
|
-
"User-Agent": buildUserAgent(),
|
|
674
|
+
"User-Agent": require_resolve_allowlist.buildUserAgent(),
|
|
640
675
|
Authorization: `Bearer ${token}`
|
|
641
676
|
} });
|
|
642
|
-
if (!res.ok) throw await createMSTeamsHttpError(res, "Get driveItem properties failed");
|
|
643
|
-
const data = await readProviderJsonResponse(res, "msteams.graph-upload.getDriveItemProperties");
|
|
677
|
+
if (!res.ok) throw await require_resolve_allowlist.createMSTeamsHttpError(res, "Get driveItem properties failed");
|
|
678
|
+
const data = await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, "msteams.graph-upload.getDriveItemProperties");
|
|
644
679
|
if (!data.eTag || !data.webDavUrl || !data.name) throw new Error("DriveItem response missing required properties (eTag, webDavUrl, or name)");
|
|
645
680
|
return {
|
|
646
681
|
eTag: data.eTag,
|
|
@@ -649,34 +684,6 @@ async function getDriveItemProperties(params) {
|
|
|
649
684
|
};
|
|
650
685
|
}
|
|
651
686
|
/**
|
|
652
|
-
* Resolve the Graph API-native chat ID from a Bot Framework conversation ID.
|
|
653
|
-
*
|
|
654
|
-
* Bot Framework personal DM conversation IDs use formats like `a:1xxx@unq.gbl.spaces`
|
|
655
|
-
* or `8:orgid:xxx` that the Graph API does not accept. Graph API requires the
|
|
656
|
-
* `19:xxx@thread.tacv2` or `19:xxx@unq.gbl.spaces` format.
|
|
657
|
-
*
|
|
658
|
-
* This function looks up the matching Graph chat by querying the bot's chats filtered
|
|
659
|
-
* by the target user's AAD object ID.
|
|
660
|
-
*/
|
|
661
|
-
async function resolveGraphChatId(params) {
|
|
662
|
-
const { botFrameworkConversationId, userAadObjectId, tokenProvider } = params;
|
|
663
|
-
const fetchFn = params.fetchFn ?? fetch;
|
|
664
|
-
if (botFrameworkConversationId.startsWith("19:")) return botFrameworkConversationId;
|
|
665
|
-
const token = await tokenProvider.getAccessToken(GRAPH_SCOPE);
|
|
666
|
-
let path;
|
|
667
|
-
if (userAadObjectId) path = `/me/chats?$filter=${encodeURIComponent(`chatType eq 'oneOnOne' and members/any(m:m/microsoft.graph.aadUserConversationMember/userId eq '${userAadObjectId}')`)}&$select=id`;
|
|
668
|
-
else path = `/me/chats?$filter=${encodeURIComponent("chatType eq 'oneOnOne'")}&$select=id`;
|
|
669
|
-
const res = await fetchFn(`${GRAPH_ROOT}${path}`, { headers: {
|
|
670
|
-
"User-Agent": buildUserAgent(),
|
|
671
|
-
Authorization: `Bearer ${token}`
|
|
672
|
-
} });
|
|
673
|
-
if (!res.ok) return null;
|
|
674
|
-
const chats = (await readProviderJsonResponse(res, "msteams.graph-upload.getOneOnOneChatId")).value ?? [];
|
|
675
|
-
if (userAadObjectId && chats.length > 0 && chats[0]?.id) return chats[0].id;
|
|
676
|
-
if (!userAadObjectId && chats.length === 1 && chats[0]?.id) return chats[0].id;
|
|
677
|
-
return null;
|
|
678
|
-
}
|
|
679
|
-
/**
|
|
680
687
|
* Get members of a Teams chat for per-user sharing.
|
|
681
688
|
* Used to create sharing links scoped to only the chat participants.
|
|
682
689
|
*/
|
|
@@ -684,14 +691,11 @@ async function getChatMembers(params) {
|
|
|
684
691
|
const fetchFn = params.fetchFn ?? fetch;
|
|
685
692
|
const token = await params.tokenProvider.getAccessToken(GRAPH_SCOPE);
|
|
686
693
|
const res = await fetchFn(`${GRAPH_ROOT}/chats/${params.chatId}/members`, { headers: {
|
|
687
|
-
"User-Agent": buildUserAgent(),
|
|
694
|
+
"User-Agent": require_resolve_allowlist.buildUserAgent(),
|
|
688
695
|
Authorization: `Bearer ${token}`
|
|
689
696
|
} });
|
|
690
|
-
if (!res.ok) throw await createMSTeamsHttpError(res, "Get chat members failed");
|
|
691
|
-
return ((await readProviderJsonResponse(res, "msteams.graph-upload.getChatMembers")).value ?? []).map((m) => ({
|
|
692
|
-
aadObjectId: m.userId ?? "",
|
|
693
|
-
displayName: m.displayName
|
|
694
|
-
})).filter((m) => m.aadObjectId);
|
|
697
|
+
if (!res.ok) throw await require_resolve_allowlist.createMSTeamsHttpError(res, "Get chat members failed");
|
|
698
|
+
return ((await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, "msteams.graph-upload.getChatMembers")).value ?? []).map((m) => ({ aadObjectId: m.userId ?? "" })).filter((m) => m.aadObjectId);
|
|
695
699
|
}
|
|
696
700
|
/**
|
|
697
701
|
* Create a sharing link for a SharePoint drive item.
|
|
@@ -711,14 +715,14 @@ async function createSharePointSharingLink(params) {
|
|
|
711
715
|
const res = await fetchFn(`${apiRoot}/sites/${params.siteId}/drive/items/${params.itemId}/createLink`, {
|
|
712
716
|
method: "POST",
|
|
713
717
|
headers: {
|
|
714
|
-
"User-Agent": buildUserAgent(),
|
|
718
|
+
"User-Agent": require_resolve_allowlist.buildUserAgent(),
|
|
715
719
|
Authorization: `Bearer ${token}`,
|
|
716
720
|
"Content-Type": "application/json"
|
|
717
721
|
},
|
|
718
722
|
body: JSON.stringify(body)
|
|
719
723
|
});
|
|
720
|
-
if (!res.ok) throw await createMSTeamsHttpError(res, "Create SharePoint sharing link failed");
|
|
721
|
-
const data = await readProviderJsonResponse(res, "msteams.graph-upload.createSharePointSharingLink");
|
|
724
|
+
if (!res.ok) throw await require_resolve_allowlist.createMSTeamsHttpError(res, "Create SharePoint sharing link failed");
|
|
725
|
+
const data = await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, "msteams.graph-upload.createSharePointSharingLink");
|
|
722
726
|
if (!data.link?.webUrl) throw new Error("Create SharePoint sharing link response missing webUrl");
|
|
723
727
|
return { webUrl: data.link.webUrl };
|
|
724
728
|
}
|
|
@@ -783,7 +787,7 @@ async function getMimeType(url) {
|
|
|
783
787
|
const match = url.match(/^data:([^;,]+)/);
|
|
784
788
|
if (match?.[1]) return match[1];
|
|
785
789
|
}
|
|
786
|
-
return await detectMime({ filePath: url }) ?? "application/octet-stream";
|
|
790
|
+
return await (0, openclaw_plugin_sdk_media_runtime.detectMime)({ filePath: url }) ?? "application/octet-stream";
|
|
787
791
|
}
|
|
788
792
|
/**
|
|
789
793
|
* Extract filename from URL or local path.
|
|
@@ -793,20 +797,20 @@ async function getMimeType(url) {
|
|
|
793
797
|
async function extractFilename(url) {
|
|
794
798
|
if (url.startsWith("data:")) {
|
|
795
799
|
const mime = await getMimeType(url);
|
|
796
|
-
const ext = extensionForMime(mime) ?? ".bin";
|
|
800
|
+
const ext = (0, openclaw_plugin_sdk_media_runtime.extensionForMime)(mime) ?? ".bin";
|
|
797
801
|
return `${mime.startsWith("image/") ? "image" : "file"}${ext}`;
|
|
798
802
|
}
|
|
799
803
|
try {
|
|
800
804
|
const pathname = new URL(url).pathname;
|
|
801
|
-
const basename =
|
|
802
|
-
const existingExt = getFileExtension(pathname);
|
|
805
|
+
const basename = node_path.default.basename(pathname);
|
|
806
|
+
const existingExt = (0, openclaw_plugin_sdk_media_runtime.getFileExtension)(pathname);
|
|
803
807
|
if (basename && existingExt) return basename;
|
|
804
808
|
const mime = await getMimeType(url);
|
|
805
|
-
const ext = extensionForMime(mime) ?? ".bin";
|
|
809
|
+
const ext = (0, openclaw_plugin_sdk_media_runtime.extensionForMime)(mime) ?? ".bin";
|
|
806
810
|
const prefix = mime.startsWith("image/") ? "image" : "file";
|
|
807
811
|
return basename ? `${basename}${ext}` : `${prefix}${ext}`;
|
|
808
812
|
} catch {
|
|
809
|
-
return extractOriginalFilename(url);
|
|
813
|
+
return (0, openclaw_plugin_sdk_media_runtime.extractOriginalFilename)(url);
|
|
810
814
|
}
|
|
811
815
|
}
|
|
812
816
|
/**
|
|
@@ -883,21 +887,21 @@ async function withRevokedProxyFallback(params) {
|
|
|
883
887
|
try {
|
|
884
888
|
return await params.run();
|
|
885
889
|
} catch (err) {
|
|
886
|
-
if (!isRevokedProxyError(err)) throw err;
|
|
890
|
+
if (!require_setup_surface.isRevokedProxyError(err)) throw err;
|
|
887
891
|
params.onRevokedLog?.();
|
|
888
892
|
return await params.onRevoked();
|
|
889
893
|
}
|
|
890
894
|
}
|
|
891
895
|
//#endregion
|
|
892
896
|
//#region extensions/msteams/src/sdk-proactive.ts
|
|
893
|
-
const loadMSTeamsApiModule = createLazyRuntimeModule(() => import("@microsoft/teams.api"));
|
|
897
|
+
const loadMSTeamsApiModule = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeModule)(() => import("@microsoft/teams.api"));
|
|
894
898
|
function resolveThreadedConversationId(conversationId, threadActivityId) {
|
|
895
899
|
if (!threadActivityId) return conversationId.split(";")[0] ?? conversationId;
|
|
896
900
|
return `${conversationId.split(";")[0] ?? conversationId};messageid=${threadActivityId}`;
|
|
897
901
|
}
|
|
898
902
|
function normalizeRequiredServiceUrl(ref) {
|
|
899
903
|
if (!ref.serviceUrl) throw new Error("Invalid stored reference: missing serviceUrl");
|
|
900
|
-
return normalizeBotFrameworkServiceUrl(ref.serviceUrl);
|
|
904
|
+
return require_resolve_allowlist.normalizeBotFrameworkServiceUrl(ref.serviceUrl);
|
|
901
905
|
}
|
|
902
906
|
function buildSdkConversationReference(source, options) {
|
|
903
907
|
const bot = source.agent ?? source.bot ?? void 0;
|
|
@@ -905,7 +909,7 @@ function buildSdkConversationReference(source, options) {
|
|
|
905
909
|
const conversationId = resolveThreadedConversationId(source.conversation.id, options?.threadActivityId);
|
|
906
910
|
const tenantId = source.tenantId ?? source.conversation.tenantId;
|
|
907
911
|
const serviceUrl = normalizeRequiredServiceUrl(source);
|
|
908
|
-
if (options?.serviceUrlBoundary) validateMSTeamsProactiveServiceUrlBoundary({
|
|
912
|
+
if (options?.serviceUrlBoundary) require_resolve_allowlist.validateMSTeamsProactiveServiceUrlBoundary({
|
|
909
913
|
cloud: options.serviceUrlBoundary.cloud,
|
|
910
914
|
conversationId,
|
|
911
915
|
storedServiceUrl: serviceUrl,
|
|
@@ -938,7 +942,7 @@ function getStructuralApiClient(app) {
|
|
|
938
942
|
function sameServiceUrl(left, right) {
|
|
939
943
|
if (!left) return false;
|
|
940
944
|
try {
|
|
941
|
-
return normalizeBotFrameworkServiceUrl(left) === right;
|
|
945
|
+
return require_resolve_allowlist.normalizeBotFrameworkServiceUrl(left) === right;
|
|
942
946
|
} catch {
|
|
943
947
|
return false;
|
|
944
948
|
}
|
|
@@ -1026,14 +1030,14 @@ const AI_GENERATED_ENTITY = {
|
|
|
1026
1030
|
//#region extensions/msteams/src/messenger.ts
|
|
1027
1031
|
/**
|
|
1028
1032
|
* MSTeams-specific media size limit (100MB).
|
|
1029
|
-
* Higher than the default
|
|
1033
|
+
* Higher than the default to support Teams file-consent and SharePoint uploads.
|
|
1030
1034
|
*/
|
|
1031
|
-
const MSTEAMS_MAX_MEDIA_BYTES
|
|
1035
|
+
const MSTEAMS_MAX_MEDIA_BYTES = 100 * 1024 * 1024;
|
|
1032
1036
|
/**
|
|
1033
1037
|
* Threshold for large files that require FileConsentCard flow in personal chats.
|
|
1034
1038
|
* Files >= 4MB use consent flow; smaller images can use inline base64.
|
|
1035
1039
|
*/
|
|
1036
|
-
const FILE_CONSENT_THRESHOLD_BYTES
|
|
1040
|
+
const FILE_CONSENT_THRESHOLD_BYTES = 4 * 1024 * 1024;
|
|
1037
1041
|
function normalizeConversationId(rawId) {
|
|
1038
1042
|
return rawId.split(";")[0] ?? rawId;
|
|
1039
1043
|
}
|
|
@@ -1068,15 +1072,15 @@ function buildConversationReference(ref) {
|
|
|
1068
1072
|
function pushTextMessages(out, text, opts) {
|
|
1069
1073
|
if (!text) return;
|
|
1070
1074
|
if (opts.chunkText) {
|
|
1071
|
-
for (const chunk of getMSTeamsRuntime().channel.text.chunkMarkdownTextWithMode(text, opts.chunkLimit, opts.chunkMode)) {
|
|
1075
|
+
for (const chunk of require_runtime.getMSTeamsRuntime().channel.text.chunkMarkdownTextWithMode(text, opts.chunkLimit, opts.chunkMode)) {
|
|
1072
1076
|
const trimmed = chunk.trim();
|
|
1073
|
-
if (!trimmed || isSilentReplyText(trimmed, SILENT_REPLY_TOKEN)) continue;
|
|
1077
|
+
if (!trimmed || (0, openclaw_plugin_sdk_reply_chunking.isSilentReplyText)(trimmed, openclaw_plugin_sdk_reply_chunking.SILENT_REPLY_TOKEN)) continue;
|
|
1074
1078
|
out.push({ text: trimmed });
|
|
1075
1079
|
}
|
|
1076
1080
|
return;
|
|
1077
1081
|
}
|
|
1078
1082
|
const trimmed = text.trim();
|
|
1079
|
-
if (!trimmed || isSilentReplyText(trimmed, SILENT_REPLY_TOKEN)) return;
|
|
1083
|
+
if (!trimmed || (0, openclaw_plugin_sdk_reply_chunking.isSilentReplyText)(trimmed, openclaw_plugin_sdk_reply_chunking.SILENT_REPLY_TOKEN)) return;
|
|
1080
1084
|
out.push({ text: trimmed });
|
|
1081
1085
|
}
|
|
1082
1086
|
function clampMs(value, maxMs) {
|
|
@@ -1110,12 +1114,12 @@ function renderReplyPayloadsToMessages(replies, options) {
|
|
|
1110
1114
|
const chunkText = options.chunkText !== false;
|
|
1111
1115
|
const chunkMode = options.chunkMode ?? "length";
|
|
1112
1116
|
const mediaMode = options.mediaMode ?? "split";
|
|
1113
|
-
const tableMode = options.tableMode ?? getMSTeamsRuntime().channel.text.resolveMarkdownTableMode({
|
|
1114
|
-
cfg: getMSTeamsRuntime().config.current(),
|
|
1117
|
+
const tableMode = options.tableMode ?? require_runtime.getMSTeamsRuntime().channel.text.resolveMarkdownTableMode({
|
|
1118
|
+
cfg: require_runtime.getMSTeamsRuntime().config.current(),
|
|
1115
1119
|
channel: "msteams"
|
|
1116
1120
|
});
|
|
1117
1121
|
for (const payload of replies) {
|
|
1118
|
-
const reply = resolveSendableOutboundReplyParts(payload, { text: getMSTeamsRuntime().channel.text.convertMarkdownTables(payload.text ?? "", tableMode) });
|
|
1122
|
+
const reply = (0, openclaw_plugin_sdk_reply_payload.resolveSendableOutboundReplyParts)(payload, { text: require_runtime.getMSTeamsRuntime().channel.text.convertMarkdownTables(payload.text ?? "", tableMode) });
|
|
1119
1123
|
if (!reply.hasContent) continue;
|
|
1120
1124
|
if (!reply.hasMedia) {
|
|
1121
1125
|
pushTextMessages(out, reply.text, {
|
|
@@ -1165,18 +1169,18 @@ async function buildActivity(msg, conversationRef, tokenProvider, sharePointSite
|
|
|
1165
1169
|
let contentType = await getMimeType(msg.mediaUrl);
|
|
1166
1170
|
let fileName = await extractFilename(msg.mediaUrl);
|
|
1167
1171
|
if (isLocalPath(msg.mediaUrl)) {
|
|
1168
|
-
const maxBytes = mediaMaxBytes ?? MSTEAMS_MAX_MEDIA_BYTES
|
|
1169
|
-
const media = await loadWebMedia(msg.mediaUrl, maxBytes);
|
|
1172
|
+
const maxBytes = mediaMaxBytes ?? MSTEAMS_MAX_MEDIA_BYTES;
|
|
1173
|
+
const media = await (0, openclaw_plugin_sdk_web_media.loadWebMedia)(msg.mediaUrl, maxBytes);
|
|
1170
1174
|
contentType = media.contentType ?? contentType;
|
|
1171
1175
|
fileName = media.fileName ?? fileName;
|
|
1172
|
-
const conversationType = normalizeOptionalLowercaseString(conversationRef.conversation?.conversationType);
|
|
1176
|
+
const conversationType = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(conversationRef.conversation?.conversationType);
|
|
1173
1177
|
const isPersonal = conversationType === "personal";
|
|
1174
1178
|
const isImage = media.kind === "image";
|
|
1175
1179
|
if (requiresFileConsent({
|
|
1176
1180
|
conversationType,
|
|
1177
1181
|
contentType,
|
|
1178
1182
|
bufferSize: media.buffer.length,
|
|
1179
|
-
thresholdBytes: FILE_CONSENT_THRESHOLD_BYTES
|
|
1183
|
+
thresholdBytes: FILE_CONSENT_THRESHOLD_BYTES
|
|
1180
1184
|
})) {
|
|
1181
1185
|
const conversationId = conversationRef.conversation?.id ?? "unknown";
|
|
1182
1186
|
const { activity: consentActivity, uploadId } = prepareFileConsentActivity({
|
|
@@ -1191,16 +1195,18 @@ async function buildActivity(msg, conversationRef, tokenProvider, sharePointSite
|
|
|
1191
1195
|
consentActivity["_pendingUploadId"] = uploadId;
|
|
1192
1196
|
return consentActivity;
|
|
1193
1197
|
}
|
|
1194
|
-
if (!isPersonal && !isImage
|
|
1195
|
-
const
|
|
1198
|
+
if (!isPersonal && !isImage) {
|
|
1199
|
+
const siteId = requireMSTeamsSharePointSiteId(sharePointSiteId);
|
|
1200
|
+
if (!tokenProvider) throw new Error("MS Teams Graph token provider unavailable for SharePoint file send");
|
|
1201
|
+
const chatId = conversationRef.conversation?.id;
|
|
1196
1202
|
activity.attachments = [buildTeamsFileInfoCard(await getDriveItemProperties({
|
|
1197
|
-
siteId
|
|
1203
|
+
siteId,
|
|
1198
1204
|
itemId: (await uploadAndShareSharePoint({
|
|
1199
1205
|
buffer: media.buffer,
|
|
1200
1206
|
filename: fileName,
|
|
1201
1207
|
contentType,
|
|
1202
1208
|
tokenProvider,
|
|
1203
|
-
siteId
|
|
1209
|
+
siteId,
|
|
1204
1210
|
chatId: chatId ?? void 0,
|
|
1205
1211
|
usePerUserSharing: conversationType === "groupchat"
|
|
1206
1212
|
})).itemId,
|
|
@@ -1208,18 +1214,6 @@ async function buildActivity(msg, conversationRef, tokenProvider, sharePointSite
|
|
|
1208
1214
|
}))];
|
|
1209
1215
|
return activity;
|
|
1210
1216
|
}
|
|
1211
|
-
if (!isPersonal && media.kind !== "image" && tokenProvider) {
|
|
1212
|
-
const uploaded = await uploadAndShareOneDrive({
|
|
1213
|
-
buffer: media.buffer,
|
|
1214
|
-
filename: fileName,
|
|
1215
|
-
contentType,
|
|
1216
|
-
tokenProvider
|
|
1217
|
-
});
|
|
1218
|
-
const fileLink = `📎 [${uploaded.name}](${uploaded.shareUrl})`;
|
|
1219
|
-
const existingText = typeof activity.text === "string" ? activity.text : void 0;
|
|
1220
|
-
activity.text = existingText ? `${existingText}\n\n${fileLink}` : fileLink;
|
|
1221
|
-
return activity;
|
|
1222
|
-
}
|
|
1223
1217
|
const base64 = media.buffer.toString("base64");
|
|
1224
1218
|
contentUrl = `data:${media.contentType};base64,${base64}`;
|
|
1225
1219
|
}
|
|
@@ -1240,7 +1234,7 @@ async function sendMSTeamsMessages(params) {
|
|
|
1240
1234
|
for (const attempt of Array.from({ length: retryOptions.maxAttempts }, (_, index) => index + 1)) try {
|
|
1241
1235
|
return await sendOnce();
|
|
1242
1236
|
} catch (err) {
|
|
1243
|
-
const classification = classifyMSTeamsSendError(err);
|
|
1237
|
+
const classification = require_setup_surface.classifyMSTeamsSendError(err);
|
|
1244
1238
|
if (!(attempt < retryOptions.maxAttempts && shouldRetry(classification))) throw err;
|
|
1245
1239
|
const delayMs = computeRetryDelayMs(attempt, classification, retryOptions);
|
|
1246
1240
|
const nextAttempt = attempt + 1;
|
|
@@ -1252,7 +1246,7 @@ async function sendMSTeamsMessages(params) {
|
|
|
1252
1246
|
delayMs,
|
|
1253
1247
|
classification
|
|
1254
1248
|
});
|
|
1255
|
-
await sleep(delayMs);
|
|
1249
|
+
await (0, openclaw_plugin_sdk_text_utility_runtime.sleep)(delayMs);
|
|
1256
1250
|
}
|
|
1257
1251
|
throw new Error("unreachable Teams send retry loop exit");
|
|
1258
1252
|
};
|
|
@@ -1312,675 +1306,189 @@ async function sendMSTeamsMessages(params) {
|
|
|
1312
1306
|
return await sendProactively(messages, 0);
|
|
1313
1307
|
}
|
|
1314
1308
|
//#endregion
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
const routeConfig = resolveMSTeamsRouteConfig({
|
|
1320
|
-
cfg: params.cfg,
|
|
1321
|
-
teamId: params.ref.teamId,
|
|
1322
|
-
conversationId: params.conversationId,
|
|
1323
|
-
allowNameMatching: false
|
|
1324
|
-
});
|
|
1325
|
-
const { replyStyle } = resolveMSTeamsReplyPolicy({
|
|
1326
|
-
isDirectMessage: false,
|
|
1327
|
-
globalConfig: params.cfg,
|
|
1328
|
-
teamConfig: routeConfig.teamConfig,
|
|
1329
|
-
channelConfig: routeConfig.channelConfig
|
|
1330
|
-
});
|
|
1331
|
-
return replyStyle;
|
|
1332
|
-
}
|
|
1333
|
-
/**
|
|
1334
|
-
* Parse the target value into a conversation reference lookup key.
|
|
1335
|
-
* Supported formats:
|
|
1336
|
-
* - conversation:19:abc@thread.tacv2 → lookup by conversation ID
|
|
1337
|
-
* - user:aad-object-id → lookup by user AAD object ID
|
|
1338
|
-
* - 19:abc@thread.tacv2 → direct conversation ID
|
|
1339
|
-
*/
|
|
1340
|
-
function parseRecipient(to) {
|
|
1341
|
-
const trimmed = to.trim();
|
|
1342
|
-
const finalize = (type, id) => {
|
|
1343
|
-
const normalized = id.trim();
|
|
1344
|
-
if (!normalized) throw new Error(`Invalid target value: missing ${type} id`);
|
|
1345
|
-
return {
|
|
1346
|
-
type,
|
|
1347
|
-
id: normalized
|
|
1348
|
-
};
|
|
1349
|
-
};
|
|
1350
|
-
if (trimmed.startsWith("conversation:")) return finalize("conversation", trimmed.slice(13));
|
|
1351
|
-
if (trimmed.startsWith("user:")) return finalize("user", trimmed.slice(5));
|
|
1352
|
-
if (trimmed.startsWith("19:") || trimmed.includes("@thread")) return finalize("conversation", trimmed);
|
|
1353
|
-
return finalize("user", trimmed);
|
|
1354
|
-
}
|
|
1355
|
-
/**
|
|
1356
|
-
* Find a stored conversation reference for the given recipient.
|
|
1357
|
-
*/
|
|
1358
|
-
async function findConversationReference(recipient) {
|
|
1359
|
-
if (recipient.type === "conversation") {
|
|
1360
|
-
const ref = await recipient.store.get(recipient.id);
|
|
1361
|
-
if (ref) return {
|
|
1362
|
-
conversationId: recipient.id,
|
|
1363
|
-
ref
|
|
1364
|
-
};
|
|
1365
|
-
return null;
|
|
1309
|
+
Object.defineProperty(exports, "buildConversationReference", {
|
|
1310
|
+
enumerable: true,
|
|
1311
|
+
get: function() {
|
|
1312
|
+
return buildConversationReference;
|
|
1366
1313
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
};
|
|
1373
|
-
}
|
|
1374
|
-
async function resolveMSTeamsSendContext(params) {
|
|
1375
|
-
const msteamsCfg = params.cfg.channels?.msteams;
|
|
1376
|
-
if (!msteamsCfg?.enabled) throw new Error("msteams provider is not enabled");
|
|
1377
|
-
const creds = resolveMSTeamsCredentials(msteamsCfg);
|
|
1378
|
-
if (!creds) throw new Error("msteams credentials not configured");
|
|
1379
|
-
const store = createMSTeamsConversationStoreState();
|
|
1380
|
-
const recipient = parseRecipient(params.to);
|
|
1381
|
-
const found = await findConversationReference({
|
|
1382
|
-
...recipient,
|
|
1383
|
-
store
|
|
1384
|
-
});
|
|
1385
|
-
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.`);
|
|
1386
|
-
const { conversationId, ref } = found;
|
|
1387
|
-
const log = getMSTeamsRuntime().logging.getChildLogger({ name: "msteams:send" });
|
|
1388
|
-
if (ref.serviceUrl && !isAllowedBotFrameworkServiceUrl(ref.serviceUrl)) {
|
|
1389
|
-
try {
|
|
1390
|
-
await store.remove(conversationId);
|
|
1391
|
-
} catch (err) {
|
|
1392
|
-
log.warn?.("failed to remove blocked msteams conversation reference", {
|
|
1393
|
-
conversationId,
|
|
1394
|
-
error: formatUnknownError(err)
|
|
1395
|
-
});
|
|
1396
|
-
}
|
|
1397
|
-
throw new Error(`Stored Microsoft Teams conversation reference has blocked serviceUrl host: ${describeBotFrameworkServiceUrlHost(ref.serviceUrl)}. The bot must receive a new message from this conversation before it can send proactively.`);
|
|
1314
|
+
});
|
|
1315
|
+
Object.defineProperty(exports, "buildFileInfoCard", {
|
|
1316
|
+
enumerable: true,
|
|
1317
|
+
get: function() {
|
|
1318
|
+
return buildFileInfoCard;
|
|
1398
1319
|
}
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
const resolvedType = normalizeLowercaseStringOrEmpty(safeRef.conversation?.conversationType ?? "");
|
|
1405
|
-
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.`);
|
|
1320
|
+
});
|
|
1321
|
+
Object.defineProperty(exports, "buildTeamsFileInfoCard", {
|
|
1322
|
+
enumerable: true,
|
|
1323
|
+
get: function() {
|
|
1324
|
+
return buildTeamsFileInfoCard;
|
|
1406
1325
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
storedServiceUrl: safeRef.serviceUrl,
|
|
1413
|
-
configuredServiceUrl: sdkCloudOptions.serviceUrl
|
|
1414
|
-
});
|
|
1415
|
-
const tokenProvider = createMSTeamsTokenProvider(app);
|
|
1416
|
-
const storedConversationType = normalizeLowercaseStringOrEmpty(safeRef.conversation?.conversationType ?? "");
|
|
1417
|
-
let conversationType;
|
|
1418
|
-
if (storedConversationType === "personal") conversationType = "personal";
|
|
1419
|
-
else if (storedConversationType === "channel") conversationType = "channel";
|
|
1420
|
-
else conversationType = "groupChat";
|
|
1421
|
-
const replyStyle = resolveMSTeamsProactiveReplyStyle({
|
|
1422
|
-
cfg: msteamsCfg,
|
|
1423
|
-
conversationId,
|
|
1424
|
-
ref: safeRef,
|
|
1425
|
-
conversationType
|
|
1426
|
-
});
|
|
1427
|
-
const sharePointSiteId = msteamsCfg.sharePointSiteId;
|
|
1428
|
-
const mediaMaxBytes = resolveChannelMediaMaxBytes({
|
|
1429
|
-
cfg: params.cfg,
|
|
1430
|
-
resolveChannelLimitMb: ({ cfg }) => cfg.channels?.msteams?.mediaMaxMb
|
|
1431
|
-
});
|
|
1432
|
-
let graphChatId = safeRef.graphChatId ?? void 0;
|
|
1433
|
-
if (graphChatId === void 0 && sharePointSiteId) try {
|
|
1434
|
-
const resolved = await resolveGraphChatId({
|
|
1435
|
-
botFrameworkConversationId: conversationId,
|
|
1436
|
-
userAadObjectId: safeRef.user?.aadObjectId,
|
|
1437
|
-
tokenProvider
|
|
1438
|
-
});
|
|
1439
|
-
graphChatId = resolved;
|
|
1440
|
-
if (resolved) await store.upsert(conversationId, {
|
|
1441
|
-
...safeRef,
|
|
1442
|
-
graphChatId: resolved
|
|
1443
|
-
});
|
|
1444
|
-
else log.warn?.("could not resolve Graph chat ID; file uploads may fail for this conversation", { conversationId });
|
|
1445
|
-
} catch (err) {
|
|
1446
|
-
log.warn?.("failed to resolve Graph chat ID; file uploads may fall back to Bot Framework ID", {
|
|
1447
|
-
conversationId,
|
|
1448
|
-
error: formatUnknownError(err)
|
|
1449
|
-
});
|
|
1450
|
-
graphChatId = null;
|
|
1326
|
+
});
|
|
1327
|
+
Object.defineProperty(exports, "deleteMSTeamsActivityWithReference", {
|
|
1328
|
+
enumerable: true,
|
|
1329
|
+
get: function() {
|
|
1330
|
+
return deleteMSTeamsActivityWithReference;
|
|
1451
1331
|
}
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
log,
|
|
1458
|
-
conversationType,
|
|
1459
|
-
replyStyle,
|
|
1460
|
-
sdkCloudOptions,
|
|
1461
|
-
tokenProvider,
|
|
1462
|
-
sharePointSiteId,
|
|
1463
|
-
mediaMaxBytes,
|
|
1464
|
-
graphChatId
|
|
1465
|
-
};
|
|
1466
|
-
}
|
|
1467
|
-
//#endregion
|
|
1468
|
-
//#region extensions/msteams/src/send.ts
|
|
1469
|
-
/** Threshold for large files that require FileConsentCard flow in personal chats */
|
|
1470
|
-
const FILE_CONSENT_THRESHOLD_BYTES = 4 * 1024 * 1024;
|
|
1471
|
-
/**
|
|
1472
|
-
* MSTeams-specific media size limit (100MB).
|
|
1473
|
-
* Higher than the default because OneDrive upload handles large files well.
|
|
1474
|
-
*/
|
|
1475
|
-
const MSTEAMS_MAX_MEDIA_BYTES = 100 * 1024 * 1024;
|
|
1476
|
-
function createMSTeamsSendReceipt(params) {
|
|
1477
|
-
return createMessageReceiptFromOutboundResults({
|
|
1478
|
-
kind: params.kind,
|
|
1479
|
-
results: params.platformMessageIds.map((messageId) => ({
|
|
1480
|
-
channel: "msteams",
|
|
1481
|
-
messageId,
|
|
1482
|
-
conversationId: params.conversationId
|
|
1483
|
-
}))
|
|
1484
|
-
});
|
|
1485
|
-
}
|
|
1486
|
-
function createMSTeamsSendResult(params) {
|
|
1487
|
-
const platformMessageIds = (params.platformMessageIds?.length ? [...params.platformMessageIds] : [params.messageId]).map((messageId) => messageId.trim()).filter((messageId) => messageId && messageId !== "unknown");
|
|
1488
|
-
return {
|
|
1489
|
-
messageId: params.messageId,
|
|
1490
|
-
conversationId: params.conversationId,
|
|
1491
|
-
receipt: createMSTeamsSendReceipt({
|
|
1492
|
-
conversationId: params.conversationId,
|
|
1493
|
-
platformMessageIds,
|
|
1494
|
-
kind: params.kind
|
|
1495
|
-
}),
|
|
1496
|
-
...params.pendingUploadId ? { pendingUploadId: params.pendingUploadId } : {}
|
|
1497
|
-
};
|
|
1498
|
-
}
|
|
1499
|
-
/**
|
|
1500
|
-
* Send a message to a Teams conversation or user.
|
|
1501
|
-
*
|
|
1502
|
-
* Uses the stored ConversationReference from previous interactions.
|
|
1503
|
-
* The bot must have received at least one message from the conversation
|
|
1504
|
-
* before proactive messaging works.
|
|
1505
|
-
*
|
|
1506
|
-
* File handling by conversation type:
|
|
1507
|
-
* - Personal (1:1) chats: small images (<4MB) use base64, large files and non-images use FileConsentCard
|
|
1508
|
-
* - Group chats / channels: files are uploaded to OneDrive and shared via link
|
|
1509
|
-
*/
|
|
1510
|
-
async function sendMessageMSTeams(params) {
|
|
1511
|
-
const { cfg, to, text, mediaUrl, filename, mediaLocalRoots, mediaReadFile } = params;
|
|
1512
|
-
const tableMode = resolveMarkdownTableMode({
|
|
1513
|
-
cfg,
|
|
1514
|
-
channel: "msteams"
|
|
1515
|
-
});
|
|
1516
|
-
const messageText = convertMarkdownTables(text ?? "", tableMode);
|
|
1517
|
-
const ctx = await resolveMSTeamsSendContext({
|
|
1518
|
-
cfg,
|
|
1519
|
-
to
|
|
1520
|
-
});
|
|
1521
|
-
const { app, conversationId, ref, log, conversationType, tokenProvider, sharePointSiteId, sdkCloudOptions } = ctx;
|
|
1522
|
-
log.debug?.("sending proactive message", {
|
|
1523
|
-
conversationId,
|
|
1524
|
-
conversationType,
|
|
1525
|
-
textLength: messageText.length,
|
|
1526
|
-
hasMedia: Boolean(mediaUrl)
|
|
1527
|
-
});
|
|
1528
|
-
if (mediaUrl) {
|
|
1529
|
-
const media = await loadOutboundMediaFromUrl(mediaUrl, {
|
|
1530
|
-
maxBytes: ctx.mediaMaxBytes ?? MSTEAMS_MAX_MEDIA_BYTES,
|
|
1531
|
-
mediaLocalRoots,
|
|
1532
|
-
mediaReadFile
|
|
1533
|
-
});
|
|
1534
|
-
const isLargeFile = media.buffer.length >= FILE_CONSENT_THRESHOLD_BYTES;
|
|
1535
|
-
const isImage = media.contentType?.startsWith("image/") ?? false;
|
|
1536
|
-
const fallbackFileName = await extractFilename(mediaUrl);
|
|
1537
|
-
const fileName = filename?.trim() || media.fileName || fallbackFileName;
|
|
1538
|
-
log.debug?.("processing media", {
|
|
1539
|
-
fileName,
|
|
1540
|
-
contentType: media.contentType,
|
|
1541
|
-
size: media.buffer.length,
|
|
1542
|
-
isLargeFile,
|
|
1543
|
-
isImage,
|
|
1544
|
-
conversationType
|
|
1545
|
-
});
|
|
1546
|
-
if (requiresFileConsent({
|
|
1547
|
-
conversationType,
|
|
1548
|
-
contentType: media.contentType,
|
|
1549
|
-
bufferSize: media.buffer.length,
|
|
1550
|
-
thresholdBytes: FILE_CONSENT_THRESHOLD_BYTES
|
|
1551
|
-
})) {
|
|
1552
|
-
const { activity, uploadId } = await prepareFileConsentActivityFs({
|
|
1553
|
-
media: {
|
|
1554
|
-
buffer: media.buffer,
|
|
1555
|
-
filename: fileName,
|
|
1556
|
-
contentType: media.contentType
|
|
1557
|
-
},
|
|
1558
|
-
conversationId,
|
|
1559
|
-
description: messageText || void 0
|
|
1560
|
-
});
|
|
1561
|
-
log.debug?.("sending file consent card", {
|
|
1562
|
-
uploadId,
|
|
1563
|
-
fileName,
|
|
1564
|
-
size: media.buffer.length
|
|
1565
|
-
});
|
|
1566
|
-
const messageId = await sendProactiveActivity({
|
|
1567
|
-
app,
|
|
1568
|
-
ref,
|
|
1569
|
-
activity,
|
|
1570
|
-
errorPrefix: "msteams consent card send",
|
|
1571
|
-
serviceUrlBoundary: sdkCloudOptions
|
|
1572
|
-
});
|
|
1573
|
-
setPendingUploadActivityId(uploadId, messageId);
|
|
1574
|
-
await setPendingUploadActivityIdFs(uploadId, messageId);
|
|
1575
|
-
log.info("sent file consent card", {
|
|
1576
|
-
conversationId,
|
|
1577
|
-
messageId,
|
|
1578
|
-
uploadId
|
|
1579
|
-
});
|
|
1580
|
-
return createMSTeamsSendResult({
|
|
1581
|
-
messageId,
|
|
1582
|
-
conversationId,
|
|
1583
|
-
kind: "card",
|
|
1584
|
-
pendingUploadId: uploadId
|
|
1585
|
-
});
|
|
1586
|
-
}
|
|
1587
|
-
if (conversationType === "personal") {
|
|
1588
|
-
const base64 = media.buffer.toString("base64");
|
|
1589
|
-
return sendTextWithMedia(ctx, messageText, `data:${media.contentType};base64,${base64}`);
|
|
1590
|
-
}
|
|
1591
|
-
if (isImage && !sharePointSiteId) {
|
|
1592
|
-
const base64 = media.buffer.toString("base64");
|
|
1593
|
-
return sendTextWithMedia(ctx, messageText, `data:${media.contentType};base64,${base64}`);
|
|
1594
|
-
}
|
|
1595
|
-
try {
|
|
1596
|
-
if (sharePointSiteId) {
|
|
1597
|
-
log.debug?.("uploading to SharePoint for native file card", {
|
|
1598
|
-
fileName,
|
|
1599
|
-
conversationType,
|
|
1600
|
-
siteId: sharePointSiteId
|
|
1601
|
-
});
|
|
1602
|
-
const uploaded = await uploadAndShareSharePoint({
|
|
1603
|
-
buffer: media.buffer,
|
|
1604
|
-
filename: fileName,
|
|
1605
|
-
contentType: media.contentType,
|
|
1606
|
-
tokenProvider,
|
|
1607
|
-
siteId: sharePointSiteId,
|
|
1608
|
-
chatId: ctx.graphChatId ?? conversationId,
|
|
1609
|
-
usePerUserSharing: conversationType === "groupChat"
|
|
1610
|
-
});
|
|
1611
|
-
log.debug?.("SharePoint upload complete", {
|
|
1612
|
-
itemId: uploaded.itemId,
|
|
1613
|
-
shareUrl: uploaded.shareUrl
|
|
1614
|
-
});
|
|
1615
|
-
const driveItem = await getDriveItemProperties({
|
|
1616
|
-
siteId: sharePointSiteId,
|
|
1617
|
-
itemId: uploaded.itemId,
|
|
1618
|
-
tokenProvider
|
|
1619
|
-
});
|
|
1620
|
-
log.debug?.("driveItem properties retrieved", {
|
|
1621
|
-
eTag: driveItem.eTag,
|
|
1622
|
-
webDavUrl: driveItem.webDavUrl
|
|
1623
|
-
});
|
|
1624
|
-
const fileCardAttachment = buildTeamsFileInfoCard(driveItem);
|
|
1625
|
-
const messageId = await sendProactiveActivityRaw({
|
|
1626
|
-
app,
|
|
1627
|
-
ref,
|
|
1628
|
-
activity: {
|
|
1629
|
-
type: "message",
|
|
1630
|
-
text: messageText || void 0,
|
|
1631
|
-
attachments: [fileCardAttachment]
|
|
1632
|
-
},
|
|
1633
|
-
serviceUrlBoundary: sdkCloudOptions
|
|
1634
|
-
});
|
|
1635
|
-
log.info("sent native file card", {
|
|
1636
|
-
conversationId,
|
|
1637
|
-
messageId,
|
|
1638
|
-
fileName: driveItem.name
|
|
1639
|
-
});
|
|
1640
|
-
return createMSTeamsSendResult({
|
|
1641
|
-
messageId,
|
|
1642
|
-
conversationId,
|
|
1643
|
-
kind: "media"
|
|
1644
|
-
});
|
|
1645
|
-
}
|
|
1646
|
-
log.debug?.("uploading to OneDrive (no SharePoint site configured)", {
|
|
1647
|
-
fileName,
|
|
1648
|
-
conversationType
|
|
1649
|
-
});
|
|
1650
|
-
const uploaded = await uploadAndShareOneDrive({
|
|
1651
|
-
buffer: media.buffer,
|
|
1652
|
-
filename: fileName,
|
|
1653
|
-
contentType: media.contentType,
|
|
1654
|
-
tokenProvider
|
|
1655
|
-
});
|
|
1656
|
-
log.debug?.("OneDrive upload complete", {
|
|
1657
|
-
itemId: uploaded.itemId,
|
|
1658
|
-
shareUrl: uploaded.shareUrl
|
|
1659
|
-
});
|
|
1660
|
-
const fileLink = `📎 [${uploaded.name}](${uploaded.shareUrl})`;
|
|
1661
|
-
const messageId = await sendProactiveActivityRaw({
|
|
1662
|
-
app,
|
|
1663
|
-
ref,
|
|
1664
|
-
activity: {
|
|
1665
|
-
type: "message",
|
|
1666
|
-
text: messageText ? `${messageText}\n\n${fileLink}` : fileLink
|
|
1667
|
-
},
|
|
1668
|
-
serviceUrlBoundary: sdkCloudOptions
|
|
1669
|
-
});
|
|
1670
|
-
log.info("sent message with OneDrive file link", {
|
|
1671
|
-
conversationId,
|
|
1672
|
-
messageId,
|
|
1673
|
-
shareUrl: uploaded.shareUrl
|
|
1674
|
-
});
|
|
1675
|
-
return createMSTeamsSendResult({
|
|
1676
|
-
messageId,
|
|
1677
|
-
conversationId,
|
|
1678
|
-
kind: "media"
|
|
1679
|
-
});
|
|
1680
|
-
} catch (err) {
|
|
1681
|
-
const classification = classifyMSTeamsSendError(err);
|
|
1682
|
-
const hint = formatMSTeamsSendErrorHint(classification);
|
|
1683
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1684
|
-
throw new Error(`msteams file send failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1685
|
-
}
|
|
1332
|
+
});
|
|
1333
|
+
Object.defineProperty(exports, "extractFilename", {
|
|
1334
|
+
enumerable: true,
|
|
1335
|
+
get: function() {
|
|
1336
|
+
return extractFilename;
|
|
1686
1337
|
}
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
async function sendTextWithMedia(ctx, text, mediaUrl) {
|
|
1693
|
-
const { app, appId, conversationId, ref, log, tokenProvider, sharePointSiteId, mediaMaxBytes, replyStyle } = ctx;
|
|
1694
|
-
let platformMessageIds;
|
|
1695
|
-
try {
|
|
1696
|
-
platformMessageIds = await sendMSTeamsMessages({
|
|
1697
|
-
replyStyle,
|
|
1698
|
-
app,
|
|
1699
|
-
appId,
|
|
1700
|
-
conversationRef: ref,
|
|
1701
|
-
messages: [{
|
|
1702
|
-
text: text || void 0,
|
|
1703
|
-
mediaUrl
|
|
1704
|
-
}],
|
|
1705
|
-
retry: {},
|
|
1706
|
-
onRetry: (event) => {
|
|
1707
|
-
log.debug?.("retrying send", {
|
|
1708
|
-
conversationId,
|
|
1709
|
-
...event
|
|
1710
|
-
});
|
|
1711
|
-
},
|
|
1712
|
-
tokenProvider,
|
|
1713
|
-
sharePointSiteId,
|
|
1714
|
-
mediaMaxBytes,
|
|
1715
|
-
serviceUrlBoundary: ctx.sdkCloudOptions
|
|
1716
|
-
});
|
|
1717
|
-
} catch (err) {
|
|
1718
|
-
const classification = classifyMSTeamsSendError(err);
|
|
1719
|
-
const hint = formatMSTeamsSendErrorHint(classification);
|
|
1720
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1721
|
-
throw new Error(`msteams send failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1338
|
+
});
|
|
1339
|
+
Object.defineProperty(exports, "extractMessageId", {
|
|
1340
|
+
enumerable: true,
|
|
1341
|
+
get: function() {
|
|
1342
|
+
return extractMessageId;
|
|
1722
1343
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
return {
|
|
1729
|
-
messageId,
|
|
1730
|
-
conversationId,
|
|
1731
|
-
receipt: createMSTeamsSendReceipt({
|
|
1732
|
-
conversationId,
|
|
1733
|
-
platformMessageIds,
|
|
1734
|
-
kind: mediaUrl ? "media" : "text"
|
|
1735
|
-
})
|
|
1736
|
-
};
|
|
1737
|
-
}
|
|
1738
|
-
async function sendProactiveActivityRaw({ app, ref, activity, serviceUrlBoundary }) {
|
|
1739
|
-
return extractMessageId(await sendMSTeamsActivityWithReference(app, buildConversationReference(ref), activity, { serviceUrlBoundary })) ?? "unknown";
|
|
1740
|
-
}
|
|
1741
|
-
async function sendProactiveActivity({ app, ref, activity, errorPrefix, serviceUrlBoundary }) {
|
|
1742
|
-
try {
|
|
1743
|
-
return await sendProactiveActivityRaw({
|
|
1744
|
-
app,
|
|
1745
|
-
ref,
|
|
1746
|
-
activity,
|
|
1747
|
-
serviceUrlBoundary
|
|
1748
|
-
});
|
|
1749
|
-
} catch (err) {
|
|
1750
|
-
const classification = classifyMSTeamsSendError(err);
|
|
1751
|
-
const hint = formatMSTeamsSendErrorHint(classification);
|
|
1752
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1753
|
-
throw new Error(`${errorPrefix} failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1344
|
+
});
|
|
1345
|
+
Object.defineProperty(exports, "fetchChannelMessage", {
|
|
1346
|
+
enumerable: true,
|
|
1347
|
+
get: function() {
|
|
1348
|
+
return fetchChannelMessage;
|
|
1754
1349
|
}
|
|
1755
|
-
}
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
const { cfg, to, question, options, maxSelections } = params;
|
|
1761
|
-
const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({
|
|
1762
|
-
cfg,
|
|
1763
|
-
to
|
|
1764
|
-
});
|
|
1765
|
-
const pollCard = buildMSTeamsPollCard({
|
|
1766
|
-
question,
|
|
1767
|
-
options,
|
|
1768
|
-
maxSelections
|
|
1769
|
-
});
|
|
1770
|
-
log.debug?.("sending poll", {
|
|
1771
|
-
conversationId,
|
|
1772
|
-
pollId: pollCard.pollId,
|
|
1773
|
-
optionCount: pollCard.options.length
|
|
1774
|
-
});
|
|
1775
|
-
const messageId = await sendProactiveActivity({
|
|
1776
|
-
app,
|
|
1777
|
-
ref,
|
|
1778
|
-
activity: {
|
|
1779
|
-
type: "message",
|
|
1780
|
-
attachments: [{
|
|
1781
|
-
contentType: "application/vnd.microsoft.card.adaptive",
|
|
1782
|
-
content: pollCard.card
|
|
1783
|
-
}]
|
|
1784
|
-
},
|
|
1785
|
-
errorPrefix: "msteams poll send",
|
|
1786
|
-
serviceUrlBoundary: sdkCloudOptions
|
|
1787
|
-
});
|
|
1788
|
-
log.info("sent poll", {
|
|
1789
|
-
conversationId,
|
|
1790
|
-
pollId: pollCard.pollId,
|
|
1791
|
-
messageId
|
|
1792
|
-
});
|
|
1793
|
-
return {
|
|
1794
|
-
pollId: pollCard.pollId,
|
|
1795
|
-
messageId,
|
|
1796
|
-
conversationId
|
|
1797
|
-
};
|
|
1798
|
-
}
|
|
1799
|
-
/**
|
|
1800
|
-
* Send an arbitrary Adaptive Card to a Teams conversation or user.
|
|
1801
|
-
*/
|
|
1802
|
-
async function sendAdaptiveCardMSTeams(params) {
|
|
1803
|
-
const { cfg, to, card } = params;
|
|
1804
|
-
const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({
|
|
1805
|
-
cfg,
|
|
1806
|
-
to
|
|
1807
|
-
});
|
|
1808
|
-
log.debug?.("sending adaptive card", {
|
|
1809
|
-
conversationId,
|
|
1810
|
-
cardType: card.type,
|
|
1811
|
-
cardVersion: card.version
|
|
1812
|
-
});
|
|
1813
|
-
const messageId = await sendProactiveActivity({
|
|
1814
|
-
app,
|
|
1815
|
-
ref,
|
|
1816
|
-
activity: {
|
|
1817
|
-
type: "message",
|
|
1818
|
-
attachments: [{
|
|
1819
|
-
contentType: "application/vnd.microsoft.card.adaptive",
|
|
1820
|
-
content: card
|
|
1821
|
-
}]
|
|
1822
|
-
},
|
|
1823
|
-
errorPrefix: "msteams card send",
|
|
1824
|
-
serviceUrlBoundary: sdkCloudOptions
|
|
1825
|
-
});
|
|
1826
|
-
log.info("sent adaptive card", {
|
|
1827
|
-
conversationId,
|
|
1828
|
-
messageId
|
|
1829
|
-
});
|
|
1830
|
-
return {
|
|
1831
|
-
messageId,
|
|
1832
|
-
conversationId
|
|
1833
|
-
};
|
|
1834
|
-
}
|
|
1835
|
-
/**
|
|
1836
|
-
* Edit (update) a previously sent message in a Teams conversation.
|
|
1837
|
-
*
|
|
1838
|
-
* Uses the Bot Framework REST API for proactive edits outside of the
|
|
1839
|
-
* original turn context.
|
|
1840
|
-
*/
|
|
1841
|
-
async function editMessageMSTeams(params) {
|
|
1842
|
-
const { cfg, to, activityId, text } = params;
|
|
1843
|
-
const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({
|
|
1844
|
-
cfg,
|
|
1845
|
-
to
|
|
1846
|
-
});
|
|
1847
|
-
log.debug?.("editing proactive message", {
|
|
1848
|
-
conversationId,
|
|
1849
|
-
activityId,
|
|
1850
|
-
textLength: text.length
|
|
1851
|
-
});
|
|
1852
|
-
try {
|
|
1853
|
-
await updateMSTeamsActivityWithReference(app, buildConversationReference(ref), activityId, {
|
|
1854
|
-
type: "message",
|
|
1855
|
-
id: activityId,
|
|
1856
|
-
text
|
|
1857
|
-
}, { serviceUrlBoundary: sdkCloudOptions });
|
|
1858
|
-
} catch (err) {
|
|
1859
|
-
const classification = classifyMSTeamsSendError(err);
|
|
1860
|
-
const hint = formatMSTeamsSendErrorHint(classification);
|
|
1861
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1862
|
-
throw new Error(`msteams edit failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1350
|
+
});
|
|
1351
|
+
Object.defineProperty(exports, "fetchChatMessageText", {
|
|
1352
|
+
enumerable: true,
|
|
1353
|
+
get: function() {
|
|
1354
|
+
return fetchChatMessageText;
|
|
1863
1355
|
}
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
}
|
|
1870
|
-
/**
|
|
1871
|
-
* Delete a previously sent message in a Teams conversation.
|
|
1872
|
-
*
|
|
1873
|
-
* Uses the Bot Framework REST API for proactive deletes outside of the
|
|
1874
|
-
* original turn context.
|
|
1875
|
-
*/
|
|
1876
|
-
async function deleteMessageMSTeams(params) {
|
|
1877
|
-
const { cfg, to, activityId } = params;
|
|
1878
|
-
const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({
|
|
1879
|
-
cfg,
|
|
1880
|
-
to
|
|
1881
|
-
});
|
|
1882
|
-
log.debug?.("deleting proactive message", {
|
|
1883
|
-
conversationId,
|
|
1884
|
-
activityId
|
|
1885
|
-
});
|
|
1886
|
-
try {
|
|
1887
|
-
await deleteMSTeamsActivityWithReference(app, buildConversationReference(ref), activityId, { serviceUrlBoundary: sdkCloudOptions });
|
|
1888
|
-
} catch (err) {
|
|
1889
|
-
const classification = classifyMSTeamsSendError(err);
|
|
1890
|
-
const hint = formatMSTeamsSendErrorHint(classification);
|
|
1891
|
-
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1892
|
-
throw new Error(`msteams delete failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1356
|
+
});
|
|
1357
|
+
Object.defineProperty(exports, "fetchThreadReplies", {
|
|
1358
|
+
enumerable: true,
|
|
1359
|
+
get: function() {
|
|
1360
|
+
return fetchThreadReplies;
|
|
1893
1361
|
}
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
}
|
|
1900
|
-
//#endregion
|
|
1901
|
-
//#region extensions/msteams/src/probe.ts
|
|
1902
|
-
function decodeJwtPayload(token) {
|
|
1903
|
-
const parts = token.split(".");
|
|
1904
|
-
if (parts.length < 2) return null;
|
|
1905
|
-
const payload = parts[1] ?? "";
|
|
1906
|
-
const normalized = payload.padEnd(payload.length + (4 - payload.length % 4) % 4, "=").replace(/-/g, "+").replace(/_/g, "/");
|
|
1907
|
-
try {
|
|
1908
|
-
const decoded = Buffer.from(normalized, "base64").toString("utf8");
|
|
1909
|
-
const parsed = JSON.parse(decoded);
|
|
1910
|
-
return parsed && typeof parsed === "object" ? parsed : null;
|
|
1911
|
-
} catch {
|
|
1912
|
-
return null;
|
|
1362
|
+
});
|
|
1363
|
+
Object.defineProperty(exports, "formatThreadContext", {
|
|
1364
|
+
enumerable: true,
|
|
1365
|
+
get: function() {
|
|
1366
|
+
return formatThreadContext;
|
|
1913
1367
|
}
|
|
1914
|
-
}
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
}
|
|
1920
|
-
function readScopes(value) {
|
|
1921
|
-
if (typeof value !== "string") return;
|
|
1922
|
-
const out = normalizeStringEntries$1(value.split(/\s+/));
|
|
1923
|
-
return out.length > 0 ? out : void 0;
|
|
1924
|
-
}
|
|
1925
|
-
async function probeMSTeams(cfg) {
|
|
1926
|
-
const creds = resolveMSTeamsCredentials(cfg);
|
|
1927
|
-
if (!creds) return {
|
|
1928
|
-
ok: false,
|
|
1929
|
-
error: "missing credentials (appId, appPassword, tenantId)"
|
|
1930
|
-
};
|
|
1931
|
-
try {
|
|
1932
|
-
const { app } = await loadMSTeamsSdkWithAuth(creds, resolveMSTeamsSdkCloudOptions(cfg));
|
|
1933
|
-
const tokenProvider = createMSTeamsTokenProvider(app);
|
|
1934
|
-
if (!await tokenProvider.getAccessToken("https://api.botframework.com")) throw new Error("Failed to acquire bot token");
|
|
1935
|
-
let graph;
|
|
1936
|
-
try {
|
|
1937
|
-
const accessToken = readAccessToken(await tokenProvider.getAccessToken("https://graph.microsoft.com"));
|
|
1938
|
-
const payload = accessToken ? decodeJwtPayload(accessToken) : null;
|
|
1939
|
-
graph = {
|
|
1940
|
-
ok: true,
|
|
1941
|
-
roles: readStringArray(payload?.roles),
|
|
1942
|
-
scopes: readScopes(payload?.scp)
|
|
1943
|
-
};
|
|
1944
|
-
} catch (err) {
|
|
1945
|
-
graph = {
|
|
1946
|
-
ok: false,
|
|
1947
|
-
error: formatUnknownError(err)
|
|
1948
|
-
};
|
|
1949
|
-
}
|
|
1950
|
-
let delegatedAuth;
|
|
1951
|
-
if (cfg?.delegatedAuth?.enabled) try {
|
|
1952
|
-
const tokens = loadDelegatedTokens();
|
|
1953
|
-
if (tokens) {
|
|
1954
|
-
const isExpired = !isFutureDateTimestampMs(tokens.expiresAt);
|
|
1955
|
-
delegatedAuth = {
|
|
1956
|
-
ok: !isExpired,
|
|
1957
|
-
scopes: tokens.scopes,
|
|
1958
|
-
userPrincipalName: tokens.userPrincipalName,
|
|
1959
|
-
...isExpired ? { error: "token expired (will auto-refresh on next use)" } : {}
|
|
1960
|
-
};
|
|
1961
|
-
} else delegatedAuth = {
|
|
1962
|
-
ok: false,
|
|
1963
|
-
error: "no delegated tokens found (run setup wizard)"
|
|
1964
|
-
};
|
|
1965
|
-
} catch {
|
|
1966
|
-
delegatedAuth = {
|
|
1967
|
-
ok: false,
|
|
1968
|
-
error: "failed to load delegated tokens"
|
|
1969
|
-
};
|
|
1970
|
-
}
|
|
1971
|
-
return {
|
|
1972
|
-
ok: true,
|
|
1973
|
-
appId: creds.appId,
|
|
1974
|
-
...graph ? { graph } : {},
|
|
1975
|
-
...delegatedAuth ? { delegatedAuth } : {}
|
|
1976
|
-
};
|
|
1977
|
-
} catch (err) {
|
|
1978
|
-
return {
|
|
1979
|
-
ok: false,
|
|
1980
|
-
appId: creds.appId,
|
|
1981
|
-
error: formatUnknownError(err)
|
|
1982
|
-
};
|
|
1368
|
+
});
|
|
1369
|
+
Object.defineProperty(exports, "getDriveItemProperties", {
|
|
1370
|
+
enumerable: true,
|
|
1371
|
+
get: function() {
|
|
1372
|
+
return getDriveItemProperties;
|
|
1983
1373
|
}
|
|
1984
|
-
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1374
|
+
});
|
|
1375
|
+
Object.defineProperty(exports, "getMSTeamsReactionEmoji", {
|
|
1376
|
+
enumerable: true,
|
|
1377
|
+
get: function() {
|
|
1378
|
+
return getMSTeamsReactionEmoji;
|
|
1379
|
+
}
|
|
1380
|
+
});
|
|
1381
|
+
Object.defineProperty(exports, "getPendingUpload", {
|
|
1382
|
+
enumerable: true,
|
|
1383
|
+
get: function() {
|
|
1384
|
+
return getPendingUpload;
|
|
1385
|
+
}
|
|
1386
|
+
});
|
|
1387
|
+
Object.defineProperty(exports, "getPendingUploadFs", {
|
|
1388
|
+
enumerable: true,
|
|
1389
|
+
get: function() {
|
|
1390
|
+
return getPendingUploadFs;
|
|
1391
|
+
}
|
|
1392
|
+
});
|
|
1393
|
+
Object.defineProperty(exports, "parseFileConsentInvoke", {
|
|
1394
|
+
enumerable: true,
|
|
1395
|
+
get: function() {
|
|
1396
|
+
return parseFileConsentInvoke;
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1399
|
+
Object.defineProperty(exports, "prepareFileConsentActivityFs", {
|
|
1400
|
+
enumerable: true,
|
|
1401
|
+
get: function() {
|
|
1402
|
+
return prepareFileConsentActivityFs;
|
|
1403
|
+
}
|
|
1404
|
+
});
|
|
1405
|
+
Object.defineProperty(exports, "removePendingUpload", {
|
|
1406
|
+
enumerable: true,
|
|
1407
|
+
get: function() {
|
|
1408
|
+
return removePendingUpload;
|
|
1409
|
+
}
|
|
1410
|
+
});
|
|
1411
|
+
Object.defineProperty(exports, "removePendingUploadFs", {
|
|
1412
|
+
enumerable: true,
|
|
1413
|
+
get: function() {
|
|
1414
|
+
return removePendingUploadFs;
|
|
1415
|
+
}
|
|
1416
|
+
});
|
|
1417
|
+
Object.defineProperty(exports, "renderReplyPayloadsToMessages", {
|
|
1418
|
+
enumerable: true,
|
|
1419
|
+
get: function() {
|
|
1420
|
+
return renderReplyPayloadsToMessages;
|
|
1421
|
+
}
|
|
1422
|
+
});
|
|
1423
|
+
Object.defineProperty(exports, "requireMSTeamsSharePointSiteId", {
|
|
1424
|
+
enumerable: true,
|
|
1425
|
+
get: function() {
|
|
1426
|
+
return requireMSTeamsSharePointSiteId;
|
|
1427
|
+
}
|
|
1428
|
+
});
|
|
1429
|
+
Object.defineProperty(exports, "requiresFileConsent", {
|
|
1430
|
+
enumerable: true,
|
|
1431
|
+
get: function() {
|
|
1432
|
+
return requiresFileConsent;
|
|
1433
|
+
}
|
|
1434
|
+
});
|
|
1435
|
+
Object.defineProperty(exports, "resolveMSTeamsReactionEmoji", {
|
|
1436
|
+
enumerable: true,
|
|
1437
|
+
get: function() {
|
|
1438
|
+
return resolveMSTeamsReactionEmoji;
|
|
1439
|
+
}
|
|
1440
|
+
});
|
|
1441
|
+
Object.defineProperty(exports, "sendMSTeamsActivityWithReference", {
|
|
1442
|
+
enumerable: true,
|
|
1443
|
+
get: function() {
|
|
1444
|
+
return sendMSTeamsActivityWithReference;
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
Object.defineProperty(exports, "sendMSTeamsMessages", {
|
|
1448
|
+
enumerable: true,
|
|
1449
|
+
get: function() {
|
|
1450
|
+
return sendMSTeamsMessages;
|
|
1451
|
+
}
|
|
1452
|
+
});
|
|
1453
|
+
Object.defineProperty(exports, "setPendingUploadActivityId", {
|
|
1454
|
+
enumerable: true,
|
|
1455
|
+
get: function() {
|
|
1456
|
+
return setPendingUploadActivityId;
|
|
1457
|
+
}
|
|
1458
|
+
});
|
|
1459
|
+
Object.defineProperty(exports, "setPendingUploadActivityIdFs", {
|
|
1460
|
+
enumerable: true,
|
|
1461
|
+
get: function() {
|
|
1462
|
+
return setPendingUploadActivityIdFs;
|
|
1463
|
+
}
|
|
1464
|
+
});
|
|
1465
|
+
Object.defineProperty(exports, "stripHtmlFromTeamsMessage", {
|
|
1466
|
+
enumerable: true,
|
|
1467
|
+
get: function() {
|
|
1468
|
+
return stripHtmlFromTeamsMessage;
|
|
1469
|
+
}
|
|
1470
|
+
});
|
|
1471
|
+
Object.defineProperty(exports, "updateMSTeamsActivityWithReference", {
|
|
1472
|
+
enumerable: true,
|
|
1473
|
+
get: function() {
|
|
1474
|
+
return updateMSTeamsActivityWithReference;
|
|
1475
|
+
}
|
|
1476
|
+
});
|
|
1477
|
+
Object.defineProperty(exports, "uploadAndShareSharePoint", {
|
|
1478
|
+
enumerable: true,
|
|
1479
|
+
get: function() {
|
|
1480
|
+
return uploadAndShareSharePoint;
|
|
1481
|
+
}
|
|
1482
|
+
});
|
|
1483
|
+
Object.defineProperty(exports, "uploadToConsentUrl", {
|
|
1484
|
+
enumerable: true,
|
|
1485
|
+
get: function() {
|
|
1486
|
+
return uploadToConsentUrl;
|
|
1487
|
+
}
|
|
1488
|
+
});
|
|
1489
|
+
Object.defineProperty(exports, "withRevokedProxyFallback", {
|
|
1490
|
+
enumerable: true,
|
|
1491
|
+
get: function() {
|
|
1492
|
+
return withRevokedProxyFallback;
|
|
1493
|
+
}
|
|
1494
|
+
});
|