@openclaw/msteams 2026.8.1-beta.2 → 2026.8.1-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapter.runtime-DEYjslFX.cjs → adapter.runtime-8g-MOPfb.cjs} +4 -2
- package/dist/api.cjs +6 -6
- package/dist/{channel-DfCbi0d_.cjs → channel-KpWENcgK.cjs} +21 -64
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/{channel.runtime-BJmueA4q.cjs → channel.runtime-Bkzj8jZ0.cjs} +45 -32
- package/dist/{setup-surface-DAhGL2h8.cjs → channel.setup-mOFtsfYz.cjs} +88 -42
- package/dist/directory-contract-api.cjs +1 -1
- package/dist/{messenger-BqA8G3pY.cjs → messenger-IISPSOvj.cjs} +46 -40
- package/dist/{oauth-DktsbN22.cjs → oauth-C9So7uld.cjs} +2 -2
- package/dist/qa-runner-api.cjs +1 -1
- package/dist/{resolve-allowlist-C6YcNC9a.cjs → resolve-allowlist-CIfWUwuc.cjs} +70 -68
- package/dist/runtime-api.cjs +1 -1
- package/dist/setup-plugin-api.cjs +2 -36
- package/dist/{src-Bz9wY0Mr.cjs → src-C127-DcQ.cjs} +102 -96
- package/package.json +4 -4
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-D6vf50IK.cjs");
|
|
2
2
|
let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime");
|
|
3
|
-
let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
|
|
4
3
|
let node_crypto = require("node:crypto");
|
|
5
4
|
let node_fs_promises = require("node:fs/promises");
|
|
6
5
|
node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises, 1);
|
|
7
6
|
let node_path = require("node:path");
|
|
8
7
|
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
8
|
+
let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
|
|
9
9
|
let node_timers_promises = require("node:timers/promises");
|
|
10
10
|
let node_url = require("node:url");
|
|
11
11
|
let node_events = require("node:events");
|
|
12
12
|
let node_http = require("node:http");
|
|
13
13
|
//#region extensions/msteams/src/qa/bot-framework-server.ts
|
|
14
|
+
const AMBIGUOUS_GATEWAY_TIMEOUT_MARKER = "QA-MSTEAMS-AMBIGUOUS-504";
|
|
14
15
|
async function readJson(request) {
|
|
15
16
|
const chunks = [];
|
|
16
17
|
for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
@@ -53,7 +54,8 @@ async function startMSTeamsQaBotFrameworkServer(options) {
|
|
|
53
54
|
conversationId: route.conversationId,
|
|
54
55
|
...route.threadId ? { threadId: route.threadId } : {}
|
|
55
56
|
});
|
|
56
|
-
|
|
57
|
+
const acceptedButTimedOut = typeof activity.text === "string" && activity.text.includes(AMBIGUOUS_GATEWAY_TIMEOUT_MARKER);
|
|
58
|
+
sendJson(response, acceptedButTimedOut ? 504 : 200, acceptedButTimedOut ? { error: "gateway timeout after acceptance" } : { id: activityId });
|
|
57
59
|
})().catch((error) => {
|
|
58
60
|
sendJson(response, 500, { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(error) });
|
|
59
61
|
});
|
package/dist/api.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_channel = require("./channel-
|
|
3
|
-
const
|
|
4
|
-
exports.createMSTeamsSetupWizardBase =
|
|
2
|
+
const require_channel = require("./channel-KpWENcgK.cjs");
|
|
3
|
+
const require_channel_setup = require("./channel.setup-mOFtsfYz.cjs");
|
|
4
|
+
exports.createMSTeamsSetupWizardBase = require_channel_setup.createMSTeamsSetupWizardBase;
|
|
5
5
|
exports.msteamsPlugin = require_channel.msteamsPlugin;
|
|
6
|
-
exports.msteamsSetupAdapter =
|
|
7
|
-
exports.msteamsSetupWizard =
|
|
8
|
-
exports.openDelegatedOAuthUrl =
|
|
6
|
+
exports.msteamsSetupAdapter = require_channel_setup.msteamsSetupAdapter;
|
|
7
|
+
exports.msteamsSetupWizard = require_channel_setup.msteamsSetupWizard;
|
|
8
|
+
exports.openDelegatedOAuthUrl = require_channel_setup.openDelegatedOAuthUrl;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
require("./runtime-api.cjs");
|
|
2
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
let openclaw_plugin_sdk_account_helpers = require("openclaw/plugin-sdk/account-helpers");
|
|
2
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CIfWUwuc.cjs");
|
|
3
|
+
const require_directory_contract_api = require("./directory-contract-api.cjs");
|
|
4
|
+
const require_channel_setup = require("./channel.setup-mOFtsfYz.cjs");
|
|
6
5
|
let openclaw_plugin_sdk_channel_core = require("openclaw/plugin-sdk/channel-core");
|
|
7
6
|
let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
|
|
8
7
|
let openclaw_plugin_sdk_channel_pairing = require("openclaw/plugin-sdk/channel-pairing");
|
|
@@ -686,7 +685,13 @@ const collectMSTeamsSecurityWarnings = (0, openclaw_plugin_sdk_channel_policy.cr
|
|
|
686
685
|
resolveGroupPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy,
|
|
687
686
|
collect: ({ groupPolicy }) => groupPolicy === "open" ? ["- MS Teams groups: groupPolicy=\"open\" allows any member to trigger (mention-gated). Set channels.msteams.groupPolicy=\"allowlist\" + channels.msteams.groupAllowFrom to restrict senders."] : []
|
|
688
687
|
});
|
|
689
|
-
const
|
|
688
|
+
const collectMSTeamsSecurityFindings = openclaw_plugin_sdk_channel_policy.createConditionalWarningCollector.findings({
|
|
689
|
+
collectWarnings: collectMSTeamsSecurityWarnings,
|
|
690
|
+
checkId: "channels.msteams.groups.open",
|
|
691
|
+
severity: "critical",
|
|
692
|
+
title: "MS Teams security warning"
|
|
693
|
+
});
|
|
694
|
+
const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-Bkzj8jZ0.cjs")), "msTeamsChannelRuntime");
|
|
690
695
|
function jsonActionResult(data) {
|
|
691
696
|
return {
|
|
692
697
|
content: [{
|
|
@@ -821,7 +826,8 @@ async function runWithRequiredActionPinnedMessageTarget(params) {
|
|
|
821
826
|
});
|
|
822
827
|
}
|
|
823
828
|
function describeMSTeamsMessageTool({ cfg }) {
|
|
824
|
-
const
|
|
829
|
+
const account = require_channel_setup.resolveMSTeamsAccount(cfg);
|
|
830
|
+
const enabled = account.enabled && account.configured && account.tokenStatus === "available";
|
|
825
831
|
return {
|
|
826
832
|
actions: enabled ? [
|
|
827
833
|
"upload-file",
|
|
@@ -891,38 +897,13 @@ const msteamsMessageAdapter = (0, openclaw_plugin_sdk_channel_outbound.createCha
|
|
|
891
897
|
});
|
|
892
898
|
const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlugin)({
|
|
893
899
|
base: {
|
|
894
|
-
|
|
895
|
-
meta: {
|
|
896
|
-
...require_setup_surface.msteamsMeta,
|
|
897
|
-
aliases: [...require_setup_surface.msteamsMeta.aliases]
|
|
898
|
-
},
|
|
899
|
-
setupWizard: require_setup_surface.msteamsSetupWizard,
|
|
900
|
-
capabilities: {
|
|
901
|
-
chatTypes: [
|
|
902
|
-
"direct",
|
|
903
|
-
"channel",
|
|
904
|
-
"thread"
|
|
905
|
-
],
|
|
906
|
-
polls: true,
|
|
907
|
-
threads: true,
|
|
908
|
-
media: true
|
|
909
|
-
},
|
|
900
|
+
...require_channel_setup.msteamsSetupPlugin,
|
|
910
901
|
streaming: { blockStreamingCoalesceDefaults: {
|
|
911
902
|
minChars: 1500,
|
|
912
903
|
idleMs: 1e3
|
|
913
904
|
} },
|
|
914
905
|
agentPrompt: { messageToolHints: () => ["- Adaptive Cards supported. Use `action=send` with `card={type,version,body}` to send rich cards.", "- MSTeams targeting: omit `target` to reply to the current conversation (auto-inferred). Explicit targets: `user:ID` or `user:Display Name` (requires Graph API) for DMs, `conversation:19:...@thread.tacv2` for groups/channels. Prefer IDs over display names for speed."] },
|
|
915
906
|
groups: { resolveToolPolicy: resolveMSTeamsGroupToolPolicy },
|
|
916
|
-
reload: { configPrefixes: ["channels.msteams"] },
|
|
917
|
-
configSchema: require_config_schema.MSTeamsChannelConfigSchema,
|
|
918
|
-
config: {
|
|
919
|
-
...require_setup_surface.msteamsConfigAdapter,
|
|
920
|
-
isConfigured: (_account, cfg) => Boolean(require_resolve_allowlist.resolveMSTeamsCredentials(cfg.channels?.msteams)),
|
|
921
|
-
describeAccount: (account) => (0, openclaw_plugin_sdk_account_helpers.describeAccountSnapshot)({
|
|
922
|
-
account,
|
|
923
|
-
configured: account.configured
|
|
924
|
-
})
|
|
925
|
-
},
|
|
926
907
|
approvalCapability: msTeamsApprovalAuth,
|
|
927
908
|
doctor: {
|
|
928
909
|
dmAllowFromMode: "topOnly",
|
|
@@ -931,7 +912,6 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
931
912
|
warnOnEmptyGroupSenderAllowlist: true,
|
|
932
913
|
collectMutableAllowlistWarnings: collectMSTeamsMutableAllowlistWarnings
|
|
933
914
|
},
|
|
934
|
-
setupContract: require_setup_surface.msteamsSetupContract,
|
|
935
915
|
messaging: {
|
|
936
916
|
targetPrefixes: ["msteams", "teams"],
|
|
937
917
|
directTargetStyle: "user-prefixed",
|
|
@@ -945,34 +925,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
945
925
|
},
|
|
946
926
|
message: msteamsMessageAdapter,
|
|
947
927
|
directory: (0, openclaw_plugin_sdk_directory_runtime.createChannelDirectoryAdapter)({
|
|
948
|
-
|
|
949
|
-
const creds = require_resolve_allowlist.resolveMSTeamsCredentials(cfg.channels?.msteams);
|
|
950
|
-
if (!creds) return null;
|
|
951
|
-
return {
|
|
952
|
-
kind: "user",
|
|
953
|
-
id: creds.appId,
|
|
954
|
-
name: creds.appId
|
|
955
|
-
};
|
|
956
|
-
},
|
|
957
|
-
listPeers: async ({ cfg, query, limit }) => (0, openclaw_plugin_sdk_directory_runtime.listDirectoryEntriesFromSources)({
|
|
958
|
-
kind: "user",
|
|
959
|
-
sources: [cfg.channels?.msteams?.allowFrom ?? [], Object.keys(cfg.channels?.msteams?.dms ?? {})],
|
|
960
|
-
query,
|
|
961
|
-
limit,
|
|
962
|
-
normalizeId: (raw) => {
|
|
963
|
-
const normalized = require_resolve_allowlist.normalizeMSTeamsMessagingTarget(raw) ?? raw;
|
|
964
|
-
const lowered = normalized.toLowerCase();
|
|
965
|
-
if (lowered.startsWith("user:") || lowered.startsWith("conversation:")) return normalized;
|
|
966
|
-
return `user:${normalized}`;
|
|
967
|
-
}
|
|
968
|
-
}),
|
|
969
|
-
listGroups: async ({ cfg, query, limit }) => (0, openclaw_plugin_sdk_directory_runtime.listDirectoryEntriesFromSources)({
|
|
970
|
-
kind: "group",
|
|
971
|
-
sources: [Object.values(cfg.channels?.msteams?.teams ?? {}).flatMap((team) => Object.keys(team.channels ?? {}))],
|
|
972
|
-
query,
|
|
973
|
-
limit,
|
|
974
|
-
normalizeId: (raw) => `conversation:${raw.replace(/^conversation:/i, "").trim()}`
|
|
975
|
-
}),
|
|
928
|
+
...require_directory_contract_api.msteamsDirectoryContractPlugin.directory,
|
|
976
929
|
...(0, openclaw_plugin_sdk_directory_runtime.createRuntimeDirectoryLiveAdapter)({
|
|
977
930
|
getRuntime: loadMSTeamsChannelRuntime,
|
|
978
931
|
listPeersLive: (runtime) => runtime.listMSTeamsDirectoryPeersLive,
|
|
@@ -1087,6 +1040,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1087
1040
|
return results;
|
|
1088
1041
|
} },
|
|
1089
1042
|
actions: {
|
|
1043
|
+
providerOwnedReadGates: true,
|
|
1090
1044
|
describeMessageTool: describeMSTeamsMessageTool,
|
|
1091
1045
|
extractToolSendResult: ({ result, send }) => extractMSTeamsToolSendResult(result, send),
|
|
1092
1046
|
requiresTrustedRequesterSender: ({ action, toolContext }) => (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(toolContext?.currentChannelProvider)?.toLowerCase() === "msteams" && MSTEAMS_GROUP_MANAGEMENT_ACTIONS.has(action),
|
|
@@ -1467,11 +1421,14 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1467
1421
|
accountId: account.accountId,
|
|
1468
1422
|
enabled: account.enabled,
|
|
1469
1423
|
configured: account.configured,
|
|
1470
|
-
extra: {
|
|
1424
|
+
extra: {
|
|
1425
|
+
port: runtime?.port ?? null,
|
|
1426
|
+
tokenStatus: account.tokenStatus
|
|
1427
|
+
}
|
|
1471
1428
|
})
|
|
1472
1429
|
}),
|
|
1473
1430
|
gateway: { startAccount: async (ctx) => {
|
|
1474
|
-
const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./src-
|
|
1431
|
+
const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./src-C127-DcQ.cjs"));
|
|
1475
1432
|
const port = ctx.cfg.channels?.msteams?.webhook?.port ?? 3978;
|
|
1476
1433
|
const statusSink = (0, openclaw_plugin_sdk_channel_outbound.createAccountStatusSink)({
|
|
1477
1434
|
accountId: ctx.accountId,
|
|
@@ -1487,7 +1444,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
|
|
|
1487
1444
|
});
|
|
1488
1445
|
} }
|
|
1489
1446
|
},
|
|
1490
|
-
security: { collectWarnings: (
|
|
1447
|
+
security: { collectWarnings: ({ cfg }) => collectMSTeamsSecurityFindings({ cfg }) },
|
|
1491
1448
|
pairing: { text: {
|
|
1492
1449
|
idLabel: "msteamsUserId",
|
|
1493
1450
|
message: openclaw_plugin_sdk_channel_status.PAIRING_APPROVED_MESSAGE,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
2
2
|
require("./runtime-api.cjs");
|
|
3
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
4
|
-
const require_channel = require("./channel-
|
|
5
|
-
const
|
|
3
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CIfWUwuc.cjs");
|
|
4
|
+
const require_channel = require("./channel-KpWENcgK.cjs");
|
|
5
|
+
const require_channel_setup = require("./channel.setup-mOFtsfYz.cjs");
|
|
6
6
|
const require_polls = require("./polls-DvuJvaDG.cjs");
|
|
7
|
-
const require_messenger = require("./messenger-
|
|
7
|
+
const require_messenger = require("./messenger-IISPSOvj.cjs");
|
|
8
8
|
let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
|
|
9
9
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
10
10
|
let openclaw_plugin_sdk_reply_payload = require("openclaw/plugin-sdk/reply-payload");
|
|
@@ -654,6 +654,9 @@ async function findConversationReference(recipient) {
|
|
|
654
654
|
async function resolveMSTeamsSendContext(params) {
|
|
655
655
|
const msteamsCfg = params.cfg.channels?.msteams;
|
|
656
656
|
if (!msteamsCfg?.enabled) throw new Error("msteams provider is not enabled");
|
|
657
|
+
const account = require_channel_setup.resolveMSTeamsAccount(params.cfg);
|
|
658
|
+
if (account.tokenStatus === "configured_unavailable") throw new Error("msteams credential file is configured but unavailable");
|
|
659
|
+
if (!account.configured) throw new Error("msteams credentials not configured");
|
|
657
660
|
const creds = require_resolve_allowlist.resolveMSTeamsCredentials(msteamsCfg);
|
|
658
661
|
if (!creds) throw new Error("msteams credentials not configured");
|
|
659
662
|
const store = require_polls.createMSTeamsConversationStoreState();
|
|
@@ -675,7 +678,7 @@ async function resolveMSTeamsSendContext(params) {
|
|
|
675
678
|
} catch (err) {
|
|
676
679
|
log.warn?.("failed to remove blocked msteams conversation reference", {
|
|
677
680
|
conversationId,
|
|
678
|
-
error:
|
|
681
|
+
error: require_channel_setup.formatUnknownError(err)
|
|
679
682
|
});
|
|
680
683
|
}
|
|
681
684
|
throw new Error(`Stored Microsoft Teams conversation reference has blocked serviceUrl host: ${require_resolve_allowlist.describeBotFrameworkServiceUrlHost(ref.serviceUrl)}. The bot must receive a new message from this conversation before it can send proactively.`);
|
|
@@ -922,10 +925,10 @@ async function sendMessageMSTeams(params) {
|
|
|
922
925
|
kind: "media"
|
|
923
926
|
});
|
|
924
927
|
} catch (err) {
|
|
925
|
-
const classification =
|
|
926
|
-
const hint =
|
|
928
|
+
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
929
|
+
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
927
930
|
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
928
|
-
throw new Error(`msteams file send failed${status}: ${
|
|
931
|
+
throw new Error(`msteams file send failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
929
932
|
}
|
|
930
933
|
}
|
|
931
934
|
return sendTextWithMedia(ctx, messageText, void 0);
|
|
@@ -960,10 +963,10 @@ async function sendTextWithMedia(ctx, text, mediaUrl) {
|
|
|
960
963
|
serviceUrlBoundary: ctx.sdkCloudOptions
|
|
961
964
|
});
|
|
962
965
|
} catch (err) {
|
|
963
|
-
const classification =
|
|
964
|
-
const hint =
|
|
966
|
+
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
967
|
+
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
965
968
|
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
966
|
-
throw new Error(`msteams send failed${status}: ${
|
|
969
|
+
throw new Error(`msteams send failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
967
970
|
}
|
|
968
971
|
const messageId = platformMessageIds[0] ?? "unknown";
|
|
969
972
|
log.info("sent proactive message", {
|
|
@@ -995,10 +998,10 @@ async function sendProactiveActivity({ ctx, activity, errorPrefix }) {
|
|
|
995
998
|
activity
|
|
996
999
|
});
|
|
997
1000
|
} catch (err) {
|
|
998
|
-
const classification =
|
|
999
|
-
const hint =
|
|
1001
|
+
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
1002
|
+
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
1000
1003
|
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1001
|
-
throw new Error(`${errorPrefix} failed${status}: ${
|
|
1004
|
+
throw new Error(`${errorPrefix} failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1002
1005
|
}
|
|
1003
1006
|
}
|
|
1004
1007
|
/**
|
|
@@ -1102,10 +1105,10 @@ async function editMessageMSTeams(params) {
|
|
|
1102
1105
|
text
|
|
1103
1106
|
}, { serviceUrlBoundary: sdkCloudOptions });
|
|
1104
1107
|
} catch (err) {
|
|
1105
|
-
const classification =
|
|
1106
|
-
const hint =
|
|
1108
|
+
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
1109
|
+
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
1107
1110
|
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1108
|
-
throw new Error(`msteams edit failed${status}: ${
|
|
1111
|
+
throw new Error(`msteams edit failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1109
1112
|
}
|
|
1110
1113
|
log.info("edited proactive message", {
|
|
1111
1114
|
conversationId,
|
|
@@ -1132,10 +1135,10 @@ async function deleteMessageMSTeams(params) {
|
|
|
1132
1135
|
try {
|
|
1133
1136
|
await require_messenger.deleteMSTeamsActivityWithReference(app, require_messenger.buildConversationReference(ref), activityId, { serviceUrlBoundary: sdkCloudOptions });
|
|
1134
1137
|
} catch (err) {
|
|
1135
|
-
const classification =
|
|
1136
|
-
const hint =
|
|
1138
|
+
const classification = require_channel_setup.classifyMSTeamsSendError(err);
|
|
1139
|
+
const hint = require_channel_setup.formatMSTeamsSendErrorHint(classification);
|
|
1137
1140
|
const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
|
|
1138
|
-
throw new Error(`msteams delete failed${status}: ${
|
|
1141
|
+
throw new Error(`msteams delete failed${status}: ${require_channel_setup.formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
|
|
1139
1142
|
}
|
|
1140
1143
|
log.info("deleted proactive message", {
|
|
1141
1144
|
conversationId,
|
|
@@ -1149,6 +1152,16 @@ const MSTEAMS_TEXT_CHUNK_LIMIT = 4e3;
|
|
|
1149
1152
|
function resolveMSTeamsEffectiveTextChunkLimit(configuredLimit) {
|
|
1150
1153
|
return typeof configuredLimit === "number" && configuredLimit > 0 ? Math.min(configuredLimit, MSTEAMS_TEXT_CHUNK_LIMIT) : MSTEAMS_TEXT_CHUNK_LIMIT;
|
|
1151
1154
|
}
|
|
1155
|
+
function toMSTeamsOutboundResult(result) {
|
|
1156
|
+
const { conversationId, ...delivery } = result;
|
|
1157
|
+
return {
|
|
1158
|
+
...delivery,
|
|
1159
|
+
target: {
|
|
1160
|
+
kind: "conversation",
|
|
1161
|
+
id: conversationId
|
|
1162
|
+
}
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1152
1165
|
function resolveMSTeamsThreadTarget(to, threadId) {
|
|
1153
1166
|
const normalizedThreadId = threadId == null ? "" : String(threadId).trim();
|
|
1154
1167
|
const graphChannelId = to.includes("/") ? to.slice(to.indexOf("/") + 1) : "";
|
|
@@ -1206,11 +1219,11 @@ const msteamsOutbound = {
|
|
|
1206
1219
|
sendPayload: async ({ cfg, to, text, mediaUrl, mediaAccess, mediaLocalRoots, mediaReadFile, payload, deps, onDeliveryResult, threadId }) => {
|
|
1207
1220
|
const deliveryTarget = resolveMSTeamsThreadTarget(to, threadId);
|
|
1208
1221
|
const presentationCard = (0, openclaw_plugin_sdk_string_coerce_runtime.asOptionalRecord)(payload.channelData?.msteams)?.presentationCard;
|
|
1209
|
-
if (presentationCard && typeof presentationCard === "object" && !Array.isArray(presentationCard)) return (0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", await sendAdaptiveCardMSTeams({
|
|
1222
|
+
if (presentationCard && typeof presentationCard === "object" && !Array.isArray(presentationCard)) return (0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", toMSTeamsOutboundResult(await sendAdaptiveCardMSTeams({
|
|
1210
1223
|
cfg,
|
|
1211
1224
|
to: deliveryTarget,
|
|
1212
1225
|
card: presentationCard
|
|
1213
|
-
}));
|
|
1226
|
+
})));
|
|
1214
1227
|
const mediaUrls = (0, openclaw_plugin_sdk_string_normalization_runtime.normalizeStringEntries)((0, openclaw_plugin_sdk_reply_payload.resolvePayloadMediaUrls)({
|
|
1215
1228
|
...payload,
|
|
1216
1229
|
mediaUrl: payload.mediaUrl ?? mediaUrl
|
|
@@ -1224,7 +1237,7 @@ const msteamsOutbound = {
|
|
|
1224
1237
|
text,
|
|
1225
1238
|
mediaUrls,
|
|
1226
1239
|
onResult: async (deliveryResult) => {
|
|
1227
|
-
await onDeliveryResult?.((0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", deliveryResult));
|
|
1240
|
+
await onDeliveryResult?.((0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", toMSTeamsOutboundResult(deliveryResult)));
|
|
1228
1241
|
},
|
|
1229
1242
|
send: async ({ text: textLocal, mediaUrl: mediaUrlLocal }) => await send(deliveryTarget, textLocal, {
|
|
1230
1243
|
mediaUrl: mediaUrlLocal,
|
|
@@ -1233,7 +1246,7 @@ const msteamsOutbound = {
|
|
|
1233
1246
|
mediaReadFile
|
|
1234
1247
|
})
|
|
1235
1248
|
});
|
|
1236
|
-
if (result) return (0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", result);
|
|
1249
|
+
if (result) return (0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", toMSTeamsOutboundResult(result));
|
|
1237
1250
|
}
|
|
1238
1251
|
if (text.trim()) {
|
|
1239
1252
|
const send = resolveMSTeamsTextSend({
|
|
@@ -1244,22 +1257,22 @@ const msteamsOutbound = {
|
|
|
1244
1257
|
let result;
|
|
1245
1258
|
for (const chunk of chunks) {
|
|
1246
1259
|
result = await send(deliveryTarget, chunk);
|
|
1247
|
-
await onDeliveryResult?.((0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", result));
|
|
1260
|
+
await onDeliveryResult?.((0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", toMSTeamsOutboundResult(result)));
|
|
1248
1261
|
}
|
|
1249
|
-
return (0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", result);
|
|
1262
|
+
return (0, openclaw_plugin_sdk_channel_send_result.attachChannelToResult)("msteams", toMSTeamsOutboundResult(result));
|
|
1250
1263
|
}
|
|
1251
1264
|
throw new Error("MS Teams payload send requires text, media, or a presentation card.");
|
|
1252
1265
|
},
|
|
1253
1266
|
...(0, openclaw_plugin_sdk_channel_send_result.createAttachedChannelResultAdapter)({
|
|
1254
1267
|
channel: "msteams",
|
|
1255
1268
|
sendText: async ({ cfg, to, text, deps, threadId }) => {
|
|
1256
|
-
return await resolveMSTeamsTextSend({
|
|
1269
|
+
return toMSTeamsOutboundResult(await resolveMSTeamsTextSend({
|
|
1257
1270
|
cfg,
|
|
1258
1271
|
deps
|
|
1259
|
-
})(resolveMSTeamsThreadTarget(to, threadId), text);
|
|
1272
|
+
})(resolveMSTeamsThreadTarget(to, threadId), text));
|
|
1260
1273
|
},
|
|
1261
1274
|
sendMedia: async ({ cfg, to, text, mediaUrl, mediaAccess, mediaLocalRoots, mediaReadFile, deps, threadId }) => {
|
|
1262
|
-
return await resolveMSTeamsMediaSend({
|
|
1275
|
+
return toMSTeamsOutboundResult(await resolveMSTeamsMediaSend({
|
|
1263
1276
|
cfg,
|
|
1264
1277
|
deps
|
|
1265
1278
|
})(resolveMSTeamsThreadTarget(to, threadId), text, {
|
|
@@ -1267,7 +1280,7 @@ const msteamsOutbound = {
|
|
|
1267
1280
|
mediaAccess,
|
|
1268
1281
|
mediaLocalRoots,
|
|
1269
1282
|
mediaReadFile
|
|
1270
|
-
});
|
|
1283
|
+
}));
|
|
1271
1284
|
},
|
|
1272
1285
|
sendPoll: async ({ cfg, to, poll, threadId }) => {
|
|
1273
1286
|
const maxSelections = poll.maxSelections ?? 1;
|
|
@@ -1345,7 +1358,7 @@ async function probeMSTeams(cfg) {
|
|
|
1345
1358
|
} catch (err) {
|
|
1346
1359
|
graph = {
|
|
1347
1360
|
ok: false,
|
|
1348
|
-
error:
|
|
1361
|
+
error: require_channel_setup.formatUnknownError(err)
|
|
1349
1362
|
};
|
|
1350
1363
|
}
|
|
1351
1364
|
let delegatedAuth;
|
|
@@ -1379,7 +1392,7 @@ async function probeMSTeams(cfg) {
|
|
|
1379
1392
|
return {
|
|
1380
1393
|
ok: false,
|
|
1381
1394
|
appId: creds.appId,
|
|
1382
|
-
error:
|
|
1395
|
+
error: require_channel_setup.formatUnknownError(err)
|
|
1383
1396
|
};
|
|
1384
1397
|
}
|
|
1385
1398
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CIfWUwuc.cjs");
|
|
2
|
+
const require_config_schema = require("./config-schema-C4CszdDi.cjs");
|
|
2
3
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
3
|
-
let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
|
|
4
4
|
let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
|
|
5
|
+
let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
|
|
5
6
|
let openclaw_plugin_sdk_number_runtime = require("openclaw/plugin-sdk/number-runtime");
|
|
6
7
|
let openclaw_plugin_sdk_channel_config_helpers = require("openclaw/plugin-sdk/channel-config-helpers");
|
|
8
|
+
let openclaw_plugin_sdk_secret_file_runtime = require("openclaw/plugin-sdk/secret-file-runtime");
|
|
9
|
+
let openclaw_plugin_sdk_account_helpers = require("openclaw/plugin-sdk/account-helpers");
|
|
7
10
|
let openclaw_plugin_sdk_channel_setup = require("openclaw/plugin-sdk/channel-setup");
|
|
8
11
|
let openclaw_plugin_sdk_setup = require("openclaw/plugin-sdk/setup");
|
|
9
12
|
let openclaw_plugin_sdk_setup_tools = require("openclaw/plugin-sdk/setup-tools");
|
|
@@ -20,13 +23,23 @@ const msteamsMeta = {
|
|
|
20
23
|
aliases: ["teams"],
|
|
21
24
|
order: 60
|
|
22
25
|
};
|
|
26
|
+
function resolveMSTeamsAccount(cfg) {
|
|
27
|
+
const config = cfg.channels?.msteams;
|
|
28
|
+
const credentials = require_resolve_allowlist.resolveMSTeamsCredentials(config);
|
|
29
|
+
const certificatePath = credentials?.type === "federated" && !credentials.useManagedIdentity ? credentials.certificatePath : void 0;
|
|
30
|
+
const certificate = certificatePath ? (0, openclaw_plugin_sdk_secret_file_runtime.tryReadSecretFileSync)(certificatePath, "Microsoft Teams certificate", void 0, { configPath: config?.certificatePath?.trim() ? "channels.msteams.certificatePath" : "env.MSTEAMS_CERTIFICATE_PATH" }) : void 0;
|
|
31
|
+
const unavailable = certificate?.status === "configured_unavailable";
|
|
32
|
+
return {
|
|
33
|
+
accountId: openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID,
|
|
34
|
+
enabled: config?.enabled !== false,
|
|
35
|
+
configured: Boolean(credentials),
|
|
36
|
+
tokenStatus: !credentials ? "missing" : unavailable ? "configured_unavailable" : "available",
|
|
37
|
+
...unavailable ? { credentialDiagnostics: [certificate.diagnostic] } : {}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
23
40
|
const msteamsConfigAdapter = (0, openclaw_plugin_sdk_channel_config_helpers.createTopLevelChannelConfigAdapter)({
|
|
24
41
|
sectionKey: "msteams",
|
|
25
|
-
resolveAccount:
|
|
26
|
-
accountId: openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID,
|
|
27
|
-
enabled: cfg.channels?.msteams?.enabled !== false,
|
|
28
|
-
configured: Boolean(require_resolve_allowlist.resolveMSTeamsCredentials(cfg.channels?.msteams))
|
|
29
|
-
}),
|
|
42
|
+
resolveAccount: resolveMSTeamsAccount,
|
|
30
43
|
resolveAccessorAccount: ({ cfg }) => ({
|
|
31
44
|
allowFrom: cfg.channels?.msteams?.allowFrom,
|
|
32
45
|
defaultTo: cfg.channels?.msteams?.defaultTo
|
|
@@ -220,12 +233,8 @@ function parseNonNegativeRetryAfterSeconds(raw) {
|
|
|
220
233
|
});
|
|
221
234
|
}
|
|
222
235
|
/**
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
* Important: We only mark errors as retryable when we have an explicit HTTP
|
|
226
|
-
* status code that indicates the message was not accepted (e.g. 429, 5xx).
|
|
227
|
-
* For transport-level errors where delivery is ambiguous, we prefer to avoid
|
|
228
|
-
* retries to reduce the chance of duplicate posts.
|
|
236
|
+
* Owns retry safety and delivery ambiguity for Teams send failures.
|
|
237
|
+
* Only Teams rate-limit rejection proves this unkeyed POST safe to replay.
|
|
229
238
|
*/
|
|
230
239
|
function classifyMSTeamsSendError(err) {
|
|
231
240
|
const statusCode = extractStatusCode(err);
|
|
@@ -249,15 +258,15 @@ function classifyMSTeamsSendError(err) {
|
|
|
249
258
|
};
|
|
250
259
|
}
|
|
251
260
|
if (statusCode === 429) return {
|
|
252
|
-
kind: "
|
|
261
|
+
kind: "replay-safe",
|
|
253
262
|
statusCode,
|
|
254
263
|
retryAfterMs: retryAfterMs ?? void 0,
|
|
255
264
|
errorCode
|
|
256
265
|
};
|
|
257
266
|
if (statusCode === 408 || statusCode != null && statusCode >= 500) return {
|
|
258
|
-
kind: "
|
|
267
|
+
kind: "ambiguous",
|
|
268
|
+
source: "http",
|
|
259
269
|
statusCode,
|
|
260
|
-
retryAfterMs: retryAfterMs ?? void 0,
|
|
261
270
|
errorCode
|
|
262
271
|
};
|
|
263
272
|
if (statusCode != null && statusCode >= 400) return {
|
|
@@ -265,17 +274,14 @@ function classifyMSTeamsSendError(err) {
|
|
|
265
274
|
statusCode,
|
|
266
275
|
errorCode
|
|
267
276
|
};
|
|
268
|
-
if (statusCode == null) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
};
|
|
274
|
-
}
|
|
277
|
+
if (statusCode == null && (0, openclaw_plugin_sdk_retry_runtime.isTransientNetworkError)(err)) return {
|
|
278
|
+
kind: "ambiguous",
|
|
279
|
+
source: "transport",
|
|
280
|
+
errorCode
|
|
281
|
+
};
|
|
275
282
|
return {
|
|
276
283
|
kind: "unknown",
|
|
277
284
|
statusCode: statusCode ?? void 0,
|
|
278
|
-
retryAfterMs: retryAfterMs ?? void 0,
|
|
279
285
|
errorCode
|
|
280
286
|
};
|
|
281
287
|
}
|
|
@@ -294,9 +300,15 @@ function isRevokedProxyError(err) {
|
|
|
294
300
|
function formatMSTeamsSendErrorHint(classification) {
|
|
295
301
|
if (classification.kind === "auth") return "check msteams appId/appPassword/tenantId (or env vars MSTEAMS_APP_ID/MSTEAMS_APP_PASSWORD/MSTEAMS_TENANT_ID)";
|
|
296
302
|
if (classification.errorCode === "ContentStreamNotAllowed") return "Teams expired the content stream; stop streaming earlier and fall back to normal message delivery";
|
|
297
|
-
if (classification.kind === "
|
|
298
|
-
if (classification.kind === "
|
|
299
|
-
|
|
303
|
+
if (classification.kind === "replay-safe") return "Teams throttled the bot; backing off may help";
|
|
304
|
+
if (classification.kind === "ambiguous") {
|
|
305
|
+
if (classification.source === "transport") return "transport-level failure sending to Teams Bot Connector (smba.trafficmanager.net); the outcome is unknown, so check egress and conversation history before taking further action";
|
|
306
|
+
return "Teams/Bot Framework delivery outcome is unknown; inspect the conversation history before taking further action";
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function formatMSTeamsDeliveryFailureGuidance(classification) {
|
|
310
|
+
if (classification.kind === "replay-safe") return "The request was rate-limited before delivery; retrying later may succeed.";
|
|
311
|
+
if (classification.kind === "ambiguous") return "Delivery may already have succeeded; do not send the same content again without checking the conversation.";
|
|
300
312
|
}
|
|
301
313
|
//#endregion
|
|
302
314
|
//#region extensions/msteams/src/setup-surface.ts
|
|
@@ -466,7 +478,7 @@ const msteamsSetupWizard = {
|
|
|
466
478
|
};
|
|
467
479
|
let oauthModule;
|
|
468
480
|
try {
|
|
469
|
-
oauthModule = await Promise.resolve().then(() => require("./oauth-
|
|
481
|
+
oauthModule = await Promise.resolve().then(() => require("./oauth-C9So7uld.cjs"));
|
|
470
482
|
} catch (err) {
|
|
471
483
|
await noteDelegatedAuthFailure(err);
|
|
472
484
|
return {
|
|
@@ -520,6 +532,40 @@ const msteamsSetupWizard = {
|
|
|
520
532
|
disable: (cfg) => (0, openclaw_plugin_sdk_setup.setSetupChannelEnabled)(cfg, channel, false)
|
|
521
533
|
};
|
|
522
534
|
//#endregion
|
|
535
|
+
//#region extensions/msteams/src/channel.setup.ts
|
|
536
|
+
const msteamsSetupPlugin = {
|
|
537
|
+
id: "msteams",
|
|
538
|
+
meta: {
|
|
539
|
+
...msteamsMeta,
|
|
540
|
+
aliases: [...msteamsMeta.aliases]
|
|
541
|
+
},
|
|
542
|
+
capabilities: {
|
|
543
|
+
chatTypes: [
|
|
544
|
+
"direct",
|
|
545
|
+
"channel",
|
|
546
|
+
"group",
|
|
547
|
+
"thread"
|
|
548
|
+
],
|
|
549
|
+
polls: true,
|
|
550
|
+
threads: true,
|
|
551
|
+
media: true,
|
|
552
|
+
reactions: true
|
|
553
|
+
},
|
|
554
|
+
reload: { configPrefixes: ["channels.msteams"] },
|
|
555
|
+
configSchema: require_config_schema.MSTeamsChannelConfigSchema,
|
|
556
|
+
config: {
|
|
557
|
+
...msteamsConfigAdapter,
|
|
558
|
+
isConfigured: (account) => account.configured,
|
|
559
|
+
describeAccount: (account) => (0, openclaw_plugin_sdk_account_helpers.describeAccountSnapshot)({
|
|
560
|
+
account,
|
|
561
|
+
configured: account.configured,
|
|
562
|
+
extra: { tokenStatus: account.tokenStatus }
|
|
563
|
+
})
|
|
564
|
+
},
|
|
565
|
+
setupWizard: msteamsSetupWizard,
|
|
566
|
+
setupContract: msteamsSetupContract
|
|
567
|
+
};
|
|
568
|
+
//#endregion
|
|
523
569
|
Object.defineProperty(exports, "classifyMSTeamsSendError", {
|
|
524
570
|
enumerable: true,
|
|
525
571
|
get: function() {
|
|
@@ -532,6 +578,12 @@ Object.defineProperty(exports, "createMSTeamsSetupWizardBase", {
|
|
|
532
578
|
return createMSTeamsSetupWizardBase;
|
|
533
579
|
}
|
|
534
580
|
});
|
|
581
|
+
Object.defineProperty(exports, "formatMSTeamsDeliveryFailureGuidance", {
|
|
582
|
+
enumerable: true,
|
|
583
|
+
get: function() {
|
|
584
|
+
return formatMSTeamsDeliveryFailureGuidance;
|
|
585
|
+
}
|
|
586
|
+
});
|
|
535
587
|
Object.defineProperty(exports, "formatMSTeamsSendErrorHint", {
|
|
536
588
|
enumerable: true,
|
|
537
589
|
get: function() {
|
|
@@ -550,28 +602,16 @@ Object.defineProperty(exports, "isRevokedProxyError", {
|
|
|
550
602
|
return isRevokedProxyError;
|
|
551
603
|
}
|
|
552
604
|
});
|
|
553
|
-
Object.defineProperty(exports, "msteamsConfigAdapter", {
|
|
554
|
-
enumerable: true,
|
|
555
|
-
get: function() {
|
|
556
|
-
return msteamsConfigAdapter;
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
Object.defineProperty(exports, "msteamsMeta", {
|
|
560
|
-
enumerable: true,
|
|
561
|
-
get: function() {
|
|
562
|
-
return msteamsMeta;
|
|
563
|
-
}
|
|
564
|
-
});
|
|
565
605
|
Object.defineProperty(exports, "msteamsSetupAdapter", {
|
|
566
606
|
enumerable: true,
|
|
567
607
|
get: function() {
|
|
568
608
|
return msteamsSetupAdapter;
|
|
569
609
|
}
|
|
570
610
|
});
|
|
571
|
-
Object.defineProperty(exports, "
|
|
611
|
+
Object.defineProperty(exports, "msteamsSetupPlugin", {
|
|
572
612
|
enumerable: true,
|
|
573
613
|
get: function() {
|
|
574
|
-
return
|
|
614
|
+
return msteamsSetupPlugin;
|
|
575
615
|
}
|
|
576
616
|
});
|
|
577
617
|
Object.defineProperty(exports, "msteamsSetupWizard", {
|
|
@@ -586,3 +626,9 @@ Object.defineProperty(exports, "openDelegatedOAuthUrl", {
|
|
|
586
626
|
return openDelegatedOAuthUrl;
|
|
587
627
|
}
|
|
588
628
|
});
|
|
629
|
+
Object.defineProperty(exports, "resolveMSTeamsAccount", {
|
|
630
|
+
enumerable: true,
|
|
631
|
+
get: function() {
|
|
632
|
+
return resolveMSTeamsAccount;
|
|
633
|
+
}
|
|
634
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
2
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CIfWUwuc.cjs");
|
|
3
3
|
let openclaw_plugin_sdk_directory_runtime = require("openclaw/plugin-sdk/directory-runtime");
|
|
4
4
|
const msteamsDirectoryContractPlugin = {
|
|
5
5
|
id: "msteams",
|