@openclaw/msteams 2026.9.8 → 2026.10.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/.setup/{adapter.runtime-BiWeMKXE.cjs → adapter.runtime-D0HYByze.cjs} +9 -7
  2. package/dist/.setup/{approval-handler.runtime-D1s7UR3U.cjs → approval-handler.runtime-C-RJ3wXc.cjs} +3 -3
  3. package/dist/.setup/{channel-ByzS7QJ0.cjs → channel-BFhXodl2.cjs} +61 -75
  4. package/dist/.setup/{channel.runtime-Baz8XDFs.cjs → channel.runtime-D9jrw2SN.cjs} +22 -46
  5. package/dist/.setup/{channel.setup-DL8lcWT_.cjs → channel.setup-ss0TO-ap.cjs} +30 -36
  6. package/dist/.setup/{conversation-store-state-B7JuyZTm.cjs → conversation-store-state-f7V8CVNy.cjs} +62 -128
  7. package/dist/.setup/{monitor-BJ7IyH4y.cjs → monitor-DfSPCRkk.cjs} +71 -171
  8. package/dist/.setup/{oauth-DQjOnJ4l.cjs → oauth-CYxMYIOQ.cjs} +1 -1
  9. package/dist/.setup/{reaction-types-CQ4oSUe7.cjs → reaction-types-B-GEv57k.cjs} +1 -1
  10. package/dist/.setup/{resolve-allowlist-Pl_NQFYH.cjs → resolve-allowlist-Ct9yxQUw.cjs} +16 -134
  11. package/dist/.setup/{send-VUM7Sryb.cjs → send-7VV1iCai.cjs} +24 -70
  12. package/dist/.setup/{setup-plugin-api-Dyf8kF-l.cjs → setup-plugin-api-B0OFG32J.cjs} +1 -1
  13. package/dist/.setup/{thread-session--rw3BTal.cjs → thread-session-ClI-lSyG.cjs} +1 -1
  14. package/dist/.setup/token-config-DOt3XwVa.cjs +139 -0
  15. package/dist/api.cjs +2 -2
  16. package/dist/channel-plugin-api.cjs +1 -1
  17. package/dist/directory-contract-api.cjs +3 -2
  18. package/dist/doctor-backup-resources.cjs +21 -0
  19. package/dist/doctor-contract-api.cjs +37 -19
  20. package/dist/qa-runner-api.cjs +1 -1
  21. package/dist/runtime-api.cjs +0 -20
  22. package/dist/setup-entry.cjs +1 -1
  23. package/dist/setup-plugin-api.cjs +1 -1
  24. package/package.json +4 -4
  25. package/dist/.setup/delegated-state-u-ywZyZT.cjs +0 -70
@@ -1,7 +1,7 @@
1
1
  const require_runtime = require("./runtime-gZTAuFux.cjs");
2
2
  require("../runtime-api.cjs");
3
3
  const require_bot_framework_service_url = require("./bot-framework-service-url-BUhTe8F3.cjs");
4
- const require_delegated_state = require("./delegated-state-u-ywZyZT.cjs");
4
+ const require_token_config = require("./token-config-DOt3XwVa.cjs");
5
5
  let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
6
6
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
7
7
  let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
@@ -17,7 +17,6 @@ let openclaw_plugin_sdk_text_utility_runtime = require("openclaw/plugin-sdk/text
17
17
  let openclaw_plugin_sdk_secret_file = require("openclaw/plugin-sdk/secret-file");
18
18
  let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
19
19
  let node_module = require("node:module");
20
- let openclaw_plugin_sdk_secret_input = require("openclaw/plugin-sdk/secret-input");
21
20
  let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
22
21
  //#region extensions/msteams/src/request-timeout.ts
23
22
  const MSTEAMS_REQUEST_TIMEOUT_MS = 3e4;
@@ -154,16 +153,6 @@ function tryBuildGraphSharesUrlForSharedLink(url) {
154
153
  if (!isGraphSharedLinkUrl(url)) return;
155
154
  return `${GRAPH_ROOT}/shares/${encodeGraphShareId(url)}/driveItem/content`;
156
155
  }
157
- function resolveRequestUrl(input) {
158
- if (typeof input === "string") return input;
159
- if (input instanceof URL) return input.toString();
160
- if (typeof input === "object" && input && "url" in input && typeof input.url === "string") return input.url;
161
- try {
162
- return JSON.stringify(input);
163
- } catch {
164
- return "";
165
- }
166
- }
167
156
  function normalizeContentType(value) {
168
157
  const trimmed = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(value);
169
158
  if (!trimmed) return;
@@ -280,15 +269,8 @@ function resolveAttachmentFetchPolicy(params) {
280
269
  };
281
270
  }
282
271
  function applyAuthorizationHeaderForUrl(params) {
283
- if (!params.bearerToken) {
284
- params.headers.delete("Authorization");
285
- return;
286
- }
287
- if ((0, openclaw_plugin_sdk_ssrf_policy.isHttpsUrlAllowedByHostnameSuffixAllowlist)(params.url, params.authAllowHosts)) {
288
- params.headers.set("Authorization", `Bearer ${params.bearerToken}`);
289
- return;
290
- }
291
- params.headers.delete("Authorization");
272
+ if (params.bearerToken && (0, openclaw_plugin_sdk_ssrf_policy.isHttpsUrlAllowedByHostnameSuffixAllowlist)(params.url, params.authAllowHosts)) params.headers.set("Authorization", `Bearer ${params.bearerToken}`);
273
+ else params.headers.delete("Authorization");
292
274
  }
293
275
  async function resolveAndValidateIP(hostname, resolveFn) {
294
276
  const resolve = resolveFn ?? node_dns_promises.lookup;
@@ -299,7 +281,6 @@ async function resolveAndValidateIP(hostname, resolveFn) {
299
281
  throw new Error(`DNS resolution failed for "${hostname}"`);
300
282
  }
301
283
  if ((0, openclaw_plugin_sdk_ssrf_policy.isPrivateIpAddress)(resolved.address)) throw new Error(`Hostname "${hostname}" resolves to private/reserved IP (${resolved.address})`);
302
- return resolved.address;
303
284
  }
304
285
  const MAX_SAFE_REDIRECTS = 5;
305
286
  function isRedirectStatus(status) {
@@ -316,7 +297,7 @@ function isRedirectStatus(status) {
316
297
  async function safeFetchWithPolicy(params) {
317
298
  const { allowHosts, authAllowHosts } = params.policy;
318
299
  const resolveFn = params.resolveFn ?? node_dns_promises.lookup;
319
- const hasDispatcher = Boolean(params.requestInit && typeof params.requestInit === "object" && "dispatcher" in params.requestInit);
300
+ const hasDispatcher = params.requestInit && "dispatcher" in params.requestInit;
320
301
  const currentHeaders = new Headers(params.requestInit?.headers);
321
302
  const currentUrl = params.url;
322
303
  if (!(0, openclaw_plugin_sdk_ssrf_policy.isHttpsUrlAllowedByHostnameSuffixAllowlist)(currentUrl, allowHosts)) throw new Error(`Initial download URL blocked: ${currentUrl}`);
@@ -590,25 +571,11 @@ const loadSdkModules = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeMod
590
571
  ExpressAdapter: apps.ExpressAdapter,
591
572
  cloudFromName: api.cloudFromName
592
573
  })));
593
- /**
594
- * Lazily construct an ExpressAdapter that the Teams SDK App can register its
595
- * routes on. The dynamic import keeps the SDK bundle off the hot startup path
596
- * when msteams is disabled; the structural return type matches what
597
- * `loadMSTeamsSdkWithAuth` accepts as its `httpServerAdapter` option.
598
- */
574
+ /** Keep the SDK off disabled-channel startup paths. */
599
575
  async function createMSTeamsExpressAdapter(serverOrApp) {
600
576
  const { ExpressAdapter } = await loadSdkModules();
601
577
  return new ExpressAdapter(serverOrApp);
602
578
  }
603
- /**
604
- * Create a Teams SDK App instance from credentials. The App manages token
605
- * acquisition, JWT validation, and the HTTP server lifecycle.
606
- *
607
- * Auth modes:
608
- * - Secret: clientId + clientSecret → MSAL client credential flow (SDK built-in)
609
- * - Managed identity: clientId + managedIdentityClientId → SDK built-in MI support
610
- * - Certificate: clientId + custom token provider via @azure/identity
611
- */
612
579
  async function createMSTeamsApp(creds, options) {
613
580
  const { App, cloudFromName } = await loadSdkModules();
614
581
  const privateQaRuntime = resolveMSTeamsPrivateQaRuntime();
@@ -660,12 +627,8 @@ async function createFederatedApp(creds, App, appOptions) {
660
627
  }
661
628
  function createCertificateApp(creds, privateKey, App, appOptions) {
662
629
  let credentialPromise = null;
663
- const getCredential = async () => {
664
- if (!credentialPromise) credentialPromise = loadAzureIdentity().then((az) => new az.ClientCertificateCredential(creds.tenantId, creds.appId, { certificate: privateKey }));
665
- return credentialPromise;
666
- };
667
630
  const tokenProvider = async (scope) => {
668
- const token = await (await getCredential()).getToken(scope);
631
+ const token = await (await (credentialPromise ??= loadAzureIdentity().then((az) => new az.ClientCertificateCredential(creds.tenantId, creds.appId, { certificate: privateKey })))).getToken(scope);
669
632
  if (!token?.token) throw new Error("Failed to acquire token via certificate credential.");
670
633
  return token.token;
671
634
  };
@@ -799,62 +762,8 @@ async function refreshMSTeamsDelegatedTokens(params) {
799
762
  }
800
763
  //#endregion
801
764
  //#region extensions/msteams/src/token.ts
802
- function resolveAuthType(cfg) {
803
- const fromCfg = cfg?.authType;
804
- if (fromCfg === "secret" || fromCfg === "federated") return fromCfg;
805
- if (process.env.MSTEAMS_AUTH_TYPE === "federated") return "federated";
806
- return "secret";
807
- }
808
- function resolveFederatedPath(configValue, envValue) {
809
- if ((0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(configValue)) return configValue;
810
- if ((0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(envValue)) return envValue;
811
- }
812
- function hasConfiguredMSTeamsCredentials(cfg) {
813
- const authType = resolveAuthType(cfg);
814
- const hasAppId = Boolean((0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.appId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_APP_ID));
815
- const hasTenantId = Boolean((0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.tenantId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_TENANT_ID));
816
- if (authType === "federated") {
817
- const hasCert = Boolean(resolveFederatedPath(cfg?.certificatePath, process.env.MSTEAMS_CERTIFICATE_PATH));
818
- const hasManagedIdentity = cfg?.useManagedIdentity ?? process.env.MSTEAMS_USE_MANAGED_IDENTITY === "true";
819
- return hasAppId && hasTenantId && (hasCert || hasManagedIdentity);
820
- }
821
- return Boolean((0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.appId) && (0, openclaw_plugin_sdk_secret_input.hasConfiguredSecretInput)(cfg?.appPassword) && (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.tenantId));
822
- }
823
- function resolveMSTeamsCredentials(cfg) {
824
- const authType = resolveAuthType(cfg);
825
- const appId = (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.appId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_APP_ID);
826
- const tenantId = (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.tenantId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_TENANT_ID);
827
- if (!appId || !tenantId) return;
828
- if (authType === "federated") {
829
- const certificatePath = resolveFederatedPath(cfg?.certificatePath, process.env.MSTEAMS_CERTIFICATE_PATH);
830
- const certificateThumbprint = cfg?.certificateThumbprint || process.env.MSTEAMS_CERTIFICATE_THUMBPRINT || void 0;
831
- const useManagedIdentity = cfg?.useManagedIdentity ?? process.env.MSTEAMS_USE_MANAGED_IDENTITY === "true";
832
- const managedIdentityClientId = cfg?.managedIdentityClientId || process.env.MSTEAMS_MANAGED_IDENTITY_CLIENT_ID || void 0;
833
- if (!certificatePath && !useManagedIdentity) return;
834
- return {
835
- type: "federated",
836
- appId,
837
- tenantId,
838
- certificatePath,
839
- certificateThumbprint,
840
- useManagedIdentity: useManagedIdentity || void 0,
841
- managedIdentityClientId
842
- };
843
- }
844
- const appPassword = (0, openclaw_plugin_sdk_secret_input.normalizeResolvedSecretInputString)({
845
- value: cfg?.appPassword,
846
- path: "channels.msteams.appPassword"
847
- }) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_APP_PASSWORD);
848
- if (!appPassword) return;
849
- return {
850
- type: "secret",
851
- appId,
852
- appPassword,
853
- tenantId
854
- };
855
- }
856
765
  async function resolveDelegatedAccessToken(params) {
857
- const tokens = await require_delegated_state.loadMSTeamsDelegatedTokens();
766
+ const tokens = await require_token_config.loadMSTeamsDelegatedTokens();
858
767
  if (!tokens) return;
859
768
  if ((0, openclaw_plugin_sdk_number_runtime.isFutureDateTimestampMs)(tokens.expiresAt)) return tokens.accessToken;
860
769
  try {
@@ -865,7 +774,7 @@ async function resolveDelegatedAccessToken(params) {
865
774
  refreshToken: tokens.refreshToken,
866
775
  scopes: tokens.scopes
867
776
  });
868
- await require_delegated_state.saveMSTeamsDelegatedTokens(refreshed);
777
+ await require_token_config.saveMSTeamsDelegatedTokens(refreshed);
869
778
  return refreshed.accessToken;
870
779
  } catch {
871
780
  return;
@@ -1019,7 +928,7 @@ async function resolveGraphToken(cfg, options) {
1019
928
  const assertRequestCurrent = captureGraphRequestCurrentness((0, openclaw_plugin_sdk_fetch_runtime.captureChannelReadAuthority)());
1020
929
  assertRequestCurrent?.();
1021
930
  const msteamsCfg = cfg?.channels?.msteams;
1022
- const creds = resolveMSTeamsCredentials(msteamsCfg);
931
+ const creds = require_token_config.resolveMSTeamsCredentials(msteamsCfg);
1023
932
  if (!creds) throw new Error("MS Teams credentials missing");
1024
933
  if (msteamsCfg?.cloud === "China") throw new Error("Microsoft Teams Graph operations are not supported for channels.msteams.cloud=China until Graph requests are routed through the Azure China Graph endpoint.");
1025
934
  if (options?.preferDelegated && msteamsCfg?.delegatedAuth?.enabled && creds.type === "secret") {
@@ -1164,9 +1073,6 @@ function wasMSTeamsBotMentioned(activity) {
1164
1073
  //#endregion
1165
1074
  //#region extensions/msteams/src/resolve-allowlist.ts
1166
1075
  const MSTEAMS_GROUP_CONVERSATION_ID = /^19:.+@thread\.(?:tacv2|skype|v2)$/i;
1167
- function normalizeExactMatch(value) {
1168
- return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(value ?? "");
1169
- }
1170
1076
  function uniqueItemsById(items) {
1171
1077
  const byId = /* @__PURE__ */ new Map();
1172
1078
  for (const item of items) {
@@ -1176,16 +1082,16 @@ function uniqueItemsById(items) {
1176
1082
  return [...byId.values()];
1177
1083
  }
1178
1084
  function findExactNames(items, query) {
1179
- const normalized = normalizeExactMatch(query);
1180
- return uniqueItemsById(items.filter((item) => normalizeExactMatch(item.displayName) === normalized));
1085
+ const normalized = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(query);
1086
+ return uniqueItemsById(items.filter((item) => (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(item.displayName) === normalized));
1181
1087
  }
1182
1088
  function findExactUsers(items, query) {
1183
- const normalized = normalizeExactMatch(query);
1089
+ const normalized = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(query);
1184
1090
  return uniqueItemsById(items.filter((item) => [
1185
1091
  item.displayName,
1186
1092
  item.mail,
1187
1093
  item.userPrincipalName
1188
- ].some((value) => normalizeExactMatch(value) === normalized)));
1094
+ ].some((value) => (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(value) === normalized)));
1189
1095
  }
1190
1096
  function isStableMSTeamsUserId(raw) {
1191
1097
  return /^[0-9a-fA-F-]{16,}$/.test(normalizeMSTeamsUserInput(raw));
@@ -1200,7 +1106,7 @@ function normalizeStaticMSTeamsAllowEntry(raw) {
1200
1106
  function projectStableMSTeamsUserAllowlist(entries) {
1201
1107
  if (!entries) return;
1202
1108
  const projected = entries.map((entry) => normalizeStaticMSTeamsAllowEntry(entry)).filter((entry) => Boolean(entry));
1203
- return [...new Map(projected.map((entry) => [normalizeExactMatch(entry), entry])).values()];
1109
+ return [...new Map(projected.map((entry) => [(0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(entry), entry])).values()];
1204
1110
  }
1205
1111
  function projectStableMSTeamsGroupAllowlist(entries) {
1206
1112
  if (!entries) return;
@@ -1210,7 +1116,7 @@ function projectStableMSTeamsGroupAllowlist(entries) {
1210
1116
  const conversationId = normalizeMSTeamsConversationId(normalizeMSTeamsUserInput(entry));
1211
1117
  return MSTEAMS_GROUP_CONVERSATION_ID.test(conversationId) ? conversationId : void 0;
1212
1118
  }).filter((entry) => Boolean(entry));
1213
- return [...new Map(projected.map((entry) => [MSTEAMS_GROUP_CONVERSATION_ID.test(entry) ? `conversation:${entry}` : normalizeExactMatch(entry), entry])).values()];
1119
+ return [...new Map(projected.map((entry) => [MSTEAMS_GROUP_CONVERSATION_ID.test(entry) ? `conversation:${entry}` : (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(entry), entry])).values()];
1214
1120
  }
1215
1121
  function stripProviderPrefix(raw) {
1216
1122
  return raw.replace(/^(msteams|teams):/i, "");
@@ -1250,13 +1156,7 @@ function parseMSTeamsConversationId(raw) {
1250
1156
  */
1251
1157
  function looksLikeMSTeamsConversationId(raw) {
1252
1158
  const trimmed = raw.trim();
1253
- if (!trimmed) return false;
1254
- if (/^conversation:/i.test(trimmed)) return true;
1255
- if (MSTEAMS_GROUP_CONVERSATION_ID.test(trimmed)) return true;
1256
- if (/^19:.+@unq\.gbl\.spaces$/i.test(trimmed)) return true;
1257
- if (/^a:1[A-Za-z0-9_-]+$/i.test(trimmed)) return true;
1258
- if (/^8:orgid:[A-Za-z0-9-]+$/i.test(trimmed)) return true;
1259
- return /@thread\b/i.test(trimmed);
1159
+ return /^conversation:/i.test(trimmed) || MSTEAMS_GROUP_CONVERSATION_ID.test(trimmed) || /^19:.+@unq\.gbl\.spaces$/i.test(trimmed) || /^a:1[A-Za-z0-9_-]+$/i.test(trimmed) || /^8:orgid:[A-Za-z0-9-]+$/i.test(trimmed) || /@thread\b/i.test(trimmed);
1260
1160
  }
1261
1161
  /**
1262
1162
  * Detect conversation ids plus stable user ids that explicit-target delivery
@@ -1761,12 +1661,6 @@ Object.defineProperty(exports, "fetchGraphJson", {
1761
1661
  return fetchGraphJson;
1762
1662
  }
1763
1663
  });
1764
- Object.defineProperty(exports, "hasConfiguredMSTeamsCredentials", {
1765
- enumerable: true,
1766
- get: function() {
1767
- return hasConfiguredMSTeamsCredentials;
1768
- }
1769
- });
1770
1664
  Object.defineProperty(exports, "htmlToPlainText", {
1771
1665
  enumerable: true,
1772
1666
  get: function() {
@@ -1929,12 +1823,6 @@ Object.defineProperty(exports, "resolveMSTeamsChannelAllowlist", {
1929
1823
  return resolveMSTeamsChannelAllowlist;
1930
1824
  }
1931
1825
  });
1932
- Object.defineProperty(exports, "resolveMSTeamsCredentials", {
1933
- enumerable: true,
1934
- get: function() {
1935
- return resolveMSTeamsCredentials;
1936
- }
1937
- });
1938
1826
  Object.defineProperty(exports, "resolveMSTeamsMediaKind", {
1939
1827
  enumerable: true,
1940
1828
  get: function() {
@@ -1977,12 +1865,6 @@ Object.defineProperty(exports, "resolveMSTeamsUserAllowlist", {
1977
1865
  return resolveMSTeamsUserAllowlist;
1978
1866
  }
1979
1867
  });
1980
- Object.defineProperty(exports, "resolveRequestUrl", {
1981
- enumerable: true,
1982
- get: function() {
1983
- return resolveRequestUrl;
1984
- }
1985
- });
1986
1868
  Object.defineProperty(exports, "runWithMSTeamsGraphRequestCurrentness", {
1987
1869
  enumerable: true,
1988
1870
  get: function() {
@@ -1,10 +1,11 @@
1
1
  const require_runtime = require("./runtime-gZTAuFux.cjs");
2
2
  require("../runtime-api.cjs");
3
- const require_resolve_allowlist = require("./resolve-allowlist-Pl_NQFYH.cjs");
3
+ const require_resolve_allowlist = require("./resolve-allowlist-Ct9yxQUw.cjs");
4
4
  const require_bot_framework_service_url = require("./bot-framework-service-url-BUhTe8F3.cjs");
5
- const require_channel = require("./channel-ByzS7QJ0.cjs");
6
- const require_channel_setup = require("./channel.setup-DL8lcWT_.cjs");
7
- const require_conversation_store_state = require("./conversation-store-state-B7JuyZTm.cjs");
5
+ const require_token_config = require("./token-config-DOt3XwVa.cjs");
6
+ const require_channel = require("./channel-BFhXodl2.cjs");
7
+ const require_channel_setup = require("./channel.setup-ss0TO-ap.cjs");
8
+ const require_conversation_store_state = require("./conversation-store-state-f7V8CVNy.cjs");
8
9
  let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
9
10
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
10
11
  let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
@@ -87,7 +88,7 @@ async function resolveMSTeamsSendContext(params) {
87
88
  const account = require_channel_setup.resolveMSTeamsAccount(params.cfg);
88
89
  if (account.tokenStatus === "configured_unavailable") throw new Error("msteams credential file is configured but unavailable");
89
90
  if (!account.configured) throw new Error("msteams credentials not configured");
90
- const creds = require_resolve_allowlist.resolveMSTeamsCredentials(msteamsCfg);
91
+ const creds = require_token_config.resolveMSTeamsCredentials(msteamsCfg);
91
92
  if (!creds) throw new Error("msteams credentials not configured");
92
93
  const store = require_conversation_store_state.createMSTeamsConversationStoreState();
93
94
  const recipient = parseRecipient(params.to);
@@ -146,7 +147,6 @@ async function resolveMSTeamsSendContext(params) {
146
147
  resolveChannelLimitMb: ({ cfg }) => cfg.channels?.msteams?.mediaMaxMb
147
148
  });
148
149
  return {
149
- appId: creds.appId,
150
150
  conversationId,
151
151
  ref: safeRef,
152
152
  app,
@@ -161,12 +161,6 @@ async function resolveMSTeamsSendContext(params) {
161
161
  }
162
162
  //#endregion
163
163
  //#region extensions/msteams/src/send.ts
164
- const FILE_CONSENT_THRESHOLD_BYTES = 4194304;
165
- /**
166
- * MSTeams-specific media size limit (100MB).
167
- * Higher than the default to support Teams file-consent and SharePoint uploads.
168
- */
169
- const MSTEAMS_MAX_MEDIA_BYTES = 104857600;
170
164
  function createMSTeamsSendError(errorPrefix, error) {
171
165
  if (error instanceof Error && (error instanceof openclaw_plugin_sdk_error_runtime.PlatformMessageNotDispatchedError || (0, openclaw_plugin_sdk_channel_inbound.isChannelPartialDeliveryError)(error))) return error;
172
166
  const classification = require_channel_setup.classifyMSTeamsSendError(error);
@@ -214,17 +208,7 @@ function createMSTeamsSendResult(params) {
214
208
  ...params.pendingUploadId ? { pendingUploadId: params.pendingUploadId } : {}
215
209
  };
216
210
  }
217
- /**
218
- * Send a message to a Teams conversation or user.
219
- *
220
- * Uses the stored ConversationReference from previous interactions.
221
- * The bot must have received at least one message from the conversation
222
- * before proactive messaging works.
223
- *
224
- * File handling by conversation type:
225
- * - Personal (1:1) chats: small images (<4MB) use base64, large files and non-images use FileConsentCard
226
- * - Group chats / channels: files require configured SharePoint storage
227
- */
211
+ /** Proactive delivery requires a conversation reference captured from an earlier inbound turn. */
228
212
  async function sendMessageMSTeams(params) {
229
213
  require_resolve_allowlist.assertMSTeamsSendHandoff(params);
230
214
  const { cfg, to, text, mediaUrl, filename, mediaAccess, mediaLocalRoots, mediaReadFile } = params;
@@ -245,14 +229,14 @@ async function sendMessageMSTeams(params) {
245
229
  hasMedia: Boolean(mediaUrl)
246
230
  });
247
231
  if (mediaUrl) {
248
- const mediaMaxBytes = ctx.mediaMaxBytes ?? MSTEAMS_MAX_MEDIA_BYTES;
232
+ const mediaMaxBytes = ctx.mediaMaxBytes ?? 104857600;
249
233
  const media = await (0, openclaw_plugin_sdk_outbound_media.loadOutboundMediaFromUrl)(mediaUrl, {
250
234
  maxBytes: mediaMaxBytes,
251
235
  mediaAccess,
252
236
  mediaLocalRoots,
253
237
  mediaReadFile
254
238
  });
255
- const isLargeFile = media.buffer.length >= FILE_CONSENT_THRESHOLD_BYTES;
239
+ const isLargeFile = media.buffer.length >= require_conversation_store_state.FILE_CONSENT_THRESHOLD_BYTES;
256
240
  const isImage = media.contentType?.startsWith("image/") ?? false;
257
241
  const fallbackFileName = await require_conversation_store_state.extractFilename(mediaUrl);
258
242
  const fileName = filename?.trim() || media.fileName || fallbackFileName;
@@ -267,8 +251,7 @@ async function sendMessageMSTeams(params) {
267
251
  if (require_conversation_store_state.requiresFileConsent({
268
252
  conversationType,
269
253
  contentType: media.contentType,
270
- bufferSize: media.buffer.length,
271
- thresholdBytes: FILE_CONSENT_THRESHOLD_BYTES
254
+ bufferSize: media.buffer.length
272
255
  })) {
273
256
  require_resolve_allowlist.assertMSTeamsSendHandoff(params);
274
257
  const { activity, uploadId } = await require_conversation_store_state.prepareFileConsentActivityFs({
@@ -377,7 +360,7 @@ async function sendMessageMSTeams(params) {
377
360
  return sendTextWithMedia(ctx, messageText, void 0, params);
378
361
  }
379
362
  async function sendTextWithMedia(ctx, text, mediaUrl, options) {
380
- const { app, appId, conversationId, ref, log, tokenProvider, sharePointSiteId, mediaMaxBytes, replyStyle } = ctx;
363
+ const { app, conversationId, ref, log, tokenProvider, sharePointSiteId, mediaMaxBytes, replyStyle } = ctx;
381
364
  const messages = text && mediaUrl ? [{ text }, { mediaUrl }] : [{
382
365
  text: text || void 0,
383
366
  mediaUrl
@@ -401,7 +384,6 @@ async function sendTextWithMedia(ctx, text, mediaUrl, options) {
401
384
  },
402
385
  replyStyle,
403
386
  app,
404
- appId,
405
387
  conversationRef: ref,
406
388
  messages,
407
389
  retry: {},
@@ -528,14 +510,8 @@ async function sendAdaptiveCardMSTeams(params) {
528
510
  await params.onDeliveryResult?.(result);
529
511
  });
530
512
  }
531
- /**
532
- * Edit (update) a previously sent message in a Teams conversation.
533
- *
534
- * Uses the Bot Framework REST API for proactive edits outside of the
535
- * original turn context.
536
- */
537
513
  async function editMessageMSTeams(params) {
538
- return updateMSTeamsMessageActivity({
514
+ return mutateMSTeamsMessageActivity({
539
515
  ...params,
540
516
  activity: {
541
517
  ...require_conversation_store_state.buildMSTeamsMessageActivity(require_conversation_store_state.formatMSTeamsMarkdown(params.text, (0, openclaw_plugin_sdk_markdown_table_runtime.resolveMarkdownTableMode)({
@@ -547,7 +523,7 @@ async function editMessageMSTeams(params) {
547
523
  });
548
524
  }
549
525
  async function editAdaptiveCardMSTeams(params) {
550
- return updateMSTeamsMessageActivity({
526
+ return mutateMSTeamsMessageActivity({
551
527
  ...params,
552
528
  activity: {
553
529
  ...require_conversation_store_state.buildMSTeamsAdaptiveCardActivity(params.card),
@@ -555,51 +531,29 @@ async function editAdaptiveCardMSTeams(params) {
555
531
  }
556
532
  });
557
533
  }
558
- async function updateMSTeamsMessageActivity(params) {
559
- const { cfg, to, activityId, activity } = params;
560
- const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({
561
- cfg,
562
- to
563
- });
564
- log.debug?.("editing proactive message", {
565
- conversationId,
566
- activityId
567
- });
568
- try {
569
- const baseRef = require_conversation_store_state.buildConversationReference(ref);
570
- await require_conversation_store_state.updateMSTeamsActivityWithReference(app, baseRef, activityId, activity, { serviceUrlBoundary: sdkCloudOptions });
571
- } catch (err) {
572
- throw createMSTeamsSendError("msteams edit", err);
573
- }
574
- log.info("edited proactive message", {
575
- conversationId,
576
- activityId
577
- });
578
- return { conversationId };
579
- }
580
- /**
581
- * Delete a previously sent message in a Teams conversation.
582
- *
583
- * Uses the Bot Framework REST API for proactive deletes outside of the
584
- * original turn context.
585
- */
586
534
  async function deleteMessageMSTeams(params) {
587
- const { cfg, to, activityId } = params;
535
+ return mutateMSTeamsMessageActivity(params);
536
+ }
537
+ async function mutateMSTeamsMessageActivity(params) {
538
+ const { cfg, to, activityId, activity } = params;
588
539
  const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({
589
540
  cfg,
590
541
  to
591
542
  });
592
- log.debug?.("deleting proactive message", {
543
+ const operation = activity ? "edit" : "delete";
544
+ log.debug?.(`${activity ? "editing" : "deleting"} proactive message`, {
593
545
  conversationId,
594
546
  activityId
595
547
  });
596
548
  try {
597
549
  const baseRef = require_conversation_store_state.buildConversationReference(ref);
598
- await require_conversation_store_state.deleteMSTeamsActivityWithReference(app, baseRef, activityId, { serviceUrlBoundary: sdkCloudOptions });
550
+ const options = { serviceUrlBoundary: sdkCloudOptions };
551
+ if (activity) await require_conversation_store_state.updateMSTeamsActivityWithReference(app, baseRef, activityId, activity, options);
552
+ else await require_conversation_store_state.deleteMSTeamsActivityWithReference(app, baseRef, activityId, options);
599
553
  } catch (err) {
600
- throw createMSTeamsSendError("msteams delete", err);
554
+ throw createMSTeamsSendError(`msteams ${operation}`, err);
601
555
  }
602
- log.info("deleted proactive message", {
556
+ log.info(`${activity ? "edited" : "deleted"} proactive message`, {
603
557
  conversationId,
604
558
  activityId
605
559
  });
@@ -1,3 +1,3 @@
1
- const require_channel_setup = require("./channel.setup-DL8lcWT_.cjs");
1
+ const require_channel_setup = require("./channel.setup-ss0TO-ap.cjs");
2
2
  require("../setup-plugin-api.cjs");
3
3
  exports.msteamsSetupPlugin = require_channel_setup.msteamsSetupPlugin;
@@ -1,4 +1,4 @@
1
- const require_resolve_allowlist = require("./resolve-allowlist-Pl_NQFYH.cjs");
1
+ const require_resolve_allowlist = require("./resolve-allowlist-Ct9yxQUw.cjs");
2
2
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
3
3
  let openclaw_plugin_sdk_approval_auth_runtime = require("openclaw/plugin-sdk/approval-auth-runtime");
4
4
  let openclaw_plugin_sdk_routing = require("openclaw/plugin-sdk/routing");
@@ -0,0 +1,139 @@
1
+ const require_runtime = require("./runtime-gZTAuFux.cjs");
2
+ let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
3
+ let openclaw_plugin_sdk_secret_input = require("openclaw/plugin-sdk/secret-input");
4
+ //#region extensions/msteams/src/delegated-state.ts
5
+ const MSTEAMS_DELEGATED_TOKEN_LEGACY_FILENAME = "msteams-delegated.json";
6
+ const MSTEAMS_DELEGATED_TOKEN_NAMESPACE = "delegated-token";
7
+ const MSTEAMS_DELEGATED_TOKEN_KEY = "current";
8
+ function openDelegatedTokenStore(env) {
9
+ return require_runtime.getMSTeamsRuntime().state.openKeyedStore({
10
+ namespace: MSTEAMS_DELEGATED_TOKEN_NAMESPACE,
11
+ maxEntries: 1,
12
+ overflowPolicy: "reject-new",
13
+ ...env ? { env } : {}
14
+ });
15
+ }
16
+ function normalizeMSTeamsDelegatedTokens(value) {
17
+ if (!value || typeof value !== "object") return null;
18
+ const token = value;
19
+ if (typeof token.accessToken !== "string" || !token.accessToken || typeof token.refreshToken !== "string" || !token.refreshToken || typeof token.expiresAt !== "number" || !Number.isFinite(token.expiresAt) || !Array.isArray(token.scopes) || !token.scopes.every((scope) => typeof scope === "string" && scope.length > 0)) return null;
20
+ return {
21
+ accessToken: token.accessToken,
22
+ refreshToken: token.refreshToken,
23
+ expiresAt: token.expiresAt,
24
+ scopes: [...token.scopes],
25
+ ...typeof token.userPrincipalName === "string" ? { userPrincipalName: token.userPrincipalName } : {}
26
+ };
27
+ }
28
+ async function loadMSTeamsDelegatedTokens(env) {
29
+ return normalizeMSTeamsDelegatedTokens(await openDelegatedTokenStore(env).lookup("current")) ?? void 0;
30
+ }
31
+ async function saveMSTeamsDelegatedTokens(tokens, env) {
32
+ const normalized = normalizeMSTeamsDelegatedTokens(tokens);
33
+ if (!normalized) throw new Error("Invalid Microsoft Teams delegated token payload");
34
+ await openDelegatedTokenStore(env).register(MSTEAMS_DELEGATED_TOKEN_KEY, normalized);
35
+ }
36
+ //#endregion
37
+ //#region extensions/msteams/src/token-config.ts
38
+ function resolveAuthType(cfg) {
39
+ const fromCfg = cfg?.authType;
40
+ if (fromCfg === "secret" || fromCfg === "federated") return fromCfg;
41
+ if (process.env.MSTEAMS_AUTH_TYPE === "federated") return "federated";
42
+ return "secret";
43
+ }
44
+ function resolveFederatedPath(configValue, envValue) {
45
+ return (0, openclaw_plugin_sdk_string_coerce_runtime.readNonBlankString)(configValue) ?? (0, openclaw_plugin_sdk_string_coerce_runtime.readNonBlankString)(envValue);
46
+ }
47
+ function hasConfiguredMSTeamsCredentials(cfg) {
48
+ const authType = resolveAuthType(cfg);
49
+ const hasAppId = Boolean((0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.appId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_APP_ID));
50
+ const hasTenantId = Boolean((0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.tenantId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_TENANT_ID));
51
+ if (authType === "federated") {
52
+ const hasCert = Boolean(resolveFederatedPath(cfg?.certificatePath, process.env.MSTEAMS_CERTIFICATE_PATH));
53
+ const hasManagedIdentity = cfg?.useManagedIdentity ?? process.env.MSTEAMS_USE_MANAGED_IDENTITY === "true";
54
+ return hasAppId && hasTenantId && (hasCert || hasManagedIdentity);
55
+ }
56
+ return Boolean((0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.appId) && (0, openclaw_plugin_sdk_secret_input.hasConfiguredSecretInput)(cfg?.appPassword) && (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.tenantId));
57
+ }
58
+ function resolveMSTeamsCredentials(cfg) {
59
+ const authType = resolveAuthType(cfg);
60
+ const appId = (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.appId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_APP_ID);
61
+ const tenantId = (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.tenantId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_TENANT_ID);
62
+ if (!appId || !tenantId) return;
63
+ if (authType === "federated") {
64
+ const certificatePath = resolveFederatedPath(cfg?.certificatePath, process.env.MSTEAMS_CERTIFICATE_PATH);
65
+ const certificateThumbprint = cfg?.certificateThumbprint || process.env.MSTEAMS_CERTIFICATE_THUMBPRINT || void 0;
66
+ const useManagedIdentity = cfg?.useManagedIdentity ?? process.env.MSTEAMS_USE_MANAGED_IDENTITY === "true";
67
+ const managedIdentityClientId = cfg?.managedIdentityClientId || process.env.MSTEAMS_MANAGED_IDENTITY_CLIENT_ID || void 0;
68
+ if (!certificatePath && !useManagedIdentity) return;
69
+ return {
70
+ type: "federated",
71
+ appId,
72
+ tenantId,
73
+ certificatePath,
74
+ certificateThumbprint,
75
+ useManagedIdentity: useManagedIdentity || void 0,
76
+ managedIdentityClientId
77
+ };
78
+ }
79
+ const appPassword = (0, openclaw_plugin_sdk_secret_input.normalizeResolvedSecretInputString)({
80
+ value: cfg?.appPassword,
81
+ path: "channels.msteams.appPassword"
82
+ }) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_APP_PASSWORD);
83
+ if (!appPassword) return;
84
+ return {
85
+ type: "secret",
86
+ appId,
87
+ appPassword,
88
+ tenantId
89
+ };
90
+ }
91
+ //#endregion
92
+ Object.defineProperty(exports, "MSTEAMS_DELEGATED_TOKEN_KEY", {
93
+ enumerable: true,
94
+ get: function() {
95
+ return MSTEAMS_DELEGATED_TOKEN_KEY;
96
+ }
97
+ });
98
+ Object.defineProperty(exports, "MSTEAMS_DELEGATED_TOKEN_LEGACY_FILENAME", {
99
+ enumerable: true,
100
+ get: function() {
101
+ return MSTEAMS_DELEGATED_TOKEN_LEGACY_FILENAME;
102
+ }
103
+ });
104
+ Object.defineProperty(exports, "MSTEAMS_DELEGATED_TOKEN_NAMESPACE", {
105
+ enumerable: true,
106
+ get: function() {
107
+ return MSTEAMS_DELEGATED_TOKEN_NAMESPACE;
108
+ }
109
+ });
110
+ Object.defineProperty(exports, "hasConfiguredMSTeamsCredentials", {
111
+ enumerable: true,
112
+ get: function() {
113
+ return hasConfiguredMSTeamsCredentials;
114
+ }
115
+ });
116
+ Object.defineProperty(exports, "loadMSTeamsDelegatedTokens", {
117
+ enumerable: true,
118
+ get: function() {
119
+ return loadMSTeamsDelegatedTokens;
120
+ }
121
+ });
122
+ Object.defineProperty(exports, "normalizeMSTeamsDelegatedTokens", {
123
+ enumerable: true,
124
+ get: function() {
125
+ return normalizeMSTeamsDelegatedTokens;
126
+ }
127
+ });
128
+ Object.defineProperty(exports, "resolveMSTeamsCredentials", {
129
+ enumerable: true,
130
+ get: function() {
131
+ return resolveMSTeamsCredentials;
132
+ }
133
+ });
134
+ Object.defineProperty(exports, "saveMSTeamsDelegatedTokens", {
135
+ enumerable: true,
136
+ get: function() {
137
+ return saveMSTeamsDelegatedTokens;
138
+ }
139
+ });
package/dist/api.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_channel = require("./.setup/channel-ByzS7QJ0.cjs");
3
- const require_channel_setup = require("./.setup/channel.setup-DL8lcWT_.cjs");
2
+ const require_channel = require("./.setup/channel-BFhXodl2.cjs");
3
+ const require_channel_setup = require("./.setup/channel.setup-ss0TO-ap.cjs");
4
4
  exports.createMSTeamsSetupWizardBase = require_channel_setup.createMSTeamsSetupWizardBase;
5
5
  exports.msteamsPlugin = require_channel.msteamsPlugin;
6
6
  exports.msteamsSetupAdapter = require_channel_setup.msteamsSetupAdapter;
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_channel = require("./.setup/channel-ByzS7QJ0.cjs");
2
+ const require_channel = require("./.setup/channel-BFhXodl2.cjs");
3
3
  exports.msteamsPlugin = require_channel.msteamsPlugin;