fix(slack): preserve real thread anchors

This commit is contained in:
Peter Steinberger
2026-04-25 00:38:01 +01:00
parent 82020bd787
commit e40d7abda9
10 changed files with 287 additions and 13 deletions

View File

@@ -61,11 +61,19 @@ const slackMessaging: ChannelMessagingAdapter = {
const slackThreading: ChannelThreadingAdapter = {
resolveReplyTransport: ({ threadId, replyToId }) => ({
replyToId: replyToId ?? (threadId != null && threadId !== "" ? String(threadId) : undefined),
replyToId: resolveSlackThreadTsCandidate(replyToId) ?? resolveSlackThreadTsCandidate(threadId),
threadId: null,
}),
};
function resolveSlackThreadTsCandidate(value?: string | number | null): string | undefined {
if (typeof value !== "string") {
return undefined;
}
const normalized = value.trim();
return /^\d+\.\d+$/.test(normalized) ? normalized : undefined;
}
const mattermostThreading: ChannelThreadingAdapter = {
resolveReplyTransport: ({ threadId, replyToId }) => ({
replyToId: replyToId ?? (threadId != null && threadId !== "" ? String(threadId) : undefined),
@@ -489,6 +497,21 @@ describe("routeReply", () => {
});
});
it("uses Slack threadId when routed replyToId is an internal message id", async () => {
await routeReply({
payload: { text: "hi", replyToId: "msg-internal-1" },
channel: "slack",
to: "channel:C123",
threadId: "1710000000.9999",
cfg: {} as never,
});
expectLastDelivery({
channel: "slack",
replyToId: "1710000000.9999",
threadId: null,
});
});
it("uses threadId as replyToId for Mattermost when replyToId is missing", async () => {
await routeReply({
payload: { text: "hi" },