@openclaw/msteams 2026.2.3 → 2026.2.9
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 +19 -1
- package/package.json +1 -2
- package/src/channel.ts +5 -2
- package/src/directory-live.ts +2 -2
- package/src/messenger.ts +1 -10
- package/src/monitor-handler/inbound-media.ts +5 -5
- package/src/monitor-handler/message-handler.ts +16 -16
- package/src/monitor-handler.ts +6 -6
- package/src/monitor-types.ts +1 -1
- package/src/monitor.ts +6 -6
- package/src/onboarding.ts +2 -1
- package/src/reply-dispatcher.ts +2 -2
- package/src/resolve-allowlist.ts +2 -1
- package/src/send.ts +11 -11
- package/src/store-fs.ts +1 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 2026.2.3
|
|
3
|
+
## 2026.2.6-3
|
|
4
|
+
|
|
5
|
+
### Changes
|
|
6
|
+
|
|
7
|
+
- Version alignment with core OpenClaw release numbers.
|
|
8
|
+
|
|
9
|
+
## 2026.2.6-2
|
|
10
|
+
|
|
11
|
+
### Changes
|
|
12
|
+
|
|
13
|
+
- Version alignment with core OpenClaw release numbers.
|
|
14
|
+
|
|
15
|
+
## 2026.2.6
|
|
16
|
+
|
|
17
|
+
### Changes
|
|
18
|
+
|
|
19
|
+
- Version alignment with core OpenClaw release numbers.
|
|
20
|
+
|
|
21
|
+
## 2026.2.4
|
|
4
22
|
|
|
5
23
|
### Changes
|
|
6
24
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/msteams",
|
|
3
|
-
"version": "2026.2.
|
|
3
|
+
"version": "2026.2.9",
|
|
4
4
|
"description": "OpenClaw Microsoft Teams channel plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
"@microsoft/agents-hosting-express": "^1.2.3",
|
|
9
9
|
"@microsoft/agents-hosting-extensions-teams": "^1.2.3",
|
|
10
10
|
"express": "^5.2.1",
|
|
11
|
-
"openclaw": "workspace:*",
|
|
12
11
|
"proper-lockfile": "^4.1.2"
|
|
13
12
|
},
|
|
14
13
|
"devDependencies": {
|
package/src/channel.ts
CHANGED
|
@@ -42,6 +42,7 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount> = {
|
|
|
42
42
|
id: "msteams",
|
|
43
43
|
meta: {
|
|
44
44
|
...meta,
|
|
45
|
+
aliases: [...meta.aliases],
|
|
45
46
|
},
|
|
46
47
|
onboarding: msteamsOnboardingAdapter,
|
|
47
48
|
pairing: {
|
|
@@ -384,7 +385,8 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount> = {
|
|
|
384
385
|
if (!to) {
|
|
385
386
|
return {
|
|
386
387
|
isError: true,
|
|
387
|
-
content: [{ type: "text", text: "Card send requires a target (to)." }],
|
|
388
|
+
content: [{ type: "text" as const, text: "Card send requires a target (to)." }],
|
|
389
|
+
details: { error: "Card send requires a target (to)." },
|
|
388
390
|
};
|
|
389
391
|
}
|
|
390
392
|
const result = await sendAdaptiveCardMSTeams({
|
|
@@ -395,7 +397,7 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount> = {
|
|
|
395
397
|
return {
|
|
396
398
|
content: [
|
|
397
399
|
{
|
|
398
|
-
type: "text",
|
|
400
|
+
type: "text" as const,
|
|
399
401
|
text: JSON.stringify({
|
|
400
402
|
ok: true,
|
|
401
403
|
channel: "msteams",
|
|
@@ -404,6 +406,7 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount> = {
|
|
|
404
406
|
}),
|
|
405
407
|
},
|
|
406
408
|
],
|
|
409
|
+
details: { ok: true, channel: "msteams", messageId: result.messageId },
|
|
407
410
|
};
|
|
408
411
|
}
|
|
409
412
|
// Return null to fall through to default handler
|
package/src/directory-live.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk";
|
|
1
|
+
import type { ChannelDirectoryEntry, MSTeamsConfig } from "openclaw/plugin-sdk";
|
|
2
2
|
import { GRAPH_ROOT } from "./attachments/shared.js";
|
|
3
3
|
import { loadMSTeamsSdkWithAuth } from "./sdk.js";
|
|
4
4
|
import { resolveMSTeamsCredentials } from "./token.js";
|
|
@@ -62,7 +62,7 @@ async function fetchGraphJson<T>(params: {
|
|
|
62
62
|
|
|
63
63
|
async function resolveGraphToken(cfg: unknown): Promise<string> {
|
|
64
64
|
const creds = resolveMSTeamsCredentials(
|
|
65
|
-
(cfg as { channels?: { msteams?: unknown } })?.channels?.msteams,
|
|
65
|
+
(cfg as { channels?: { msteams?: unknown } })?.channels?.msteams as MSTeamsConfig | undefined,
|
|
66
66
|
);
|
|
67
67
|
if (!creds) {
|
|
68
68
|
throw new Error("MS Teams credentials missing");
|
package/src/messenger.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type MSTeamsReplyStyle,
|
|
7
7
|
type ReplyPayload,
|
|
8
8
|
SILENT_REPLY_TOKEN,
|
|
9
|
+
sleep,
|
|
9
10
|
} from "openclaw/plugin-sdk";
|
|
10
11
|
import type { MSTeamsAccessTokenProvider } from "./attachments/types.js";
|
|
11
12
|
import type { StoredConversationReference } from "./conversation-store.js";
|
|
@@ -166,16 +167,6 @@ function clampMs(value: number, maxMs: number): number {
|
|
|
166
167
|
return Math.min(value, maxMs);
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
async function sleep(ms: number): Promise<void> {
|
|
170
|
-
const delay = Math.max(0, ms);
|
|
171
|
-
if (delay === 0) {
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
await new Promise<void>((resolve) => {
|
|
175
|
-
setTimeout(resolve, delay);
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
170
|
function resolveRetryOptions(
|
|
180
171
|
retry: false | MSTeamsSendRetryOptions | undefined,
|
|
181
172
|
): Required<MSTeamsSendRetryOptions> & { enabled: boolean } {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "../attachments.js";
|
|
11
11
|
|
|
12
12
|
type MSTeamsLogger = {
|
|
13
|
-
debug
|
|
13
|
+
debug?: (message: string, meta?: Record<string, unknown>) => void;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export async function resolveMSTeamsInboundMedia(params: {
|
|
@@ -66,7 +66,7 @@ export async function resolveMSTeamsInboundMedia(params: {
|
|
|
66
66
|
channelData: activity.channelData,
|
|
67
67
|
});
|
|
68
68
|
if (messageUrls.length === 0) {
|
|
69
|
-
log.debug("graph message url unavailable", {
|
|
69
|
+
log.debug?.("graph message url unavailable", {
|
|
70
70
|
conversationType,
|
|
71
71
|
hasChannelData: Boolean(activity.channelData),
|
|
72
72
|
messageId: activity.id ?? undefined,
|
|
@@ -107,16 +107,16 @@ export async function resolveMSTeamsInboundMedia(params: {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
if (mediaList.length === 0) {
|
|
110
|
-
log.debug("graph media fetch empty", { attempts });
|
|
110
|
+
log.debug?.("graph media fetch empty", { attempts });
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
if (mediaList.length > 0) {
|
|
117
|
-
log.debug("downloaded attachments", { count: mediaList.length });
|
|
117
|
+
log.debug?.("downloaded attachments", { count: mediaList.length });
|
|
118
118
|
} else if (htmlSummary?.imgTags) {
|
|
119
|
-
log.debug("inline images detected but none downloaded", {
|
|
119
|
+
log.debug?.("inline images detected but none downloaded", {
|
|
120
120
|
imgTags: htmlSummary.imgTags,
|
|
121
121
|
srcHosts: htmlSummary.srcHosts,
|
|
122
122
|
dataImages: htmlSummary.dataImages,
|
|
@@ -54,7 +54,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
54
54
|
const core = getMSTeamsRuntime();
|
|
55
55
|
const logVerboseMessage = (message: string) => {
|
|
56
56
|
if (core.logging.shouldLogVerbose()) {
|
|
57
|
-
log.debug(message);
|
|
57
|
+
log.debug?.(message);
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
const msteamsCfg = cfg.channels?.msteams;
|
|
@@ -105,11 +105,11 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
105
105
|
conversation: conversation?.id,
|
|
106
106
|
});
|
|
107
107
|
if (htmlSummary) {
|
|
108
|
-
log.debug("html attachment summary", htmlSummary);
|
|
108
|
+
log.debug?.("html attachment summary", htmlSummary);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
if (!from?.id) {
|
|
112
|
-
log.debug("skipping message without from.id");
|
|
112
|
+
log.debug?.("skipping message without from.id");
|
|
113
113
|
return;
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -137,7 +137,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
137
137
|
const allowFrom = dmAllowFrom;
|
|
138
138
|
|
|
139
139
|
if (dmPolicy === "disabled") {
|
|
140
|
-
log.debug("dropping dm (dms disabled)");
|
|
140
|
+
log.debug?.("dropping dm (dms disabled)");
|
|
141
141
|
return;
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -163,7 +163,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
log.debug("dropping dm (not allowlisted)", {
|
|
166
|
+
log.debug?.("dropping dm (not allowlisted)", {
|
|
167
167
|
sender: senderId,
|
|
168
168
|
label: senderName,
|
|
169
169
|
allowlistMatch: formatAllowlistMatchMeta(allowMatch),
|
|
@@ -200,7 +200,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
200
200
|
|
|
201
201
|
if (!isDirectMessage && msteamsCfg) {
|
|
202
202
|
if (groupPolicy === "disabled") {
|
|
203
|
-
log.debug("dropping group message (groupPolicy: disabled)", {
|
|
203
|
+
log.debug?.("dropping group message (groupPolicy: disabled)", {
|
|
204
204
|
conversationId,
|
|
205
205
|
});
|
|
206
206
|
return;
|
|
@@ -208,7 +208,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
208
208
|
|
|
209
209
|
if (groupPolicy === "allowlist") {
|
|
210
210
|
if (channelGate.allowlistConfigured && !channelGate.allowed) {
|
|
211
|
-
log.debug("dropping group message (not in team/channel allowlist)", {
|
|
211
|
+
log.debug?.("dropping group message (not in team/channel allowlist)", {
|
|
212
212
|
conversationId,
|
|
213
213
|
teamKey: channelGate.teamKey ?? "none",
|
|
214
214
|
channelKey: channelGate.channelKey ?? "none",
|
|
@@ -218,20 +218,19 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
218
218
|
return;
|
|
219
219
|
}
|
|
220
220
|
if (effectiveGroupAllowFrom.length === 0 && !channelGate.allowlistConfigured) {
|
|
221
|
-
log.debug("dropping group message (groupPolicy: allowlist, no allowlist)", {
|
|
221
|
+
log.debug?.("dropping group message (groupPolicy: allowlist, no allowlist)", {
|
|
222
222
|
conversationId,
|
|
223
223
|
});
|
|
224
224
|
return;
|
|
225
225
|
}
|
|
226
226
|
if (effectiveGroupAllowFrom.length > 0) {
|
|
227
227
|
const allowMatch = resolveMSTeamsAllowlistMatch({
|
|
228
|
-
groupPolicy,
|
|
229
228
|
allowFrom: effectiveGroupAllowFrom,
|
|
230
229
|
senderId,
|
|
231
230
|
senderName,
|
|
232
231
|
});
|
|
233
232
|
if (!allowMatch.allowed) {
|
|
234
|
-
log.debug("dropping group message (not in groupAllowFrom)", {
|
|
233
|
+
log.debug?.("dropping group message (not in groupAllowFrom)", {
|
|
235
234
|
sender: senderId,
|
|
236
235
|
label: senderName,
|
|
237
236
|
allowlistMatch: formatAllowlistMatchMeta(allowMatch),
|
|
@@ -293,7 +292,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
293
292
|
locale: activity.locale,
|
|
294
293
|
};
|
|
295
294
|
conversationStore.upsert(conversationId, conversationRef).catch((err) => {
|
|
296
|
-
log.debug("failed to save conversation reference", {
|
|
295
|
+
log.debug?.("failed to save conversation reference", {
|
|
297
296
|
error: formatUnknownError(err),
|
|
298
297
|
});
|
|
299
298
|
});
|
|
@@ -307,7 +306,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
307
306
|
selections: pollVote.selections,
|
|
308
307
|
});
|
|
309
308
|
if (!poll) {
|
|
310
|
-
log.debug("poll vote ignored (poll not found)", {
|
|
309
|
+
log.debug?.("poll vote ignored (poll not found)", {
|
|
311
310
|
pollId: pollVote.pollId,
|
|
312
311
|
});
|
|
313
312
|
} else {
|
|
@@ -327,7 +326,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
327
326
|
}
|
|
328
327
|
|
|
329
328
|
if (!rawBody) {
|
|
330
|
-
log.debug("skipping empty message after stripping mentions");
|
|
329
|
+
log.debug?.("skipping empty message after stripping mentions");
|
|
331
330
|
return;
|
|
332
331
|
}
|
|
333
332
|
|
|
@@ -342,7 +341,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
342
341
|
cfg,
|
|
343
342
|
channel: "msteams",
|
|
344
343
|
peer: {
|
|
345
|
-
kind: isDirectMessage ? "
|
|
344
|
+
kind: isDirectMessage ? "direct" : isChannel ? "channel" : "group",
|
|
346
345
|
id: isDirectMessage ? senderId : conversationId,
|
|
347
346
|
},
|
|
348
347
|
});
|
|
@@ -377,7 +376,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
377
376
|
});
|
|
378
377
|
const mentioned = mentionGate.effectiveWasMentioned;
|
|
379
378
|
if (requireMention && mentionGate.shouldSkip) {
|
|
380
|
-
log.debug("skipping message (mention required)", {
|
|
379
|
+
log.debug?.("skipping message (mention required)", {
|
|
381
380
|
teamId,
|
|
382
381
|
channelId,
|
|
383
382
|
requireMention,
|
|
@@ -413,7 +412,8 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
413
412
|
channelData: activity.channelData,
|
|
414
413
|
},
|
|
415
414
|
log,
|
|
416
|
-
preserveFilenames: cfg.media
|
|
415
|
+
preserveFilenames: (cfg as { media?: { preserveFilenames?: boolean } }).media
|
|
416
|
+
?.preserveFilenames,
|
|
417
417
|
});
|
|
418
418
|
|
|
419
419
|
const mediaPayload = buildMSTeamsMediaPayload(mediaList);
|
package/src/monitor-handler.ts
CHANGED
|
@@ -49,7 +49,7 @@ async function handleFileConsentInvoke(
|
|
|
49
49
|
|
|
50
50
|
const consentResponse = parseFileConsentInvoke(activity);
|
|
51
51
|
if (!consentResponse) {
|
|
52
|
-
log.debug("invalid file consent invoke", { value: activity.value });
|
|
52
|
+
log.debug?.("invalid file consent invoke", { value: activity.value });
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -61,7 +61,7 @@ async function handleFileConsentInvoke(
|
|
|
61
61
|
if (consentResponse.action === "accept" && consentResponse.uploadInfo) {
|
|
62
62
|
const pendingFile = getPendingUpload(uploadId);
|
|
63
63
|
if (pendingFile) {
|
|
64
|
-
log.debug("user accepted file consent, uploading", {
|
|
64
|
+
log.debug?.("user accepted file consent, uploading", {
|
|
65
65
|
uploadId,
|
|
66
66
|
filename: pendingFile.filename,
|
|
67
67
|
size: pendingFile.buffer.length,
|
|
@@ -94,20 +94,20 @@ async function handleFileConsentInvoke(
|
|
|
94
94
|
uniqueId: consentResponse.uploadInfo.uniqueId,
|
|
95
95
|
});
|
|
96
96
|
} catch (err) {
|
|
97
|
-
log.debug("file upload failed", { uploadId, error: String(err) });
|
|
97
|
+
log.debug?.("file upload failed", { uploadId, error: String(err) });
|
|
98
98
|
await context.sendActivity(`File upload failed: ${String(err)}`);
|
|
99
99
|
} finally {
|
|
100
100
|
removePendingUpload(uploadId);
|
|
101
101
|
}
|
|
102
102
|
} else {
|
|
103
|
-
log.debug("pending file not found for consent", { uploadId });
|
|
103
|
+
log.debug?.("pending file not found for consent", { uploadId });
|
|
104
104
|
await context.sendActivity(
|
|
105
105
|
"The file upload request has expired. Please try sending the file again.",
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
108
|
} else {
|
|
109
109
|
// User declined
|
|
110
|
-
log.debug("user declined file consent", { uploadId });
|
|
110
|
+
log.debug?.("user declined file consent", { uploadId });
|
|
111
111
|
removePendingUpload(uploadId);
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -151,7 +151,7 @@ export function registerMSTeamsHandlers<T extends MSTeamsActivityHandler>(
|
|
|
151
151
|
const membersAdded = (context as MSTeamsTurnContext).activity?.membersAdded ?? [];
|
|
152
152
|
for (const member of membersAdded) {
|
|
153
153
|
if (member.id !== (context as MSTeamsTurnContext).activity?.recipient?.id) {
|
|
154
|
-
deps.log.debug("member added", { member: member.id });
|
|
154
|
+
deps.log.debug?.("member added", { member: member.id });
|
|
155
155
|
// Don't send welcome message - let the user initiate conversation.
|
|
156
156
|
}
|
|
157
157
|
}
|
package/src/monitor-types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type MSTeamsMonitorLogger = {
|
|
2
|
-
debug
|
|
2
|
+
debug?: (message: string, meta?: Record<string, unknown>) => void;
|
|
3
3
|
info: (message: string, meta?: Record<string, unknown>) => void;
|
|
4
4
|
error: (message: string, meta?: Record<string, unknown>) => void;
|
|
5
5
|
};
|
package/src/monitor.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { MSTeamsConversationStore } from "./conversation-store.js";
|
|
|
9
9
|
import type { MSTeamsAdapter } from "./messenger.js";
|
|
10
10
|
import { createMSTeamsConversationStoreFs } from "./conversation-store-fs.js";
|
|
11
11
|
import { formatUnknownError } from "./errors.js";
|
|
12
|
-
import { registerMSTeamsHandlers } from "./monitor-handler.js";
|
|
12
|
+
import { registerMSTeamsHandlers, type MSTeamsActivityHandler } from "./monitor-handler.js";
|
|
13
13
|
import { createMSTeamsPollStoreFs, type MSTeamsPollStore } from "./polls.js";
|
|
14
14
|
import {
|
|
15
15
|
resolveMSTeamsChannelAllowlist,
|
|
@@ -40,7 +40,7 @@ export async function monitorMSTeamsProvider(
|
|
|
40
40
|
let cfg = opts.cfg;
|
|
41
41
|
let msteamsCfg = cfg.channels?.msteams;
|
|
42
42
|
if (!msteamsCfg?.enabled) {
|
|
43
|
-
log.debug("msteams provider disabled");
|
|
43
|
+
log.debug?.("msteams provider disabled");
|
|
44
44
|
return { app: null, shutdown: async () => {} };
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -224,7 +224,7 @@ export async function monitorMSTeamsProvider(
|
|
|
224
224
|
const tokenProvider = new MsalTokenProvider(authConfig);
|
|
225
225
|
const adapter = createMSTeamsAdapter(authConfig, sdk);
|
|
226
226
|
|
|
227
|
-
const handler = registerMSTeamsHandlers(new ActivityHandler(), {
|
|
227
|
+
const handler = registerMSTeamsHandlers(new ActivityHandler() as MSTeamsActivityHandler, {
|
|
228
228
|
cfg,
|
|
229
229
|
runtime,
|
|
230
230
|
appId,
|
|
@@ -246,7 +246,7 @@ export async function monitorMSTeamsProvider(
|
|
|
246
246
|
const configuredPath = msteamsCfg.webhook?.path ?? "/api/messages";
|
|
247
247
|
const messageHandler = (req: Request, res: Response) => {
|
|
248
248
|
void adapter
|
|
249
|
-
.process(req, res, (context: unknown) => handler.run(context))
|
|
249
|
+
.process(req, res, (context: unknown) => handler.run!(context))
|
|
250
250
|
.catch((err: unknown) => {
|
|
251
251
|
log.error("msteams webhook failed", { error: formatUnknownError(err) });
|
|
252
252
|
});
|
|
@@ -258,7 +258,7 @@ export async function monitorMSTeamsProvider(
|
|
|
258
258
|
expressApp.post("/api/messages", messageHandler);
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
log.debug("listening on paths", {
|
|
261
|
+
log.debug?.("listening on paths", {
|
|
262
262
|
primary: configuredPath,
|
|
263
263
|
fallback: "/api/messages",
|
|
264
264
|
});
|
|
@@ -277,7 +277,7 @@ export async function monitorMSTeamsProvider(
|
|
|
277
277
|
return new Promise<void>((resolve) => {
|
|
278
278
|
httpServer.close((err) => {
|
|
279
279
|
if (err) {
|
|
280
|
-
log.debug("msteams server close error", { error: String(err) });
|
|
280
|
+
log.debug?.("msteams server close error", { error: String(err) });
|
|
281
281
|
}
|
|
282
282
|
resolve();
|
|
283
283
|
});
|
package/src/onboarding.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
OpenClawConfig,
|
|
5
5
|
DmPolicy,
|
|
6
6
|
WizardPrompter,
|
|
7
|
+
MSTeamsTeamConfig,
|
|
7
8
|
} from "openclaw/plugin-sdk";
|
|
8
9
|
import {
|
|
9
10
|
addWildcardAllowFrom,
|
|
@@ -184,7 +185,7 @@ function setMSTeamsTeamsAllowlist(
|
|
|
184
185
|
msteams: {
|
|
185
186
|
...cfg.channels?.msteams,
|
|
186
187
|
enabled: true,
|
|
187
|
-
teams,
|
|
188
|
+
teams: teams as Record<string, MSTeamsTeamConfig>,
|
|
188
189
|
},
|
|
189
190
|
},
|
|
190
191
|
};
|
package/src/reply-dispatcher.ts
CHANGED
|
@@ -49,7 +49,7 @@ export function createMSTeamsReplyDispatcher(params: {
|
|
|
49
49
|
start: sendTypingIndicator,
|
|
50
50
|
onStartError: (err) => {
|
|
51
51
|
logTypingFailure({
|
|
52
|
-
log: (message) => params.log.debug(message),
|
|
52
|
+
log: (message) => params.log.debug?.(message),
|
|
53
53
|
channel: "msteams",
|
|
54
54
|
action: "start",
|
|
55
55
|
error: err,
|
|
@@ -94,7 +94,7 @@ export function createMSTeamsReplyDispatcher(params: {
|
|
|
94
94
|
// Enable default retry/backoff for throttling/transient failures.
|
|
95
95
|
retry: {},
|
|
96
96
|
onRetry: (event) => {
|
|
97
|
-
params.log.debug("retrying send", {
|
|
97
|
+
params.log.debug?.("retrying send", {
|
|
98
98
|
replyStyle: params.replyStyle,
|
|
99
99
|
...event,
|
|
100
100
|
});
|
package/src/resolve-allowlist.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { MSTeamsConfig } from "openclaw/plugin-sdk";
|
|
1
2
|
import { GRAPH_ROOT } from "./attachments/shared.js";
|
|
2
3
|
import { loadMSTeamsSdkWithAuth } from "./sdk.js";
|
|
3
4
|
import { resolveMSTeamsCredentials } from "./token.js";
|
|
@@ -155,7 +156,7 @@ async function fetchGraphJson<T>(params: {
|
|
|
155
156
|
|
|
156
157
|
async function resolveGraphToken(cfg: unknown): Promise<string> {
|
|
157
158
|
const creds = resolveMSTeamsCredentials(
|
|
158
|
-
(cfg as { channels?: { msteams?: unknown } })?.channels?.msteams,
|
|
159
|
+
(cfg as { channels?: { msteams?: unknown } })?.channels?.msteams as MSTeamsConfig | undefined,
|
|
159
160
|
);
|
|
160
161
|
if (!creds) {
|
|
161
162
|
throw new Error("MS Teams credentials missing");
|
package/src/send.ts
CHANGED
|
@@ -111,7 +111,7 @@ export async function sendMessageMSTeams(
|
|
|
111
111
|
sharePointSiteId,
|
|
112
112
|
} = ctx;
|
|
113
113
|
|
|
114
|
-
log.debug("sending proactive message", {
|
|
114
|
+
log.debug?.("sending proactive message", {
|
|
115
115
|
conversationId,
|
|
116
116
|
conversationType,
|
|
117
117
|
textLength: messageText.length,
|
|
@@ -131,7 +131,7 @@ export async function sendMessageMSTeams(
|
|
|
131
131
|
const fallbackFileName = await extractFilename(mediaUrl);
|
|
132
132
|
const fileName = media.fileName ?? fallbackFileName;
|
|
133
133
|
|
|
134
|
-
log.debug("processing media", {
|
|
134
|
+
log.debug?.("processing media", {
|
|
135
135
|
fileName,
|
|
136
136
|
contentType: media.contentType,
|
|
137
137
|
size: media.buffer.length,
|
|
@@ -155,7 +155,7 @@ export async function sendMessageMSTeams(
|
|
|
155
155
|
description: messageText || undefined,
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
log.debug("sending file consent card", { uploadId, fileName, size: media.buffer.length });
|
|
158
|
+
log.debug?.("sending file consent card", { uploadId, fileName, size: media.buffer.length });
|
|
159
159
|
|
|
160
160
|
const baseRef = buildConversationReference(ref);
|
|
161
161
|
const proactiveRef = { ...baseRef, activityId: undefined };
|
|
@@ -205,7 +205,7 @@ export async function sendMessageMSTeams(
|
|
|
205
205
|
try {
|
|
206
206
|
if (sharePointSiteId) {
|
|
207
207
|
// Use SharePoint upload + Graph API for native file card
|
|
208
|
-
log.debug("uploading to SharePoint for native file card", {
|
|
208
|
+
log.debug?.("uploading to SharePoint for native file card", {
|
|
209
209
|
fileName,
|
|
210
210
|
conversationType,
|
|
211
211
|
siteId: sharePointSiteId,
|
|
@@ -221,7 +221,7 @@ export async function sendMessageMSTeams(
|
|
|
221
221
|
usePerUserSharing: conversationType === "groupChat",
|
|
222
222
|
});
|
|
223
223
|
|
|
224
|
-
log.debug("SharePoint upload complete", {
|
|
224
|
+
log.debug?.("SharePoint upload complete", {
|
|
225
225
|
itemId: uploaded.itemId,
|
|
226
226
|
shareUrl: uploaded.shareUrl,
|
|
227
227
|
});
|
|
@@ -233,7 +233,7 @@ export async function sendMessageMSTeams(
|
|
|
233
233
|
tokenProvider,
|
|
234
234
|
});
|
|
235
235
|
|
|
236
|
-
log.debug("driveItem properties retrieved", {
|
|
236
|
+
log.debug?.("driveItem properties retrieved", {
|
|
237
237
|
eTag: driveItem.eTag,
|
|
238
238
|
webDavUrl: driveItem.webDavUrl,
|
|
239
239
|
});
|
|
@@ -265,7 +265,7 @@ export async function sendMessageMSTeams(
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
// Fallback: no SharePoint site configured, use OneDrive with markdown link
|
|
268
|
-
log.debug("uploading to OneDrive (no SharePoint site configured)", {
|
|
268
|
+
log.debug?.("uploading to OneDrive (no SharePoint site configured)", {
|
|
269
269
|
fileName,
|
|
270
270
|
conversationType,
|
|
271
271
|
});
|
|
@@ -277,7 +277,7 @@ export async function sendMessageMSTeams(
|
|
|
277
277
|
tokenProvider,
|
|
278
278
|
});
|
|
279
279
|
|
|
280
|
-
log.debug("OneDrive upload complete", {
|
|
280
|
+
log.debug?.("OneDrive upload complete", {
|
|
281
281
|
itemId: uploaded.itemId,
|
|
282
282
|
shareUrl: uploaded.shareUrl,
|
|
283
283
|
});
|
|
@@ -349,7 +349,7 @@ async function sendTextWithMedia(
|
|
|
349
349
|
messages: [{ text: text || undefined, mediaUrl }],
|
|
350
350
|
retry: {},
|
|
351
351
|
onRetry: (event) => {
|
|
352
|
-
log.debug("retrying send", { conversationId, ...event });
|
|
352
|
+
log.debug?.("retrying send", { conversationId, ...event });
|
|
353
353
|
},
|
|
354
354
|
tokenProvider,
|
|
355
355
|
sharePointSiteId,
|
|
@@ -392,7 +392,7 @@ export async function sendPollMSTeams(
|
|
|
392
392
|
maxSelections,
|
|
393
393
|
});
|
|
394
394
|
|
|
395
|
-
log.debug("sending poll", {
|
|
395
|
+
log.debug?.("sending poll", {
|
|
396
396
|
conversationId,
|
|
397
397
|
pollId: pollCard.pollId,
|
|
398
398
|
optionCount: pollCard.options.length,
|
|
@@ -452,7 +452,7 @@ export async function sendAdaptiveCardMSTeams(
|
|
|
452
452
|
to,
|
|
453
453
|
});
|
|
454
454
|
|
|
455
|
-
log.debug("sending adaptive card", {
|
|
455
|
+
log.debug?.("sending adaptive card", {
|
|
456
456
|
conversationId,
|
|
457
457
|
cardType: card.type,
|
|
458
458
|
cardVersion: card.version,
|
package/src/store-fs.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { safeParseJson } from "openclaw/plugin-sdk";
|
|
4
5
|
import lockfile from "proper-lockfile";
|
|
5
6
|
|
|
6
7
|
const STORE_LOCK_OPTIONS = {
|
|
@@ -14,14 +15,6 @@ const STORE_LOCK_OPTIONS = {
|
|
|
14
15
|
stale: 30_000,
|
|
15
16
|
} as const;
|
|
16
17
|
|
|
17
|
-
function safeParseJson<T>(raw: string): T | null {
|
|
18
|
-
try {
|
|
19
|
-
return JSON.parse(raw) as T;
|
|
20
|
-
} catch {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
18
|
export async function readJsonFile<T>(
|
|
26
19
|
filePath: string,
|
|
27
20
|
fallback: T,
|