@openclaw/msteams 2026.9.4 → 2026.9.6
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/assets/activity.svg +40 -0
- package/assets/icon.png +0 -0
- package/dist/{adapter.runtime-BzR3RK2J.cjs → .setup/adapter.runtime-CQWZeqB5.cjs} +5 -3
- package/dist/{approval-handler.runtime-DRhFNeJS.cjs → .setup/approval-handler.runtime-CUnanUdR.cjs} +3 -3
- package/dist/{channel-B9LIyYeu.cjs → .setup/channel-BDp16XRR.cjs} +128 -89
- package/dist/{channel.runtime-BergqMHg.cjs → .setup/channel.runtime-Cv5F8JCa.cjs} +61 -34
- package/dist/{channel.setup-BhxokviI.cjs → .setup/channel.setup-BVDfgdCc.cjs} +3 -3
- package/dist/{delegated-state-DiEz9JIa.cjs → .setup/delegated-state-u-ywZyZT.cjs} +5 -5
- package/dist/{messenger-TLdZf9Ar.cjs → .setup/messenger-8RA1FUJa.cjs} +112 -188
- package/dist/{oauth-DUtLTz2u.cjs → .setup/oauth-C6m7dvHj.cjs} +1 -1
- package/dist/{polls-BBdZPx_R.cjs → .setup/polls-BJ4-4uZm.cjs} +14 -7
- package/dist/{reaction-types-BbBBdnQ5.cjs → .setup/reaction-types-C7RA7Wxt.cjs} +1 -1
- package/dist/{resolve-allowlist-DmUTQxEz.cjs → .setup/resolve-allowlist-CHzaaWiC.cjs} +135 -93
- package/dist/.setup/secret-contract-api-ChQdBeU1.cjs +4 -0
- package/dist/.setup/secret-contract-api-ipiUsANg.cjs +28 -0
- package/dist/{send-CU61PSDN.cjs → .setup/send-CYN_N7O1.cjs} +99 -34
- package/dist/.setup/setup-plugin-api-DpiaA8z1.cjs +3 -0
- package/dist/{src-D7Do7sM5.cjs → .setup/src-BfOCwlHp.cjs} +150 -125
- package/dist/{sso-token-store-DTeYxubp.cjs → .setup/sso-token-store-YYLHXgFH.cjs} +1 -1
- package/dist/{thread-session-NmA7_njI.cjs → .setup/thread-session-CXgHK-yi.cjs} +1 -1
- package/dist/api.cjs +2 -2
- package/dist/channel-config-api.cjs +1 -1
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/configured-state.cjs +1 -1
- package/dist/directory-contract-api.cjs +1 -1
- package/dist/doctor-contract-api.cjs +64 -62
- package/dist/qa-runner-api.cjs +1 -1
- package/dist/runtime-api.cjs +1 -1
- package/dist/secret-contract-api.cjs +4 -13
- package/dist/setup-entry.cjs +5 -3
- package/dist/setup-plugin-api.cjs +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +14 -11
- /package/dist/{approval-card-CPNH_q3P.cjs → .setup/approval-card-CPNH_q3P.cjs} +0 -0
- /package/dist/{config-schema-D22Lr1Qk.cjs → .setup/config-schema-D22Lr1Qk.cjs} +0 -0
- /package/dist/{rolldown-runtime-VH7oDXx4.cjs → .setup/rolldown-runtime-VH7oDXx4.cjs} +0 -0
- /package/dist/{runtime-gZTAuFux.cjs → .setup/runtime-gZTAuFux.cjs} +0 -0
- /package/dist/{secret-input-C65t6kjM.cjs → .setup/secret-input-C65t6kjM.cjs} +0 -0
|
@@ -4,7 +4,7 @@ const MSTEAMS_DELEGATED_TOKEN_LEGACY_FILENAME = "msteams-delegated.json";
|
|
|
4
4
|
const MSTEAMS_DELEGATED_TOKEN_NAMESPACE = "delegated-token";
|
|
5
5
|
const MSTEAMS_DELEGATED_TOKEN_KEY = "current";
|
|
6
6
|
function openDelegatedTokenStore(env) {
|
|
7
|
-
return require_runtime.getMSTeamsRuntime().state.
|
|
7
|
+
return require_runtime.getMSTeamsRuntime().state.openKeyedStore({
|
|
8
8
|
namespace: MSTEAMS_DELEGATED_TOKEN_NAMESPACE,
|
|
9
9
|
maxEntries: 1,
|
|
10
10
|
overflowPolicy: "reject-new",
|
|
@@ -23,13 +23,13 @@ function normalizeMSTeamsDelegatedTokens(value) {
|
|
|
23
23
|
...typeof token.userPrincipalName === "string" ? { userPrincipalName: token.userPrincipalName } : {}
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
function loadMSTeamsDelegatedTokens(env) {
|
|
27
|
-
return normalizeMSTeamsDelegatedTokens(openDelegatedTokenStore(env).lookup("current")) ?? void 0;
|
|
26
|
+
async function loadMSTeamsDelegatedTokens(env) {
|
|
27
|
+
return normalizeMSTeamsDelegatedTokens(await openDelegatedTokenStore(env).lookup("current")) ?? void 0;
|
|
28
28
|
}
|
|
29
|
-
function saveMSTeamsDelegatedTokens(tokens, env) {
|
|
29
|
+
async function saveMSTeamsDelegatedTokens(tokens, env) {
|
|
30
30
|
const normalized = normalizeMSTeamsDelegatedTokens(tokens);
|
|
31
31
|
if (!normalized) throw new Error("Invalid Microsoft Teams delegated token payload");
|
|
32
|
-
openDelegatedTokenStore(env).register(MSTEAMS_DELEGATED_TOKEN_KEY, normalized);
|
|
32
|
+
await openDelegatedTokenStore(env).register(MSTEAMS_DELEGATED_TOKEN_KEY, normalized);
|
|
33
33
|
}
|
|
34
34
|
//#endregion
|
|
35
35
|
Object.defineProperty(exports, "MSTEAMS_DELEGATED_TOKEN_KEY", {
|
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
|
|
2
2
|
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
3
|
-
require("
|
|
4
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
5
|
-
const require_channel_setup = require("./channel.setup-
|
|
6
|
-
const require_polls = require("./polls-
|
|
3
|
+
require("../runtime-api.cjs");
|
|
4
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CHzaaWiC.cjs");
|
|
5
|
+
const require_channel_setup = require("./channel.setup-BVDfgdCc.cjs");
|
|
6
|
+
const require_polls = require("./polls-BJ4-4uZm.cjs");
|
|
7
7
|
let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
|
|
8
8
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
9
|
+
let openclaw_plugin_sdk_fetch_runtime = require("openclaw/plugin-sdk/fetch-runtime");
|
|
9
10
|
let openclaw_plugin_sdk_provider_http = require("openclaw/plugin-sdk/provider-http");
|
|
10
11
|
let openclaw_plugin_sdk_reply_payload = require("openclaw/plugin-sdk/reply-payload");
|
|
12
|
+
let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime");
|
|
11
13
|
let openclaw_plugin_sdk_text_chunking = require("openclaw/plugin-sdk/text-chunking");
|
|
12
14
|
let node_dns_promises = require("node:dns/promises");
|
|
13
15
|
let openclaw_plugin_sdk_ssrf_policy = require("openclaw/plugin-sdk/ssrf-policy");
|
|
14
16
|
let openclaw_plugin_sdk_text_utility_runtime = require("openclaw/plugin-sdk/text-utility-runtime");
|
|
17
|
+
let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
|
|
15
18
|
let openclaw_plugin_sdk_retry_runtime = require("openclaw/plugin-sdk/retry-runtime");
|
|
16
19
|
let node_crypto = require("node:crypto");
|
|
17
20
|
node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
|
|
18
21
|
let node_path = require("node:path");
|
|
19
22
|
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
20
23
|
let openclaw_plugin_sdk_runtime_env = require("openclaw/plugin-sdk/runtime-env");
|
|
24
|
+
let openclaw_plugin_sdk_markdown_table_runtime = require("openclaw/plugin-sdk/markdown-table-runtime");
|
|
21
25
|
let openclaw_plugin_sdk_blob_runtime = require("openclaw/plugin-sdk/blob-runtime");
|
|
22
26
|
let openclaw_plugin_sdk_global_singleton = require("openclaw/plugin-sdk/global-singleton");
|
|
23
|
-
let
|
|
27
|
+
let openclaw_plugin_sdk_expect_runtime = require("openclaw/plugin-sdk/expect-runtime");
|
|
24
28
|
let openclaw_plugin_sdk_reply_chunking = require("openclaw/plugin-sdk/reply-chunking");
|
|
25
29
|
let openclaw_plugin_sdk_web_media = require("openclaw/plugin-sdk/web-media");
|
|
26
30
|
let openclaw_plugin_sdk_media_runtime = require("openclaw/plugin-sdk/media-runtime");
|
|
@@ -475,18 +479,16 @@ function prepareFileConsentActivity(params) {
|
|
|
475
479
|
*/
|
|
476
480
|
async function prepareFileConsentActivityFs(params) {
|
|
477
481
|
const { media, conversationId, description } = params;
|
|
478
|
-
const
|
|
482
|
+
const upload = {
|
|
479
483
|
buffer: media.buffer,
|
|
480
484
|
filename: media.filename,
|
|
481
485
|
contentType: media.contentType,
|
|
482
486
|
conversationId
|
|
483
|
-
}
|
|
487
|
+
};
|
|
488
|
+
const uploadId = storePendingUpload(upload);
|
|
484
489
|
await storePendingUploadFs({
|
|
485
490
|
id: uploadId,
|
|
486
|
-
|
|
487
|
-
filename: media.filename,
|
|
488
|
-
contentType: media.contentType,
|
|
489
|
-
conversationId
|
|
491
|
+
...upload
|
|
490
492
|
});
|
|
491
493
|
return {
|
|
492
494
|
activity: buildConsentActivity({
|
|
@@ -497,10 +499,6 @@ async function prepareFileConsentActivityFs(params) {
|
|
|
497
499
|
uploadId
|
|
498
500
|
};
|
|
499
501
|
}
|
|
500
|
-
/**
|
|
501
|
-
* Check if a file requires FileConsentCard flow.
|
|
502
|
-
* True for: personal chat AND (large file OR non-image)
|
|
503
|
-
*/
|
|
504
502
|
function requiresFileConsent(params) {
|
|
505
503
|
const isPersonal = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(params.conversationType) === "personal";
|
|
506
504
|
const isImage = params.contentType?.startsWith("image/") ?? false;
|
|
@@ -635,6 +633,7 @@ function serializeMarkdownDestination(href) {
|
|
|
635
633
|
return `<${href.replace(/([\\<>])/gu, "\\$1")}>`;
|
|
636
634
|
}
|
|
637
635
|
function blankBlockEnd(text, index) {
|
|
636
|
+
if (text[index] !== "\n" && text[index] !== "\r") return;
|
|
638
637
|
const match = /^(?:\r?\n)[ \t]*(?:\r?\n)/u.exec(text.slice(index));
|
|
639
638
|
return match ? index + match[0].length : void 0;
|
|
640
639
|
}
|
|
@@ -692,136 +691,25 @@ function protectDelimitedMarkdown(text, opener, tokenPrefix, values) {
|
|
|
692
691
|
}
|
|
693
692
|
return protectedText + text.slice(cursor);
|
|
694
693
|
}
|
|
695
|
-
function
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
cursor += 1;
|
|
703
|
-
spaces += 1;
|
|
704
|
-
}
|
|
705
|
-
if (line[cursor] !== ">") {
|
|
706
|
-
cursor = checkpoint;
|
|
707
|
-
break;
|
|
708
|
-
}
|
|
709
|
-
cursor += 1;
|
|
710
|
-
depth += 1;
|
|
711
|
-
if (line[cursor] === " " || line[cursor] === " ") cursor += 1;
|
|
712
|
-
}
|
|
713
|
-
return {
|
|
714
|
-
content: line.slice(cursor).replace(/\r$/u, ""),
|
|
715
|
-
depth,
|
|
716
|
-
prefix: line.slice(0, cursor)
|
|
717
|
-
};
|
|
718
|
-
}
|
|
719
|
-
function isTableDelimiterLine(content) {
|
|
720
|
-
const cells = content.trim().replace(/^\|/u, "").replace(/\|$/u, "").split("|").map((cell) => cell.trim());
|
|
721
|
-
return cells.length > 0 && cells.every((cell) => /^:?-+:?$/u.test(cell));
|
|
722
|
-
}
|
|
723
|
-
function protectRawTablesInSegment(text, tokenPrefix, rawTables) {
|
|
724
|
-
const lines = text.split("\n");
|
|
725
|
-
const output = [];
|
|
726
|
-
for (let index = 0; index < lines.length;) {
|
|
727
|
-
const line = lines[index] ?? "";
|
|
728
|
-
const header = parseQuotePrefix(line);
|
|
729
|
-
const delimiter = parseQuotePrefix(lines[index + 1] ?? "");
|
|
730
|
-
if (header.content.includes("|") && delimiter.depth === header.depth && isTableDelimiterLine(delimiter.content)) {
|
|
731
|
-
let end = index + 2;
|
|
732
|
-
while (end < lines.length) {
|
|
733
|
-
const row = parseQuotePrefix(lines[end] ?? "");
|
|
734
|
-
if (row.depth !== header.depth || !row.content.trim() || isInterruptingBlock(lines[end] ?? "")) break;
|
|
735
|
-
end += 1;
|
|
736
|
-
}
|
|
737
|
-
const table = lines.slice(index, end).join("\n");
|
|
738
|
-
if ((0, openclaw_plugin_sdk_text_chunking.convertMarkdownTables)(table, "code") !== table) {
|
|
739
|
-
const tableIndex = rawTables.push(table.slice(header.prefix.length)) - 1;
|
|
740
|
-
output.push(`${header.prefix}${tokenPrefix}t${tableIndex}${TOKEN_END}`);
|
|
741
|
-
index = end;
|
|
742
|
-
continue;
|
|
743
|
-
}
|
|
744
|
-
for (let lineIndex = index; lineIndex < end; lineIndex += 1) output.push(lines[lineIndex] ?? "");
|
|
745
|
-
index = end;
|
|
746
|
-
continue;
|
|
747
|
-
}
|
|
748
|
-
output.push(line);
|
|
749
|
-
index += 1;
|
|
750
|
-
}
|
|
751
|
-
return output.join("\n");
|
|
752
|
-
}
|
|
753
|
-
function isInterruptingBlock(line) {
|
|
754
|
-
const content = parseQuotePrefix(line).content;
|
|
755
|
-
return /^[ \t]{0,3}(?:#{1,6}(?:[ \t]|$)|`{3,}|~{3,}|(?:[-+*]|\d+[.)])[ \t]+)/u.test(content);
|
|
756
|
-
}
|
|
757
|
-
function leadingQuoteDepth(line) {
|
|
758
|
-
return parseQuotePrefix(line).depth;
|
|
759
|
-
}
|
|
760
|
-
function parseFenceLine(line) {
|
|
761
|
-
const match = /^((?: {0,3}>[ \t]?)*)(?:((?:[-+*]|\d+[.)])[ \t]+))?( {0,3})(`{3,}|~{3,})(.*)$/u.exec(line);
|
|
762
|
-
const marker = match?.[4];
|
|
763
|
-
const trailing = match?.[5] ?? "";
|
|
764
|
-
if (!marker || marker.startsWith("`") && trailing.includes("`")) return;
|
|
765
|
-
return {
|
|
766
|
-
marker,
|
|
767
|
-
quoteDepth: match?.[1]?.match(/>/gu)?.length ?? 0,
|
|
768
|
-
trailing,
|
|
769
|
-
listIndent: match?.[2]?.length ?? 0,
|
|
770
|
-
indent: match?.[3]?.length ?? 0
|
|
771
|
-
};
|
|
772
|
-
}
|
|
773
|
-
function protectRawTablesOutsideFences(text, tokenPrefix, rawTables) {
|
|
694
|
+
function protectRawTables(text, tokenPrefix, rawTables) {
|
|
695
|
+
if (!text.includes("|")) return text;
|
|
696
|
+
const { tables } = (0, openclaw_plugin_sdk_text_chunking.markdownToIRWithMeta)(text, {
|
|
697
|
+
autolink: false,
|
|
698
|
+
linkify: false,
|
|
699
|
+
tableMode: "block"
|
|
700
|
+
});
|
|
774
701
|
let result = "";
|
|
775
|
-
let
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
let fence = parseFenceLine(line);
|
|
785
|
-
const lineQuoteDepth = leadingQuoteDepth(line);
|
|
786
|
-
const lineWithoutQuotes = line.replace(/^(?:[ \t]*>[ \t]?)+/u, "");
|
|
787
|
-
const lineIndent = /^[ \t]*/u.exec(lineWithoutQuotes)?.[0].length ?? 0;
|
|
788
|
-
const listMarkerIndent = /^((?:[-+*]|\d+[.)])[ \t]+)/u.exec(lineWithoutQuotes)?.[1]?.length;
|
|
789
|
-
if (listMarkerIndent) listContextIndent = listMarkerIndent;
|
|
790
|
-
else if (line.trim() && lineIndent < listContextIndent && !fence) listContextIndent = 0;
|
|
791
|
-
if (fence && fence.listIndent === 0 && listContextIndent > 0 && fence.indent >= listContextIndent) fence = {
|
|
792
|
-
...fence,
|
|
793
|
-
listIndent: listContextIndent
|
|
794
|
-
};
|
|
795
|
-
const listOutdented = Boolean(active?.listIndent && line.trim() && lineIndent < active.listIndent && !fence);
|
|
796
|
-
if (active && (active.quoteDepth > lineQuoteDepth || listOutdented)) {
|
|
797
|
-
result += text.slice(fenceStart, offset);
|
|
798
|
-
outsideStart = offset;
|
|
799
|
-
active = void 0;
|
|
800
|
-
fenceStart = void 0;
|
|
801
|
-
}
|
|
802
|
-
if (!active && fence) {
|
|
803
|
-
result += protectRawTablesInSegment(text.slice(outsideStart, offset), tokenPrefix, rawTables);
|
|
804
|
-
fenceStart = offset;
|
|
805
|
-
active = {
|
|
806
|
-
marker: fence.marker,
|
|
807
|
-
quoteDepth: fence.quoteDepth,
|
|
808
|
-
listIndent: fence.listIndent
|
|
809
|
-
};
|
|
810
|
-
} else if (active && fence && fence.marker[0] === active.marker[0] && fence.marker.length >= active.marker.length && fence.quoteDepth === active.quoteDepth && /^[ \t]*$/u.test(fence.trailing)) {
|
|
811
|
-
const fenceEnd = nextNewline < 0 ? lineEnd : nextNewline + 1;
|
|
812
|
-
result += text.slice(fenceStart, fenceEnd);
|
|
813
|
-
outsideStart = fenceEnd;
|
|
814
|
-
active = void 0;
|
|
815
|
-
fenceStart = void 0;
|
|
816
|
-
}
|
|
817
|
-
if (nextNewline < 0) break;
|
|
818
|
-
offset = nextNewline + 1;
|
|
819
|
-
}
|
|
820
|
-
if (active && fenceStart !== void 0) {
|
|
821
|
-
result += text.slice(fenceStart);
|
|
822
|
-
return result;
|
|
702
|
+
let cursor = 0;
|
|
703
|
+
for (const table of tables) {
|
|
704
|
+
const source = (0, openclaw_plugin_sdk_expect_runtime.expectDefined)((0, openclaw_plugin_sdk_markdown_table_runtime.getMarkdownTableSource)(table), "Markdown table source");
|
|
705
|
+
const lineStart = Math.max(text.lastIndexOf("\n", source.start - 1), text.lastIndexOf("\r", source.start - 1)) + 1;
|
|
706
|
+
const start = lineStart + (/^(?: {0,3}>[ \t]?)*/u.exec(text.slice(lineStart, source.start))?.[0] ?? "").length;
|
|
707
|
+
const end = source.end + (text.slice(source.end, source.end + 2) === "\r\n" ? 1 : 0);
|
|
708
|
+
const index = rawTables.push(text.slice(start, end)) - 1;
|
|
709
|
+
result += text.slice(cursor, start) + `${tokenPrefix}t${index}${TOKEN_END}`;
|
|
710
|
+
cursor = end;
|
|
823
711
|
}
|
|
824
|
-
return result +
|
|
712
|
+
return result + text.slice(cursor);
|
|
825
713
|
}
|
|
826
714
|
function protectMSTeamsCode(ir, tokenPrefix, code, protectedValues) {
|
|
827
715
|
const codeSpans = ir.styles.filter((span) => span.style === "code" || span.style === "code_block");
|
|
@@ -877,7 +765,7 @@ function formatMSTeamsMarkdown(markdown, tableMode) {
|
|
|
877
765
|
return `${tokenPrefix}h${index}${TOKEN_END}`;
|
|
878
766
|
}), "![", `${tokenPrefix}i`, images), "@[", `${tokenPrefix}m`, mentions);
|
|
879
767
|
const tableInput = (0, openclaw_plugin_sdk_text_chunking.convertMarkdownTables)(mentionsProtected, tableMode);
|
|
880
|
-
const protectedMarkdown = (tableMode === "off" ?
|
|
768
|
+
const protectedMarkdown = (tableMode === "off" ? protectRawTables(tableInput, tokenPrefix, rawTables) : tableInput).replace(ESCAPED_MARKDOWN_RE, (escaped) => {
|
|
881
769
|
const index = escapedMarkdown.push(escaped) - 1;
|
|
882
770
|
return `${tokenPrefix}e${index}${TOKEN_END}`;
|
|
883
771
|
});
|
|
@@ -957,6 +845,19 @@ function buildTeamsFileInfoCard(file) {
|
|
|
957
845
|
const GRAPH_ROOT = "https://graph.microsoft.com/v1.0";
|
|
958
846
|
const GRAPH_BETA = "https://graph.microsoft.com/beta";
|
|
959
847
|
const GRAPH_SCOPE = "https://graph.microsoft.com";
|
|
848
|
+
async function requestSharePoint(url, init, params) {
|
|
849
|
+
const { response, release } = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
|
|
850
|
+
url,
|
|
851
|
+
init,
|
|
852
|
+
fetchImpl: params.fetchFn,
|
|
853
|
+
mode: "trusted_env_proxy",
|
|
854
|
+
beforeRequest: () => require_resolve_allowlist.assertMSTeamsSendHandoff(params),
|
|
855
|
+
maxRedirects: 20,
|
|
856
|
+
allowCrossOriginUnsafeRedirectReplay: true,
|
|
857
|
+
auditContext: "msteams.graph-upload"
|
|
858
|
+
});
|
|
859
|
+
return (0, openclaw_plugin_sdk_fetch_runtime.responseWithRelease)(response, release);
|
|
860
|
+
}
|
|
960
861
|
function requireMSTeamsSharePointSiteId(siteId) {
|
|
961
862
|
const normalized = siteId?.trim();
|
|
962
863
|
if (!normalized) throw new Error("channels.msteams.sharePointSiteId is required to send files to group chats or channels");
|
|
@@ -978,7 +879,6 @@ async function getGraphAccessToken(tokenProvider) {
|
|
|
978
879
|
* @param params.siteId - SharePoint site ID (e.g., "contoso.sharepoint.com,guid1,guid2")
|
|
979
880
|
*/
|
|
980
881
|
async function uploadToSharePoint(params) {
|
|
981
|
-
const fetchFn = params.fetchFn ?? fetch;
|
|
982
882
|
const uploadPath = `/OpenClawShared/${encodeURIComponent(params.filename)}`;
|
|
983
883
|
const uploadUrl = `${GRAPH_ROOT}/sites/${params.siteId}/drive/root:${uploadPath}:/content?@microsoft.graph.conflictBehavior=rename`;
|
|
984
884
|
const timeoutMs = require_resolve_allowlist.resolveMSTeamsSharePointUploadTimeoutMs(params.buffer.length);
|
|
@@ -986,8 +886,10 @@ async function uploadToSharePoint(params) {
|
|
|
986
886
|
label: SHAREPOINT_UPLOAD_TIMEOUT_LABEL,
|
|
987
887
|
timeoutMs,
|
|
988
888
|
work: async (signal) => {
|
|
889
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
989
890
|
const token = await getGraphAccessToken(params.tokenProvider);
|
|
990
|
-
|
|
891
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
892
|
+
const res = await requestSharePoint(uploadUrl, {
|
|
991
893
|
method: "PUT",
|
|
992
894
|
headers: {
|
|
993
895
|
"User-Agent": require_resolve_allowlist.buildUserAgent(),
|
|
@@ -996,7 +898,7 @@ async function uploadToSharePoint(params) {
|
|
|
996
898
|
},
|
|
997
899
|
body: new Blob([(0, openclaw_plugin_sdk_blob_runtime.bufferToBlobPart)(params.buffer)]),
|
|
998
900
|
signal
|
|
999
|
-
});
|
|
901
|
+
}, params);
|
|
1000
902
|
if (!res.ok) throw await require_resolve_allowlist.createMSTeamsHttpError(res, "SharePoint upload failed");
|
|
1001
903
|
return await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, "msteams.graph-upload.uploadSharePointFile", { chunkTimeoutMs: timeoutMs });
|
|
1002
904
|
}
|
|
@@ -1016,18 +918,19 @@ async function uploadToSharePoint(params) {
|
|
|
1016
918
|
* @param params.itemId - The driveItem ID (returned from upload)
|
|
1017
919
|
*/
|
|
1018
920
|
async function getDriveItemProperties(params) {
|
|
1019
|
-
const fetchFn = params.fetchFn ?? fetch;
|
|
1020
921
|
const data = await require_resolve_allowlist.withMSTeamsAbortableRequestTimeout({
|
|
1021
922
|
label: SHAREPOINT_REQUEST_TIMEOUT_LABEL,
|
|
1022
923
|
work: async (signal) => {
|
|
924
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
1023
925
|
const token = await getGraphAccessToken(params.tokenProvider);
|
|
1024
|
-
|
|
926
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
927
|
+
const res = await requestSharePoint(`${GRAPH_ROOT}/sites/${params.siteId}/drive/items/${params.itemId}?$select=eTag,webDavUrl,name`, {
|
|
1025
928
|
headers: {
|
|
1026
929
|
"User-Agent": require_resolve_allowlist.buildUserAgent(),
|
|
1027
930
|
Authorization: `Bearer ${token}`
|
|
1028
931
|
},
|
|
1029
932
|
signal
|
|
1030
|
-
});
|
|
933
|
+
}, params);
|
|
1031
934
|
if (!res.ok) throw await require_resolve_allowlist.createMSTeamsHttpError(res, "Get driveItem properties failed");
|
|
1032
935
|
return await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, "msteams.graph-upload.getDriveItemProperties");
|
|
1033
936
|
}
|
|
@@ -1044,18 +947,19 @@ async function getDriveItemProperties(params) {
|
|
|
1044
947
|
* Used to create sharing links scoped to only the chat participants.
|
|
1045
948
|
*/
|
|
1046
949
|
async function getChatMembers(params) {
|
|
1047
|
-
const fetchFn = params.fetchFn ?? fetch;
|
|
1048
950
|
return await require_resolve_allowlist.withMSTeamsAbortableRequestTimeout({
|
|
1049
951
|
label: SHAREPOINT_REQUEST_TIMEOUT_LABEL,
|
|
1050
952
|
work: async (signal) => {
|
|
953
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
1051
954
|
const token = await getGraphAccessToken(params.tokenProvider);
|
|
1052
|
-
|
|
955
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
956
|
+
const res = await requestSharePoint(`${GRAPH_ROOT}/chats/${params.chatId}/members`, {
|
|
1053
957
|
headers: {
|
|
1054
958
|
"User-Agent": require_resolve_allowlist.buildUserAgent(),
|
|
1055
959
|
Authorization: `Bearer ${token}`
|
|
1056
960
|
},
|
|
1057
961
|
signal
|
|
1058
|
-
});
|
|
962
|
+
}, params);
|
|
1059
963
|
if (!res.ok) {
|
|
1060
964
|
const message = res.status === 403 ? "Get chat members failed; verify Graph chat-member permissions and tenant access policies" : "Get chat members failed";
|
|
1061
965
|
throw await require_resolve_allowlist.createMSTeamsHttpError(res, message);
|
|
@@ -1070,7 +974,6 @@ async function getChatMembers(params) {
|
|
|
1070
974
|
* For per-user scope, uses beta API with recipients.
|
|
1071
975
|
*/
|
|
1072
976
|
async function createSharePointSharingLink(params) {
|
|
1073
|
-
const fetchFn = params.fetchFn ?? fetch;
|
|
1074
977
|
const scope = params.scope ?? "organization";
|
|
1075
978
|
const apiRoot = scope === "users" ? GRAPH_BETA : GRAPH_ROOT;
|
|
1076
979
|
const body = {
|
|
@@ -1081,8 +984,10 @@ async function createSharePointSharingLink(params) {
|
|
|
1081
984
|
const data = await require_resolve_allowlist.withMSTeamsAbortableRequestTimeout({
|
|
1082
985
|
label: SHAREPOINT_REQUEST_TIMEOUT_LABEL,
|
|
1083
986
|
work: async (signal) => {
|
|
987
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
1084
988
|
const token = await getGraphAccessToken(params.tokenProvider);
|
|
1085
|
-
|
|
989
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
990
|
+
const res = await requestSharePoint(`${apiRoot}/sites/${params.siteId}/drive/items/${params.itemId}/createLink`, {
|
|
1086
991
|
method: "POST",
|
|
1087
992
|
headers: {
|
|
1088
993
|
"User-Agent": require_resolve_allowlist.buildUserAgent(),
|
|
@@ -1091,7 +996,7 @@ async function createSharePointSharingLink(params) {
|
|
|
1091
996
|
},
|
|
1092
997
|
body: JSON.stringify(body),
|
|
1093
998
|
signal
|
|
1094
|
-
});
|
|
999
|
+
}, params);
|
|
1095
1000
|
if (!res.ok) throw await require_resolve_allowlist.createMSTeamsHttpError(res, "Create SharePoint sharing link failed");
|
|
1096
1001
|
return await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, "msteams.graph-upload.createSharePointSharingLink");
|
|
1097
1002
|
}
|
|
@@ -1116,7 +1021,8 @@ async function uploadAndShareSharePoint(params) {
|
|
|
1116
1021
|
contentType: params.contentType,
|
|
1117
1022
|
tokenProvider: params.tokenProvider,
|
|
1118
1023
|
siteId: params.siteId,
|
|
1119
|
-
fetchFn: params.fetchFn
|
|
1024
|
+
fetchFn: params.fetchFn,
|
|
1025
|
+
assertDirectAdapterHandoff: params.assertDirectAdapterHandoff
|
|
1120
1026
|
});
|
|
1121
1027
|
let scope = "organization";
|
|
1122
1028
|
let recipientObjectIds;
|
|
@@ -1124,7 +1030,8 @@ async function uploadAndShareSharePoint(params) {
|
|
|
1124
1030
|
const members = await getChatMembers({
|
|
1125
1031
|
chatId: params.chatId,
|
|
1126
1032
|
tokenProvider: params.tokenProvider,
|
|
1127
|
-
fetchFn: params.fetchFn
|
|
1033
|
+
fetchFn: params.fetchFn,
|
|
1034
|
+
assertDirectAdapterHandoff: params.assertDirectAdapterHandoff
|
|
1128
1035
|
});
|
|
1129
1036
|
if (members.length === 0) throw new Error("MS Teams chat member lookup returned no recipients");
|
|
1130
1037
|
scope = "users";
|
|
@@ -1136,7 +1043,8 @@ async function uploadAndShareSharePoint(params) {
|
|
|
1136
1043
|
tokenProvider: params.tokenProvider,
|
|
1137
1044
|
scope,
|
|
1138
1045
|
recipientObjectIds,
|
|
1139
|
-
fetchFn: params.fetchFn
|
|
1046
|
+
fetchFn: params.fetchFn,
|
|
1047
|
+
assertDirectAdapterHandoff: params.assertDirectAdapterHandoff
|
|
1140
1048
|
});
|
|
1141
1049
|
return {
|
|
1142
1050
|
itemId: uploaded.id,
|
|
@@ -1236,13 +1144,13 @@ function isValidTeamsId(id) {
|
|
|
1236
1144
|
* Returns both the formatted text with <at> tags and the entities array.
|
|
1237
1145
|
*/
|
|
1238
1146
|
function parseMentions(text) {
|
|
1239
|
-
const mentionPattern = /@\[([^\]]+)\]\(([^)]+)\)/g;
|
|
1147
|
+
const mentionPattern = /@\[((?:\\[\s\S]|[^\]\\])+)\]\(([^)]+)\)/g;
|
|
1240
1148
|
const entities = [];
|
|
1241
1149
|
return {
|
|
1242
1150
|
text: text.replace(mentionPattern, (match, name, id) => {
|
|
1243
1151
|
const trimmedId = id.trim();
|
|
1244
1152
|
if (!isValidTeamsId(trimmedId)) return match;
|
|
1245
|
-
const trimmedName = name.trim();
|
|
1153
|
+
const trimmedName = name.replace(/\\([\\[\]])/g, "$1").trim();
|
|
1246
1154
|
const mentionTag = `<at>${trimmedName}</at>`;
|
|
1247
1155
|
entities.push({
|
|
1248
1156
|
type: "mention",
|
|
@@ -1390,24 +1298,28 @@ function mergeReferenceIntoActivity(activity, ref) {
|
|
|
1390
1298
|
};
|
|
1391
1299
|
}
|
|
1392
1300
|
async function sendMSTeamsActivityWithReference(app, source, activity, options) {
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
const
|
|
1301
|
+
return require_resolve_allowlist.withMSTeamsConnectorHandoff(options ?? {}, async (handoff) => {
|
|
1302
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(handoff);
|
|
1303
|
+
const ref = buildSdkConversationReference(source, options);
|
|
1304
|
+
const activities = (await getApiClientForReference(app, ref)).conversations.activities(ref.conversation.id);
|
|
1305
|
+
const activityWithRef = mergeReferenceIntoActivity(options?.quoteActivityId ? await quoteMSTeamsActivity(activity, options.quoteActivityId) : activity, ref);
|
|
1306
|
+
const isTargeted = activityWithRef.recipient?.isTargeted === true;
|
|
1307
|
+
if (isTargeted && ref.conversation.conversationType === "personal") throw new Error("Targeted messages are not supported in 1:1 (personal) chats.");
|
|
1308
|
+
const activityId = typeof activityWithRef.id === "string" ? activityWithRef.id : void 0;
|
|
1309
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(handoff);
|
|
1310
|
+
if (activityId) {
|
|
1311
|
+
const res = isTargeted && activities.updateTargeted ? await activities.updateTargeted(activityId, activityWithRef) : await activities.update(activityId, activityWithRef);
|
|
1312
|
+
return {
|
|
1313
|
+
...activityWithRef,
|
|
1314
|
+
...res && typeof res === "object" ? res : {}
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
const res = isTargeted && activities.createTargeted ? await activities.createTargeted(activityWithRef) : await activities.create(activityWithRef);
|
|
1401
1318
|
return {
|
|
1402
1319
|
...activityWithRef,
|
|
1403
|
-
...res
|
|
1320
|
+
...res
|
|
1404
1321
|
};
|
|
1405
|
-
}
|
|
1406
|
-
const res = isTargeted && activities.createTargeted ? await activities.createTargeted(activityWithRef) : await activities.create(activityWithRef);
|
|
1407
|
-
return {
|
|
1408
|
-
...activityWithRef,
|
|
1409
|
-
...res
|
|
1410
|
-
};
|
|
1322
|
+
});
|
|
1411
1323
|
}
|
|
1412
1324
|
async function updateMSTeamsActivityWithReference(app, source, activityId, activity, options) {
|
|
1413
1325
|
const ref = buildSdkConversationReference(source, options);
|
|
@@ -1566,6 +1478,7 @@ async function buildActivity(msg, conversationRef, tokenProvider, sharePointSite
|
|
|
1566
1478
|
thresholdBytes: FILE_CONSENT_THRESHOLD_BYTES
|
|
1567
1479
|
})) {
|
|
1568
1480
|
const conversationId = conversationRef.conversation?.id ?? "unknown";
|
|
1481
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(options);
|
|
1569
1482
|
const { activity: consentActivity, uploadId } = prepareFileConsentActivity({
|
|
1570
1483
|
media: {
|
|
1571
1484
|
buffer: media.buffer,
|
|
@@ -1582,17 +1495,20 @@ async function buildActivity(msg, conversationRef, tokenProvider, sharePointSite
|
|
|
1582
1495
|
const siteId = requireMSTeamsSharePointSiteId(sharePointSiteId);
|
|
1583
1496
|
if (!tokenProvider) throw new Error("MS Teams Graph token provider unavailable for SharePoint file send");
|
|
1584
1497
|
const chatId = conversationRef.conversation?.id;
|
|
1498
|
+
const uploaded = await uploadAndShareSharePoint({
|
|
1499
|
+
assertDirectAdapterHandoff: options?.assertDirectAdapterHandoff,
|
|
1500
|
+
buffer: media.buffer,
|
|
1501
|
+
filename: fileName,
|
|
1502
|
+
contentType,
|
|
1503
|
+
tokenProvider,
|
|
1504
|
+
siteId,
|
|
1505
|
+
chatId: chatId ?? void 0,
|
|
1506
|
+
usePerUserSharing: conversationType === "groupchat"
|
|
1507
|
+
});
|
|
1585
1508
|
activity.attachments = [buildTeamsFileInfoCard(await getDriveItemProperties({
|
|
1509
|
+
assertDirectAdapterHandoff: options?.assertDirectAdapterHandoff,
|
|
1586
1510
|
siteId,
|
|
1587
|
-
itemId:
|
|
1588
|
-
buffer: media.buffer,
|
|
1589
|
-
filename: fileName,
|
|
1590
|
-
contentType,
|
|
1591
|
-
tokenProvider,
|
|
1592
|
-
siteId,
|
|
1593
|
-
chatId: chatId ?? void 0,
|
|
1594
|
-
usePerUserSharing: conversationType === "groupchat"
|
|
1595
|
-
})).itemId,
|
|
1511
|
+
itemId: uploaded.itemId,
|
|
1596
1512
|
tokenProvider
|
|
1597
1513
|
}))];
|
|
1598
1514
|
return activity;
|
|
@@ -1640,9 +1556,14 @@ async function sendMSTeamsMessages(params) {
|
|
|
1640
1556
|
let response;
|
|
1641
1557
|
try {
|
|
1642
1558
|
response = await sendWithRetry(async () => {
|
|
1643
|
-
|
|
1559
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
1560
|
+
activity ??= await buildActivity(message, params.conversationRef, params.tokenProvider, params.sharePointSiteId, params.mediaMaxBytes, {
|
|
1561
|
+
feedbackLoopEnabled: params.feedbackLoopEnabled,
|
|
1562
|
+
assertDirectAdapterHandoff: params.assertDirectAdapterHandoff
|
|
1563
|
+
});
|
|
1644
1564
|
pendingUploadId ??= typeof activity["_pendingUploadId"] === "string" ? activity["_pendingUploadId"] : void 0;
|
|
1645
1565
|
delete activity["_pendingUploadId"];
|
|
1566
|
+
require_resolve_allowlist.assertMSTeamsSendHandoff(params);
|
|
1646
1567
|
providerDispatchStarted = true;
|
|
1647
1568
|
return await sendFn(activity);
|
|
1648
1569
|
}, {
|
|
@@ -1650,10 +1571,11 @@ async function sendMSTeamsMessages(params) {
|
|
|
1650
1571
|
messageCount: messages.length
|
|
1651
1572
|
});
|
|
1652
1573
|
} catch (error) {
|
|
1653
|
-
if (!providerDispatchStarted) throw new openclaw_plugin_sdk_error_runtime.PlatformMessageNotDispatchedError(error instanceof Error ? error.message : "Teams activity preparation failed", { cause: error });
|
|
1574
|
+
if (!providerDispatchStarted && !(error instanceof openclaw_plugin_sdk_error_runtime.PlatformMessageNotDispatchedError)) throw new openclaw_plugin_sdk_error_runtime.PlatformMessageNotDispatchedError(error instanceof Error ? error.message : "Teams activity preparation failed", { cause: error });
|
|
1654
1575
|
throw error;
|
|
1655
1576
|
}
|
|
1656
1577
|
const messageId = extractMessageId(response) ?? "unknown";
|
|
1578
|
+
await params.onMessageSent?.(messageId, messageIndex);
|
|
1657
1579
|
if (pendingUploadId && messageId !== "unknown") setPendingUploadActivityId(pendingUploadId, messageId);
|
|
1658
1580
|
return messageId;
|
|
1659
1581
|
};
|
|
@@ -1672,6 +1594,8 @@ async function sendMSTeamsMessages(params) {
|
|
|
1672
1594
|
}
|
|
1673
1595
|
const isChannel = params.conversationRef.conversation?.conversationType === "channel";
|
|
1674
1596
|
const sendFn = (activity) => sendMSTeamsActivityWithReference(params.app, baseRef, activity, {
|
|
1597
|
+
assertDirectAdapterHandoff: params.assertDirectAdapterHandoff,
|
|
1598
|
+
onPlatformSendDispatch: params.onPlatformSendDispatch,
|
|
1675
1599
|
threadActivityId: isChannel ? threadActivityId : void 0,
|
|
1676
1600
|
serviceUrlBoundary: params.serviceUrlBoundary
|
|
1677
1601
|
});
|
|
@@ -1681,7 +1605,7 @@ async function sendMSTeamsMessages(params) {
|
|
|
1681
1605
|
if (params.replyStyle === "thread") {
|
|
1682
1606
|
const ctx = params.context;
|
|
1683
1607
|
if (!ctx) return await sendProactively(messages, 0, resolvedThreadId);
|
|
1684
|
-
const sendFn = ctx.sendActivity;
|
|
1608
|
+
const sendFn = (activity) => require_resolve_allowlist.withMSTeamsConnectorHandoff(params, () => ctx.sendActivity(activity));
|
|
1685
1609
|
const messageIds = [];
|
|
1686
1610
|
for (const [idx, message] of messages.entries()) {
|
|
1687
1611
|
const result = await withRevokedProxyFallback({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CHzaaWiC.cjs");
|
|
2
2
|
let openclaw_plugin_sdk_runtime_env = require("openclaw/plugin-sdk/runtime-env");
|
|
3
3
|
let openclaw_plugin_sdk_provider_auth = require("openclaw/plugin-sdk/provider-auth");
|
|
4
4
|
let openclaw_plugin_sdk_provider_auth_runtime = require("openclaw/plugin-sdk/provider-auth-runtime");
|
|
@@ -224,7 +224,6 @@ const MSTEAMS_SQLITE_MAX_POLL_ROWS = 2e3;
|
|
|
224
224
|
const MSTEAMS_POLL_VOTE_BUCKET_COUNT = 32;
|
|
225
225
|
const MSTEAMS_MAX_POLL_VOTE_BUCKET_ROWS = 1001 * MSTEAMS_POLL_VOTE_BUCKET_COUNT;
|
|
226
226
|
const MSTEAMS_POLL_TTL_MS = 2592e6;
|
|
227
|
-
const POLL_MUTATION_KEY = "polls";
|
|
228
227
|
function normalizeChoiceValue(value) {
|
|
229
228
|
if (typeof value === "string") {
|
|
230
229
|
const trimmed = value.trim();
|
|
@@ -404,8 +403,11 @@ function createMSTeamsPollStoreState(params) {
|
|
|
404
403
|
for (const row of await voteBucketStore.entries()) if (row.value.pollId === pollId) Object.assign(votes, row.value.votes);
|
|
405
404
|
return votes;
|
|
406
405
|
};
|
|
407
|
-
const deletePollVotes = async (pollId) => {
|
|
408
|
-
for (const row of await voteBucketStore.entries()) if (row.value.pollId === pollId)
|
|
406
|
+
const deletePollVotes = async (pollId, cachedRows) => {
|
|
407
|
+
for (const row of cachedRows?.values() ?? await voteBucketStore.entries()) if (row.value.pollId === pollId) {
|
|
408
|
+
await voteBucketStore.delete(row.key);
|
|
409
|
+
cachedRows?.delete(row.key);
|
|
410
|
+
}
|
|
409
411
|
};
|
|
410
412
|
const registerPollVotes = async (pollId, votes, updatedAt) => {
|
|
411
413
|
const buckets = /* @__PURE__ */ new Map();
|
|
@@ -450,11 +452,16 @@ function createMSTeamsPollStoreState(params) {
|
|
|
450
452
|
};
|
|
451
453
|
};
|
|
452
454
|
const prunePollStoreToLimit = async () => {
|
|
455
|
+
let voteRows;
|
|
456
|
+
const deletePrunedPollVotes = async (pollId) => {
|
|
457
|
+
voteRows ??= new Map((await voteBucketStore.entries()).map((row) => [row.key, row]));
|
|
458
|
+
await deletePollVotes(pollId, voteRows);
|
|
459
|
+
};
|
|
453
460
|
const rows = [];
|
|
454
461
|
for (const row of await pollStore.entries()) {
|
|
455
462
|
if (!pruneExpired({ [row.key]: row.value })[row.key]) {
|
|
456
463
|
await pollStore.delete(row.key);
|
|
457
|
-
await
|
|
464
|
+
await deletePrunedPollVotes(row.value.id);
|
|
458
465
|
continue;
|
|
459
466
|
}
|
|
460
467
|
rows.push(row);
|
|
@@ -465,11 +472,11 @@ function createMSTeamsPollStoreState(params) {
|
|
|
465
472
|
});
|
|
466
473
|
for (const row of sorted.slice(0, rows.length - MSTEAMS_MAX_POLLS)) {
|
|
467
474
|
await pollStore.delete(row.key);
|
|
468
|
-
await
|
|
475
|
+
await deletePrunedPollVotes(row.value.id);
|
|
469
476
|
}
|
|
470
477
|
};
|
|
471
478
|
const createPoll = async (poll) => {
|
|
472
|
-
await withMSTeamsSqliteMutationLock(params,
|
|
479
|
+
await withMSTeamsSqliteMutationLock(params, MSTEAMS_POLLS_NAMESPACE, async () => {
|
|
473
480
|
const { metadata, votes } = splitMSTeamsPoll(poll);
|
|
474
481
|
await pollStore.register(buildMSTeamsPollStateKey(poll.id), toPluginJsonValue(metadata));
|
|
475
482
|
await deletePollVotes(poll.id);
|
|
@@ -484,7 +491,7 @@ function createMSTeamsPollStoreState(params) {
|
|
|
484
491
|
return await reconstructPoll(poll);
|
|
485
492
|
};
|
|
486
493
|
const recordVote = async (vote) => {
|
|
487
|
-
return await withMSTeamsSqliteMutationLock(params,
|
|
494
|
+
return await withMSTeamsSqliteMutationLock(params, MSTEAMS_POLLS_NAMESPACE, async () => {
|
|
488
495
|
const pollKey = buildMSTeamsPollStateKey(vote.pollId);
|
|
489
496
|
const poll = await pollStore.lookup(pollKey);
|
|
490
497
|
if (!poll) return null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CHzaaWiC.cjs");
|
|
2
2
|
let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
|
|
3
3
|
//#region extensions/msteams/src/graph-thread.ts
|
|
4
4
|
/**
|