@openclaw/msteams 2026.2.17 → 2026.2.21
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/CHANGELOG.md +0 -120
- package/package.json +2 -4
- package/src/channel.ts +1 -0
- package/src/graph-upload.ts +0 -1
- package/src/media-helpers.test.ts +4 -0
- package/src/media-helpers.ts +5 -0
- package/src/messenger.test.ts +2 -1
- package/src/messenger.ts +2 -2
- package/src/sent-message-cache.ts +3 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,125 +1,5 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 2026.2.17
|
|
4
|
-
|
|
5
|
-
### Changes
|
|
6
|
-
|
|
7
|
-
- Version alignment with core OpenClaw release numbers.
|
|
8
|
-
|
|
9
|
-
## 2026.2.16
|
|
10
|
-
|
|
11
|
-
### Changes
|
|
12
|
-
|
|
13
|
-
- Version alignment with core OpenClaw release numbers.
|
|
14
|
-
|
|
15
|
-
## 2026.2.15
|
|
16
|
-
|
|
17
|
-
### Changes
|
|
18
|
-
|
|
19
|
-
- Version alignment with core OpenClaw release numbers.
|
|
20
|
-
|
|
21
|
-
## 2026.2.14
|
|
22
|
-
|
|
23
|
-
### Changes
|
|
24
|
-
|
|
25
|
-
- Version alignment with core OpenClaw release numbers.
|
|
26
|
-
|
|
27
|
-
## 2026.2.13
|
|
28
|
-
|
|
29
|
-
### Changes
|
|
30
|
-
|
|
31
|
-
- Version alignment with core OpenClaw release numbers.
|
|
32
|
-
|
|
33
|
-
## 2026.2.6-3
|
|
34
|
-
|
|
35
|
-
### Changes
|
|
36
|
-
|
|
37
|
-
- Version alignment with core OpenClaw release numbers.
|
|
38
|
-
|
|
39
|
-
## 2026.2.6-2
|
|
40
|
-
|
|
41
|
-
### Changes
|
|
42
|
-
|
|
43
|
-
- Version alignment with core OpenClaw release numbers.
|
|
44
|
-
|
|
45
|
-
## 2026.2.6
|
|
46
|
-
|
|
47
|
-
### Changes
|
|
48
|
-
|
|
49
|
-
- Version alignment with core OpenClaw release numbers.
|
|
50
|
-
|
|
51
|
-
## 2026.2.4
|
|
52
|
-
|
|
53
|
-
### Changes
|
|
54
|
-
|
|
55
|
-
- Version alignment with core OpenClaw release numbers.
|
|
56
|
-
|
|
57
|
-
## 2026.2.2
|
|
58
|
-
|
|
59
|
-
### Changes
|
|
60
|
-
|
|
61
|
-
- Version alignment with core OpenClaw release numbers.
|
|
62
|
-
|
|
63
|
-
## 2026.1.31
|
|
64
|
-
|
|
65
|
-
### Changes
|
|
66
|
-
|
|
67
|
-
- Version alignment with core OpenClaw release numbers.
|
|
68
|
-
|
|
69
|
-
## 2026.1.30
|
|
70
|
-
|
|
71
|
-
### Changes
|
|
72
|
-
|
|
73
|
-
- Version alignment with core OpenClaw release numbers.
|
|
74
|
-
|
|
75
|
-
## 2026.1.29
|
|
76
|
-
|
|
77
|
-
### Changes
|
|
78
|
-
|
|
79
|
-
- Version alignment with core OpenClaw release numbers.
|
|
80
|
-
|
|
81
|
-
## 2026.1.23
|
|
82
|
-
|
|
83
|
-
### Changes
|
|
84
|
-
|
|
85
|
-
- Version alignment with core OpenClaw release numbers.
|
|
86
|
-
|
|
87
|
-
## 2026.1.22
|
|
88
|
-
|
|
89
|
-
### Changes
|
|
90
|
-
|
|
91
|
-
- Version alignment with core OpenClaw release numbers.
|
|
92
|
-
|
|
93
|
-
## 2026.1.21
|
|
94
|
-
|
|
95
|
-
### Changes
|
|
96
|
-
|
|
97
|
-
- Version alignment with core OpenClaw release numbers.
|
|
98
|
-
|
|
99
|
-
## 2026.1.20
|
|
100
|
-
|
|
101
|
-
### Changes
|
|
102
|
-
|
|
103
|
-
- Version alignment with core OpenClaw release numbers.
|
|
104
|
-
|
|
105
|
-
## 2026.1.17-1
|
|
106
|
-
|
|
107
|
-
### Changes
|
|
108
|
-
|
|
109
|
-
- Version alignment with core OpenClaw release numbers.
|
|
110
|
-
|
|
111
|
-
## 2026.1.17
|
|
112
|
-
|
|
113
|
-
### Changes
|
|
114
|
-
|
|
115
|
-
- Version alignment with core OpenClaw release numbers.
|
|
116
|
-
|
|
117
|
-
## 2026.1.16
|
|
118
|
-
|
|
119
|
-
### Changes
|
|
120
|
-
|
|
121
|
-
- Version alignment with core OpenClaw release numbers.
|
|
122
|
-
|
|
123
3
|
## 2026.1.15
|
|
124
4
|
|
|
125
5
|
### Features
|
package/package.json
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/msteams",
|
|
3
|
-
"version": "2026.2.
|
|
3
|
+
"version": "2026.2.21",
|
|
4
4
|
"description": "OpenClaw Microsoft Teams channel plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@microsoft/agents-hosting": "^1.
|
|
8
|
-
"@microsoft/agents-hosting-express": "^1.2.3",
|
|
9
|
-
"@microsoft/agents-hosting-extensions-teams": "^1.2.3",
|
|
7
|
+
"@microsoft/agents-hosting": "^1.3.1",
|
|
10
8
|
"express": "^5.2.1"
|
|
11
9
|
},
|
|
12
10
|
"devDependencies": {
|
package/src/channel.ts
CHANGED
|
@@ -123,6 +123,7 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount> = {
|
|
|
123
123
|
.map((entry) => String(entry).trim())
|
|
124
124
|
.filter(Boolean)
|
|
125
125
|
.map((entry) => entry.toLowerCase()),
|
|
126
|
+
resolveDefaultTo: ({ cfg }) => cfg.channels?.msteams?.defaultTo?.trim() || undefined,
|
|
126
127
|
},
|
|
127
128
|
security: {
|
|
128
129
|
collectWarnings: ({ cfg }) => {
|
package/src/graph-upload.ts
CHANGED
|
@@ -24,7 +24,6 @@ export interface OneDriveUploadResult {
|
|
|
24
24
|
/**
|
|
25
25
|
* Upload a file to the user's OneDrive root folder.
|
|
26
26
|
* For larger files, this uses the simple upload endpoint (up to 4MB).
|
|
27
|
-
* TODO: For files >4MB, implement resumable upload session.
|
|
28
27
|
*/
|
|
29
28
|
export async function uploadToOneDrive(params: {
|
|
30
29
|
buffer: Buffer;
|
|
@@ -154,6 +154,10 @@ describe("msteams media-helpers", () => {
|
|
|
154
154
|
expect(isLocalPath("\\\\server\\share\\image.png")).toBe(true);
|
|
155
155
|
});
|
|
156
156
|
|
|
157
|
+
it("returns true for Windows rooted paths", () => {
|
|
158
|
+
expect(isLocalPath("\\tmp\\openclaw\\file.txt")).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
|
|
157
161
|
it("returns false for http URLs", () => {
|
|
158
162
|
expect(isLocalPath("http://example.com/image.png")).toBe(false);
|
|
159
163
|
expect(isLocalPath("https://example.com/image.png")).toBe(false);
|
package/src/media-helpers.ts
CHANGED
|
@@ -69,6 +69,11 @@ export function isLocalPath(url: string): boolean {
|
|
|
69
69
|
return true;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// Windows rooted path on current drive (e.g. \tmp\file.txt)
|
|
73
|
+
if (url.startsWith("\\") && !url.startsWith("\\\\")) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
|
|
72
77
|
// Windows drive-letter absolute path (e.g. C:\foo\bar.txt or C:/foo/bar.txt)
|
|
73
78
|
if (/^[a-zA-Z]:[\\/]/.test(url)) {
|
|
74
79
|
return true;
|
package/src/messenger.test.ts
CHANGED
|
@@ -16,6 +16,7 @@ vi.mock("./graph-upload.js", async () => {
|
|
|
16
16
|
};
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
import { resolvePreferredOpenClawTmpDir } from "../../../src/infra/tmp-openclaw-dir.js";
|
|
19
20
|
import {
|
|
20
21
|
type MSTeamsAdapter,
|
|
21
22
|
renderReplyPayloadsToMessages,
|
|
@@ -178,7 +179,7 @@ describe("msteams messenger", () => {
|
|
|
178
179
|
});
|
|
179
180
|
|
|
180
181
|
it("preserves parsed mentions when appending OneDrive fallback file links", async () => {
|
|
181
|
-
const tmpDir = await mkdtemp(path.join(
|
|
182
|
+
const tmpDir = await mkdtemp(path.join(resolvePreferredOpenClawTmpDir(), "msteams-mention-"));
|
|
182
183
|
const localFile = path.join(tmpDir, "note.txt");
|
|
183
184
|
await writeFile(localFile, "hello");
|
|
184
185
|
|
package/src/messenger.ts
CHANGED
|
@@ -295,7 +295,7 @@ async function buildActivity(
|
|
|
295
295
|
// Teams only accepts base64 data URLs for images
|
|
296
296
|
const conversationType = conversationRef.conversation?.conversationType?.toLowerCase();
|
|
297
297
|
const isPersonal = conversationType === "personal";
|
|
298
|
-
const isImage =
|
|
298
|
+
const isImage = media.kind === "image";
|
|
299
299
|
|
|
300
300
|
if (
|
|
301
301
|
requiresFileConsent({
|
|
@@ -347,7 +347,7 @@ async function buildActivity(
|
|
|
347
347
|
return activity;
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
-
if (!isPersonal &&
|
|
350
|
+
if (!isPersonal && media.kind !== "image" && tokenProvider) {
|
|
351
351
|
// Fallback: no SharePoint site configured, try OneDrive upload
|
|
352
352
|
const uploaded = await uploadAndShareOneDrive({
|
|
353
353
|
buffer: media.buffer,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
2
2
|
|
|
3
3
|
type CacheEntry = {
|
|
4
|
-
messageIds: Set<string>;
|
|
5
4
|
timestamps: Map<string, number>;
|
|
6
5
|
};
|
|
7
6
|
|
|
@@ -11,7 +10,6 @@ function cleanupExpired(entry: CacheEntry): void {
|
|
|
11
10
|
const now = Date.now();
|
|
12
11
|
for (const [msgId, timestamp] of entry.timestamps) {
|
|
13
12
|
if (now - timestamp > TTL_MS) {
|
|
14
|
-
entry.messageIds.delete(msgId);
|
|
15
13
|
entry.timestamps.delete(msgId);
|
|
16
14
|
}
|
|
17
15
|
}
|
|
@@ -23,12 +21,11 @@ export function recordMSTeamsSentMessage(conversationId: string, messageId: stri
|
|
|
23
21
|
}
|
|
24
22
|
let entry = sentMessages.get(conversationId);
|
|
25
23
|
if (!entry) {
|
|
26
|
-
entry = {
|
|
24
|
+
entry = { timestamps: new Map() };
|
|
27
25
|
sentMessages.set(conversationId, entry);
|
|
28
26
|
}
|
|
29
|
-
entry.messageIds.add(messageId);
|
|
30
27
|
entry.timestamps.set(messageId, Date.now());
|
|
31
|
-
if (entry.
|
|
28
|
+
if (entry.timestamps.size > 200) {
|
|
32
29
|
cleanupExpired(entry);
|
|
33
30
|
}
|
|
34
31
|
}
|
|
@@ -39,7 +36,7 @@ export function wasMSTeamsMessageSent(conversationId: string, messageId: string)
|
|
|
39
36
|
return false;
|
|
40
37
|
}
|
|
41
38
|
cleanupExpired(entry);
|
|
42
|
-
return entry.
|
|
39
|
+
return entry.timestamps.has(messageId);
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
export function clearMSTeamsSentMessageCache(): void {
|