fix: read Slack thread replies for message reads (#1450) (#1450)

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Rodrigo Uroz <rodrigouroz@users.noreply.github.com>
This commit is contained in:
Rodrigo Uroz
2026-01-23 01:17:45 -03:00
committed by GitHub
parent 5d001cb953
commit dd2400fb2a
7 changed files with 140 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
import { describe, expect, it, vi } from "vitest";
import type { WebClient } from "@slack/web-api";
import { readSlackMessages } from "./actions.js";
function createClient() {
return {
conversations: {
replies: vi.fn(async () => ({ messages: [], has_more: false })),
history: vi.fn(async () => ({ messages: [], has_more: false })),
},
} as unknown as WebClient & {
conversations: {
replies: ReturnType<typeof vi.fn>;
history: ReturnType<typeof vi.fn>;
};
};
}
describe("readSlackMessages", () => {
it("uses conversations.replies and drops the parent message", async () => {
const client = createClient();
client.conversations.replies.mockResolvedValueOnce({
messages: [{ ts: "171234.567" }, { ts: "171234.890" }, { ts: "171235.000" }],
has_more: true,
});
const result = await readSlackMessages("C1", {
client,
threadId: "171234.567",
token: "xoxb-test",
});
expect(client.conversations.replies).toHaveBeenCalledWith({
channel: "C1",
ts: "171234.567",
limit: undefined,
latest: undefined,
oldest: undefined,
});
expect(client.conversations.history).not.toHaveBeenCalled();
expect(result.messages.map((message) => message.ts)).toEqual(["171234.890", "171235.000"]);
});
it("uses conversations.history when threadId is missing", async () => {
const client = createClient();
client.conversations.history.mockResolvedValueOnce({
messages: [{ ts: "1" }],
has_more: false,
});
const result = await readSlackMessages("C1", {
client,
limit: 20,
token: "xoxb-test",
});
expect(client.conversations.history).toHaveBeenCalledWith({
channel: "C1",
limit: 20,
latest: undefined,
oldest: undefined,
});
expect(client.conversations.replies).not.toHaveBeenCalled();
expect(result.messages.map((message) => message.ts)).toEqual(["1"]);
});
});

View File

@@ -186,9 +186,29 @@ export async function readSlackMessages(
limit?: number;
before?: string;
after?: string;
threadId?: string;
} = {},
): Promise<{ messages: SlackMessageSummary[]; hasMore: boolean }> {
const client = await getClient(opts);
// Use conversations.replies for thread messages, conversations.history for channel messages.
if (opts.threadId) {
const result = await client.conversations.replies({
channel: channelId,
ts: opts.threadId,
limit: opts.limit,
latest: opts.before,
oldest: opts.after,
});
return {
// conversations.replies includes the parent message; drop it for replies-only reads.
messages: (result.messages ?? []).filter(
(message) => (message as SlackMessageSummary)?.ts !== opts.threadId,
) as SlackMessageSummary[],
hasMore: Boolean(result.has_more),
};
}
const result = await client.conversations.history({
channel: channelId,
limit: opts.limit,