@openclaw/msteams 2026.5.2 → 2026.5.3-beta.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/api.js +3 -0
- package/dist/channel-D7hdreTh.js +984 -0
- package/dist/channel-config-api.js +2 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.runtime-BC1ruIfN.js +573 -0
- package/dist/config-schema-B8QezH6t.js +15 -0
- package/dist/contract-api.js +2 -0
- package/dist/graph-users-9uQJepqr.js +1354 -0
- package/dist/index.js +22 -0
- package/dist/oauth-BWJyilR1.js +114 -0
- package/dist/oauth.token-xxpoLWy5.js +115 -0
- package/dist/policy-DTnU2GR7.js +142 -0
- package/dist/probe-D_H8yFps.js +2194 -0
- package/dist/resolve-allowlist-D41JSziq.js +219 -0
- package/dist/runtime-api-DV1iVMn1.js +28 -0
- package/dist/runtime-api.js +2 -0
- package/dist/secret-contract-BuoEXmPS.js +35 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/setup-entry.js +15 -0
- package/dist/setup-plugin-api.js +64 -0
- package/dist/setup-surface-BLkFQYIQ.js +313 -0
- package/dist/src-CFp1QpFd.js +4064 -0
- package/dist/test-api.js +2 -0
- package/package.json +14 -6
- package/api.ts +0 -3
- package/channel-config-api.ts +0 -1
- package/channel-plugin-api.ts +0 -2
- package/config-api.ts +0 -4
- package/contract-api.ts +0 -4
- package/index.ts +0 -20
- package/runtime-api.ts +0 -73
- package/secret-contract-api.ts +0 -5
- package/setup-entry.ts +0 -13
- package/setup-plugin-api.ts +0 -3
- package/src/ai-entity.ts +0 -7
- package/src/approval-auth.ts +0 -44
- package/src/attachments/bot-framework.test.ts +0 -461
- package/src/attachments/bot-framework.ts +0 -362
- package/src/attachments/download.ts +0 -311
- package/src/attachments/graph.test.ts +0 -416
- package/src/attachments/graph.ts +0 -484
- package/src/attachments/html.ts +0 -122
- package/src/attachments/payload.ts +0 -14
- package/src/attachments/remote-media.test.ts +0 -137
- package/src/attachments/remote-media.ts +0 -112
- package/src/attachments/shared.test.ts +0 -530
- package/src/attachments/shared.ts +0 -626
- package/src/attachments/types.ts +0 -47
- package/src/attachments.graph.test.ts +0 -342
- package/src/attachments.helpers.test.ts +0 -246
- package/src/attachments.test-helpers.ts +0 -17
- package/src/attachments.test.ts +0 -687
- package/src/attachments.ts +0 -18
- package/src/block-streaming-config.test.ts +0 -61
- package/src/channel-api.ts +0 -1
- package/src/channel.actions.test.ts +0 -742
- package/src/channel.directory.test.ts +0 -200
- package/src/channel.runtime.ts +0 -56
- package/src/channel.setup.ts +0 -77
- package/src/channel.test.ts +0 -128
- package/src/channel.ts +0 -1136
- package/src/config-schema.ts +0 -6
- package/src/config-ui-hints.ts +0 -12
- package/src/conversation-store-fs.test.ts +0 -74
- package/src/conversation-store-fs.ts +0 -149
- package/src/conversation-store-helpers.test.ts +0 -202
- package/src/conversation-store-helpers.ts +0 -105
- package/src/conversation-store-memory.ts +0 -51
- package/src/conversation-store.shared.test.ts +0 -225
- package/src/conversation-store.ts +0 -71
- package/src/directory-live.test.ts +0 -156
- package/src/directory-live.ts +0 -111
- package/src/doctor.ts +0 -27
- package/src/errors.test.ts +0 -133
- package/src/errors.ts +0 -246
- package/src/feedback-reflection-prompt.ts +0 -117
- package/src/feedback-reflection-store.ts +0 -114
- package/src/feedback-reflection.test.ts +0 -237
- package/src/feedback-reflection.ts +0 -283
- package/src/file-consent-helpers.test.ts +0 -326
- package/src/file-consent-helpers.ts +0 -126
- package/src/file-consent-invoke.ts +0 -150
- package/src/file-consent.test.ts +0 -363
- package/src/file-consent.ts +0 -287
- package/src/graph-chat.ts +0 -55
- package/src/graph-group-management.test.ts +0 -318
- package/src/graph-group-management.ts +0 -168
- package/src/graph-members.test.ts +0 -89
- package/src/graph-members.ts +0 -48
- package/src/graph-messages.actions.test.ts +0 -243
- package/src/graph-messages.read.test.ts +0 -391
- package/src/graph-messages.search.test.ts +0 -213
- package/src/graph-messages.test-helpers.ts +0 -50
- package/src/graph-messages.ts +0 -534
- package/src/graph-teams.test.ts +0 -215
- package/src/graph-teams.ts +0 -114
- package/src/graph-thread.test.ts +0 -246
- package/src/graph-thread.ts +0 -146
- package/src/graph-upload.test.ts +0 -258
- package/src/graph-upload.ts +0 -531
- package/src/graph-users.ts +0 -29
- package/src/graph.test.ts +0 -516
- package/src/graph.ts +0 -293
- package/src/inbound.test.ts +0 -221
- package/src/inbound.ts +0 -148
- package/src/index.ts +0 -4
- package/src/media-helpers.test.ts +0 -202
- package/src/media-helpers.ts +0 -105
- package/src/mentions.test.ts +0 -244
- package/src/mentions.ts +0 -114
- package/src/messenger.test.ts +0 -865
- package/src/messenger.ts +0 -605
- package/src/monitor-handler/access.ts +0 -125
- package/src/monitor-handler/inbound-media.test.ts +0 -289
- package/src/monitor-handler/inbound-media.ts +0 -180
- package/src/monitor-handler/message-handler-mock-support.test-support.ts +0 -28
- package/src/monitor-handler/message-handler.authz.test.ts +0 -669
- package/src/monitor-handler/message-handler.dm-media.test.ts +0 -54
- package/src/monitor-handler/message-handler.test-support.ts +0 -100
- package/src/monitor-handler/message-handler.thread-parent.test.ts +0 -223
- package/src/monitor-handler/message-handler.thread-session.test.ts +0 -77
- package/src/monitor-handler/message-handler.ts +0 -1000
- package/src/monitor-handler/reaction-handler.test.ts +0 -267
- package/src/monitor-handler/reaction-handler.ts +0 -210
- package/src/monitor-handler/thread-session.ts +0 -17
- package/src/monitor-handler.adaptive-card.test.ts +0 -162
- package/src/monitor-handler.feedback-authz.test.ts +0 -314
- package/src/monitor-handler.file-consent.test.ts +0 -423
- package/src/monitor-handler.sso.test.ts +0 -563
- package/src/monitor-handler.test-helpers.ts +0 -180
- package/src/monitor-handler.ts +0 -534
- package/src/monitor-handler.types.ts +0 -27
- package/src/monitor-types.ts +0 -6
- package/src/monitor.lifecycle.test.ts +0 -278
- package/src/monitor.test.ts +0 -119
- package/src/monitor.ts +0 -442
- package/src/oauth.flow.ts +0 -77
- package/src/oauth.shared.ts +0 -37
- package/src/oauth.test.ts +0 -305
- package/src/oauth.token.ts +0 -158
- package/src/oauth.ts +0 -130
- package/src/outbound.test.ts +0 -130
- package/src/outbound.ts +0 -71
- package/src/pending-uploads-fs.test.ts +0 -246
- package/src/pending-uploads-fs.ts +0 -235
- package/src/pending-uploads.test.ts +0 -173
- package/src/pending-uploads.ts +0 -121
- package/src/policy.test.ts +0 -240
- package/src/policy.ts +0 -262
- package/src/polls-store-memory.ts +0 -32
- package/src/polls.test.ts +0 -160
- package/src/polls.ts +0 -323
- package/src/presentation.ts +0 -68
- package/src/probe.test.ts +0 -77
- package/src/probe.ts +0 -132
- package/src/reply-dispatcher.test.ts +0 -437
- package/src/reply-dispatcher.ts +0 -346
- package/src/reply-stream-controller.test.ts +0 -235
- package/src/reply-stream-controller.ts +0 -147
- package/src/resolve-allowlist.test.ts +0 -250
- package/src/resolve-allowlist.ts +0 -309
- package/src/revoked-context.ts +0 -17
- package/src/runtime.ts +0 -9
- package/src/sdk-types.ts +0 -59
- package/src/sdk.test.ts +0 -666
- package/src/sdk.ts +0 -884
- package/src/secret-contract.ts +0 -49
- package/src/secret-input.ts +0 -7
- package/src/send-context.ts +0 -231
- package/src/send.test.ts +0 -493
- package/src/send.ts +0 -637
- package/src/sent-message-cache.test.ts +0 -15
- package/src/sent-message-cache.ts +0 -56
- package/src/session-route.ts +0 -40
- package/src/setup-core.ts +0 -160
- package/src/setup-surface.test.ts +0 -202
- package/src/setup-surface.ts +0 -320
- package/src/sso-token-store.test.ts +0 -72
- package/src/sso-token-store.ts +0 -166
- package/src/sso.ts +0 -300
- package/src/storage.ts +0 -25
- package/src/store-fs.ts +0 -44
- package/src/streaming-message.test.ts +0 -262
- package/src/streaming-message.ts +0 -297
- package/src/test-runtime.ts +0 -16
- package/src/thread-parent-context.test.ts +0 -224
- package/src/thread-parent-context.ts +0 -159
- package/src/token-response.ts +0 -11
- package/src/token.test.ts +0 -259
- package/src/token.ts +0 -195
- package/src/user-agent.test.ts +0 -86
- package/src/user-agent.ts +0 -53
- package/src/webhook-timeouts.ts +0 -27
- package/src/welcome-card.test.ts +0 -81
- package/src/welcome-card.ts +0 -57
- package/test-api.ts +0 -1
- package/tsconfig.json +0 -16
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
// Mock the runtime so we can assert whether the strict-dispatcher path
|
|
4
|
-
// (`fetchRemoteMedia`) was invoked versus the new direct-fetch path added
|
|
5
|
-
// for issue #63396 (Node 24+ / undici v7 compat).
|
|
6
|
-
const runtimeFetchRemoteMediaMock = vi.fn();
|
|
7
|
-
const runtimeDetectMimeMock = vi.fn(async () => "image/png");
|
|
8
|
-
const runtimeSaveMediaBufferMock = vi.fn(async (_buf: Buffer, contentType?: string) => ({
|
|
9
|
-
id: "saved",
|
|
10
|
-
path: "/tmp/saved.png",
|
|
11
|
-
size: 42,
|
|
12
|
-
contentType: contentType ?? "image/png",
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
|
-
vi.mock("../runtime.js", () => ({
|
|
16
|
-
getMSTeamsRuntime: () => ({
|
|
17
|
-
media: { detectMime: runtimeDetectMimeMock },
|
|
18
|
-
channel: {
|
|
19
|
-
media: {
|
|
20
|
-
fetchRemoteMedia: runtimeFetchRemoteMediaMock,
|
|
21
|
-
saveMediaBuffer: runtimeSaveMediaBufferMock,
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
}),
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
import { downloadAndStoreMSTeamsRemoteMedia } from "./remote-media.js";
|
|
28
|
-
|
|
29
|
-
const PNG_BYTES = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
|
30
|
-
|
|
31
|
-
function jsonResponse(body: BodyInit, init?: ResponseInit): Response {
|
|
32
|
-
return new Response(body, init);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
describe("downloadAndStoreMSTeamsRemoteMedia", () => {
|
|
36
|
-
beforeEach(() => {
|
|
37
|
-
runtimeFetchRemoteMediaMock.mockReset();
|
|
38
|
-
runtimeDetectMimeMock.mockClear();
|
|
39
|
-
runtimeSaveMediaBufferMock.mockClear();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe("useDirectFetch: true (Node 24+ / undici v7 path for issue #63396)", () => {
|
|
43
|
-
it("bypasses fetchRemoteMedia and calls the supplied fetchImpl directly", async () => {
|
|
44
|
-
// `fetchImpl` here simulates the "pre-validated hostname" contract from
|
|
45
|
-
// `safeFetchWithPolicy`: the caller has already enforced the allowlist,
|
|
46
|
-
// so the strict SSRF dispatcher is not needed.
|
|
47
|
-
const fetchImpl = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
|
48
|
-
jsonResponse(PNG_BYTES, { status: 200, headers: { "content-type": "image/png" } }),
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
const result = await downloadAndStoreMSTeamsRemoteMedia({
|
|
52
|
-
url: "https://graph.microsoft.com/v1.0/shares/abc/driveItem/content",
|
|
53
|
-
filePathHint: "file.png",
|
|
54
|
-
maxBytes: 1024,
|
|
55
|
-
useDirectFetch: true,
|
|
56
|
-
fetchImpl,
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
expect(fetchImpl).toHaveBeenCalledTimes(1);
|
|
60
|
-
const [calledUrl] = fetchImpl.mock.calls[0] ?? [];
|
|
61
|
-
expect(calledUrl).toBe("https://graph.microsoft.com/v1.0/shares/abc/driveItem/content");
|
|
62
|
-
expect(runtimeFetchRemoteMediaMock).not.toHaveBeenCalled();
|
|
63
|
-
expect(result.path).toBe("/tmp/saved.png");
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("surfaces HTTP errors as exceptions (no silent drop)", async () => {
|
|
67
|
-
const fetchImpl = vi.fn(async () => jsonResponse("nope", { status: 403 }));
|
|
68
|
-
|
|
69
|
-
await expect(
|
|
70
|
-
downloadAndStoreMSTeamsRemoteMedia({
|
|
71
|
-
url: "https://graph.microsoft.com/v1.0/shares/abc/driveItem/content",
|
|
72
|
-
filePathHint: "file.png",
|
|
73
|
-
maxBytes: 1024,
|
|
74
|
-
useDirectFetch: true,
|
|
75
|
-
fetchImpl,
|
|
76
|
-
}),
|
|
77
|
-
).rejects.toThrow(/HTTP 403/);
|
|
78
|
-
expect(runtimeFetchRemoteMediaMock).not.toHaveBeenCalled();
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("rejects a response whose Content-Length exceeds maxBytes", async () => {
|
|
82
|
-
const fetchImpl = vi.fn(async () =>
|
|
83
|
-
jsonResponse(PNG_BYTES, {
|
|
84
|
-
status: 200,
|
|
85
|
-
headers: { "content-length": "999999" },
|
|
86
|
-
}),
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
await expect(
|
|
90
|
-
downloadAndStoreMSTeamsRemoteMedia({
|
|
91
|
-
url: "https://graph.microsoft.com/v1.0/shares/abc/driveItem/content",
|
|
92
|
-
filePathHint: "file.png",
|
|
93
|
-
maxBytes: 1024,
|
|
94
|
-
useDirectFetch: true,
|
|
95
|
-
fetchImpl,
|
|
96
|
-
}),
|
|
97
|
-
).rejects.toThrow(/exceeds maxBytes/);
|
|
98
|
-
expect(runtimeFetchRemoteMediaMock).not.toHaveBeenCalled();
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("falls back to the runtime fetchRemoteMedia path when useDirectFetch is omitted", async () => {
|
|
102
|
-
// Non-SharePoint caller, no pre-validated fetchImpl: make sure the strict
|
|
103
|
-
// SSRF dispatcher path is still used.
|
|
104
|
-
runtimeFetchRemoteMediaMock.mockResolvedValueOnce({
|
|
105
|
-
buffer: PNG_BYTES,
|
|
106
|
-
contentType: "image/png",
|
|
107
|
-
fileName: "file.png",
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
await downloadAndStoreMSTeamsRemoteMedia({
|
|
111
|
-
url: "https://tenant.sharepoint.com/file.png",
|
|
112
|
-
filePathHint: "file.png",
|
|
113
|
-
maxBytes: 1024,
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
expect(runtimeFetchRemoteMediaMock).toHaveBeenCalledTimes(1);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it("does not use the direct path when useDirectFetch is true but fetchImpl is missing", async () => {
|
|
120
|
-
runtimeFetchRemoteMediaMock.mockResolvedValueOnce({
|
|
121
|
-
buffer: PNG_BYTES,
|
|
122
|
-
contentType: "image/png",
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
await downloadAndStoreMSTeamsRemoteMedia({
|
|
126
|
-
url: "https://graph.microsoft.com/v1.0/shares/abc/driveItem/content",
|
|
127
|
-
filePathHint: "file.png",
|
|
128
|
-
maxBytes: 1024,
|
|
129
|
-
useDirectFetch: true,
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
// Without a fetchImpl to delegate to, we must fall back to the runtime
|
|
133
|
-
// path rather than crashing.
|
|
134
|
-
expect(runtimeFetchRemoteMediaMock).toHaveBeenCalledTimes(1);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
});
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { readResponseWithLimit } from "openclaw/plugin-sdk/media-runtime";
|
|
2
|
-
import type { SsrFPolicy } from "../../runtime-api.js";
|
|
3
|
-
import { getMSTeamsRuntime } from "../runtime.js";
|
|
4
|
-
import { inferPlaceholder } from "./shared.js";
|
|
5
|
-
import type { MSTeamsInboundMedia } from "./types.js";
|
|
6
|
-
|
|
7
|
-
type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
8
|
-
|
|
9
|
-
type FetchedRemoteMedia = {
|
|
10
|
-
buffer: Buffer;
|
|
11
|
-
contentType?: string;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Direct fetch path used when the caller's `fetchImpl` has already validated
|
|
16
|
-
* the URL against a hostname allowlist (for example `safeFetchWithPolicy`).
|
|
17
|
-
*
|
|
18
|
-
* Bypasses the strict SSRF dispatcher on `fetchRemoteMedia` because:
|
|
19
|
-
* 1. The pinned undici dispatcher used by `fetchRemoteMedia` is incompatible
|
|
20
|
-
* with Node 24+'s built-in undici v7 (fails with "invalid onRequestStart
|
|
21
|
-
* method"), which silently breaks SharePoint/OneDrive downloads. See
|
|
22
|
-
* issue #63396.
|
|
23
|
-
* 2. SSRF protection is already enforced by the caller's `fetchImpl`
|
|
24
|
-
* (`safeFetch` validates every redirect hop against the hostname
|
|
25
|
-
* allowlist before following).
|
|
26
|
-
*/
|
|
27
|
-
async function fetchRemoteMediaDirect(params: {
|
|
28
|
-
url: string;
|
|
29
|
-
fetchImpl: FetchLike;
|
|
30
|
-
maxBytes: number;
|
|
31
|
-
}): Promise<FetchedRemoteMedia> {
|
|
32
|
-
const response = await params.fetchImpl(params.url, { redirect: "follow" });
|
|
33
|
-
if (!response.ok) {
|
|
34
|
-
const statusText = response.statusText ? ` ${response.statusText}` : "";
|
|
35
|
-
throw new Error(`HTTP ${response.status}${statusText}`);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Enforce the max-bytes cap before buffering the full body so a rogue
|
|
39
|
-
// response cannot drive RSS usage past the configured limit.
|
|
40
|
-
const contentLength = response.headers.get("content-length");
|
|
41
|
-
if (contentLength) {
|
|
42
|
-
const length = Number(contentLength);
|
|
43
|
-
if (Number.isFinite(length) && length > params.maxBytes) {
|
|
44
|
-
throw new Error(`content length ${length} exceeds maxBytes ${params.maxBytes}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const buffer = await readResponseWithLimit(response, params.maxBytes, {
|
|
49
|
-
onOverflow: ({ size, maxBytes }) =>
|
|
50
|
-
new Error(`payload size ${size} exceeds maxBytes ${maxBytes}`),
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
buffer,
|
|
55
|
-
contentType: response.headers.get("content-type") ?? undefined,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export async function downloadAndStoreMSTeamsRemoteMedia(params: {
|
|
60
|
-
url: string;
|
|
61
|
-
filePathHint: string;
|
|
62
|
-
maxBytes: number;
|
|
63
|
-
fetchImpl?: FetchLike;
|
|
64
|
-
ssrfPolicy?: SsrFPolicy;
|
|
65
|
-
contentTypeHint?: string;
|
|
66
|
-
placeholder?: string;
|
|
67
|
-
preserveFilenames?: boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Opt into a direct fetch path that bypasses `fetchRemoteMedia`'s strict
|
|
70
|
-
* SSRF dispatcher. Required for SharePoint/OneDrive downloads on Node 24+
|
|
71
|
-
* (see issue #63396). Only safe when the supplied `fetchImpl` has already
|
|
72
|
-
* validated the URL against a hostname allowlist.
|
|
73
|
-
*/
|
|
74
|
-
useDirectFetch?: boolean;
|
|
75
|
-
}): Promise<MSTeamsInboundMedia> {
|
|
76
|
-
let fetched: FetchedRemoteMedia;
|
|
77
|
-
if (params.useDirectFetch && params.fetchImpl) {
|
|
78
|
-
fetched = await fetchRemoteMediaDirect({
|
|
79
|
-
url: params.url,
|
|
80
|
-
fetchImpl: params.fetchImpl,
|
|
81
|
-
maxBytes: params.maxBytes,
|
|
82
|
-
});
|
|
83
|
-
} else {
|
|
84
|
-
fetched = await getMSTeamsRuntime().channel.media.fetchRemoteMedia({
|
|
85
|
-
url: params.url,
|
|
86
|
-
fetchImpl: params.fetchImpl,
|
|
87
|
-
filePathHint: params.filePathHint,
|
|
88
|
-
maxBytes: params.maxBytes,
|
|
89
|
-
ssrfPolicy: params.ssrfPolicy,
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
const mime = await getMSTeamsRuntime().media.detectMime({
|
|
93
|
-
buffer: fetched.buffer,
|
|
94
|
-
headerMime: fetched.contentType ?? params.contentTypeHint,
|
|
95
|
-
filePath: params.filePathHint,
|
|
96
|
-
});
|
|
97
|
-
const originalFilename = params.preserveFilenames ? params.filePathHint : undefined;
|
|
98
|
-
const saved = await getMSTeamsRuntime().channel.media.saveMediaBuffer(
|
|
99
|
-
fetched.buffer,
|
|
100
|
-
mime ?? params.contentTypeHint,
|
|
101
|
-
"inbound",
|
|
102
|
-
params.maxBytes,
|
|
103
|
-
originalFilename,
|
|
104
|
-
);
|
|
105
|
-
return {
|
|
106
|
-
path: saved.path,
|
|
107
|
-
contentType: saved.contentType,
|
|
108
|
-
placeholder:
|
|
109
|
-
params.placeholder ??
|
|
110
|
-
inferPlaceholder({ contentType: saved.contentType, fileName: params.filePathHint }),
|
|
111
|
-
};
|
|
112
|
-
}
|