mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 21:54:31 +00:00
feat(slack): add download-file action for on-demand file attachment access (#24723)
* feat(slack): add download-file action for on-demand file attachment access Adds a new `download-file` message tool action that allows the agent to download Slack file attachments by file ID on demand. This is a prerequisite for accessing images posted in thread history, where file attachments are not automatically resolved. Changes: - Add `files` field to `SlackMessageSummary` type so file IDs are visible in message read results - Add `downloadSlackFile()` to fetch a file by ID via `files.info` and resolve it through the existing `resolveSlackMedia()` pipeline - Register `download-file` in `CHANNEL_MESSAGE_ACTION_NAMES`, `MESSAGE_ACTION_TARGET_MODE`, and `listSlackMessageActions` - Add `downloadFile` dispatch case in `handleSlackAction` - Wire agent-facing `download-file` → internal `downloadFile` in `handleSlackMessageAction` Closes #24681 * style: fix formatting in slack-actions and actions * test(slack): cover download-file action path --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { handleSlackAction } from "./slack-actions.js";
|
||||
|
||||
const deleteSlackMessage = vi.fn(async (..._args: unknown[]) => ({}));
|
||||
const downloadSlackFile = vi.fn(async (..._args: unknown[]) => null);
|
||||
const editSlackMessage = vi.fn(async (..._args: unknown[]) => ({}));
|
||||
const getSlackMemberInfo = vi.fn(async (..._args: unknown[]) => ({}));
|
||||
const listSlackEmojis = vi.fn(async (..._args: unknown[]) => ({}));
|
||||
@@ -19,6 +20,7 @@ const unpinSlackMessage = vi.fn(async (..._args: unknown[]) => ({}));
|
||||
vi.mock("../../slack/actions.js", () => ({
|
||||
deleteSlackMessage: (...args: Parameters<typeof deleteSlackMessage>) =>
|
||||
deleteSlackMessage(...args),
|
||||
downloadSlackFile: (...args: Parameters<typeof downloadSlackFile>) => downloadSlackFile(...args),
|
||||
editSlackMessage: (...args: Parameters<typeof editSlackMessage>) => editSlackMessage(...args),
|
||||
getSlackMemberInfo: (...args: Parameters<typeof getSlackMemberInfo>) =>
|
||||
getSlackMemberInfo(...args),
|
||||
@@ -194,6 +196,26 @@ describe("handleSlackAction", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("returns a friendly error when downloadFile cannot fetch the attachment", async () => {
|
||||
downloadSlackFile.mockResolvedValueOnce(null);
|
||||
const result = await handleSlackAction(
|
||||
{
|
||||
action: "downloadFile",
|
||||
fileId: "F123",
|
||||
},
|
||||
slackConfig(),
|
||||
);
|
||||
expect(downloadSlackFile).toHaveBeenCalledWith(
|
||||
"F123",
|
||||
expect.objectContaining({ maxBytes: 20 * 1024 * 1024 }),
|
||||
);
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
details: expect.objectContaining({ ok: false }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: "JSON blocks",
|
||||
|
||||
Reference in New Issue
Block a user