























@@ -624,7 +624,7 @@ describe("preflightDiscordMessage", () => {
624624expect(result?.boundSessionKey).toBe(threadBinding.targetSessionKey);
625625});
626626627-it("drops hydrated bound-thread webhook echoes after fetching an empty payload", async () => {
627+it("drops hydrated bound-thread webhook copies after fetching an empty payload", async () => {
628628const threadBinding = createThreadBinding({
629629targetKind: "session",
630630targetSessionKey: "agent:main:acp:discord-thread-1",
@@ -685,6 +685,38 @@ describe("preflightDiscordMessage", () => {
685685expect(result).toBeNull();
686686});
687687688+it("drops bound-thread webhook copies from other webhook ids", async () => {
689+const threadBinding = createThreadBinding({
690+targetKind: "session",
691+targetSessionKey: "agent:main:acp:discord-thread-1",
692+});
693+const threadId = "thread-webhook-proxy-1";
694+const parentId = "channel-parent-webhook-proxy-1";
695+const message = createDiscordMessage({
696+id: "m-webhook-proxy-1",
697+channelId: threadId,
698+content: "proxied user message",
699+webhook_id: "pluralkit-webhook-1",
700+author: {
701+id: "relay-bot-1",
702+bot: true,
703+username: "Proxy",
704+},
705+});
706+707+const result = await runThreadBoundPreflight({
708+ threadId,
709+ parentId,
710+ message,
711+ threadBinding,
712+discordConfig: {
713+allowBots: true,
714+} as DiscordConfig,
715+});
716+717+expect(result).toBeNull();
718+});
719+688720it("bypasses mention gating in bound threads for allowed bot senders", async () => {
689721const threadBinding = createThreadBinding();
690722const threadId = "thread-bot-focus";
@@ -1445,25 +1477,36 @@ describe("shouldIgnoreBoundThreadWebhookMessage", () => {
14451477).toBe(true);
14461478});
144714791448-it("returns false when webhook ids differ", () => {
1480+it("returns true when a bound thread receives a different webhook id", () => {
14491481expect(
14501482shouldIgnoreBoundThreadWebhookMessage({
1483+threadId: "thread-1",
14511484webhookId: "wh-other",
14521485threadBinding: createThreadBinding(),
14531486}),
1454-).toBe(false);
1487+).toBe(true);
14551488});
145614891457-it("returns false when there is no bound thread webhook", () => {
1490+it("returns true when a bound thread receives a webhook without a recorded bound webhook id", () => {
14581491expect(
14591492shouldIgnoreBoundThreadWebhookMessage({
1493+threadId: "thread-1",
14601494webhookId: "wh-1",
14611495threadBinding: createThreadBinding({
14621496metadata: {
14631497webhookId: undefined,
14641498},
14651499}),
14661500}),
1501+).toBe(true);
1502+});
1503+1504+it("returns false for differing webhook ids without a known thread id", () => {
1505+expect(
1506+shouldIgnoreBoundThreadWebhookMessage({
1507+webhookId: "wh-other",
1508+threadBinding: createThreadBinding(),
1509+}),
14671510).toBe(false);
14681511});
14691512此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。