/** * Slack file fetch — get a Slack file by link or id, even one your own bot * cannot see. * * Slack serves a file only to members of a channel it was shared in. An * agent asked to work on a colleague's file from another channel, often * posted from another machine so the event never reached this one, had no * way to open it. Rex asked Ella to "paste the text into the thread" * instead (2026-10-08, `longform-en.md` in #pro-crewly-marketing). * * Order: * 1. Locally, with the bot tokens this instance holds: the requesting * agent's own bot, the uploader's bot, bots of agents in the channel, * the workspace bot, then any other installed identity. The first one * `files.info` answers for downloads the file. * 2. Otherwise Crewly Cloud (`POST /api/cloud/slack/files/fetch`), which * holds every bot of the account and tries them the same way. * * Files land in the same directory as inbound Slack attachments * (`~/.crewly/tmp/slack-files/-`). * * @module services/slack/slack-file-fetch */ import { type SlackFileRef } from './slack-file-ref.js'; /** Stable failure codes (the route maps them to HTTP statuses). */ export type SlackFileGetErrorCode = 'validation' | 'not_visible' | 'no_file_in_message' | 'file_deleted' | 'too_large' | 'foreign_workspace' | 'cloud_unavailable' | 'slack_error'; /** HTTP status per code. */ export declare const SLACK_FILE_GET_STATUS: Record; /** A failure with a stable code. */ export declare class SlackFileGetError extends Error { readonly code: SlackFileGetErrorCode; constructor(code: SlackFileGetErrorCode, message: string); } /** What the caller learns about a fetched file. */ export interface SlackFetchedFileMeta { id: string; name: string; mimetype: string; size: number; user: string | null; channels: string[]; permalink: string | null; isText: boolean; /** Who could see it: `local:`, `local:workspace`, or `cloud:`. */ via: string; /** Other files on the same message (message links). */ otherFileIds?: string[]; } /** A fetched file, saved on disk. */ export interface SlackFetchedFile { meta: SlackFetchedFileMeta; localPath: string; } /** One bot token this instance may try. */ export interface LocalTokenCandidate { token: string; /** For logs and the result: `` or `workspace`. */ label: string; } /** Collaborators (injectable for tests). */ export interface SlackFileFetchDeps { /** Local bot tokens in the order to try them. */ localCandidates: (ref: SlackFileRef, requesterAgent?: string) => LocalTokenCandidate[] | Promise; /** Cloud base URL and access token; null when not signed in. */ cloud: () => { baseUrl: string; token: string; } | null; /** Where files are written. Default `~/.crewly/tmp/slack-files`. */ saveDir?: string; fetchImpl?: typeof fetch; slackApiBase?: string; } /** * The service — see module docs. */ export declare class SlackFileFetchService { private readonly deps; private readonly logger; private readonly fetchImpl; private readonly apiBase; private readonly saveDir; constructor(deps: SlackFileFetchDeps); /** * Fetch a file: locally first, then through Cloud. * * @param fileRef - File id, permalink, download URL or message link * @param opts - `requesterAgent` (preferred bot, audit), `maxBytes` (default 25 MB) * @returns Metadata and the saved path * @throws {SlackFileGetError} */ get(fileRef: string, opts?: { requesterAgent?: string; maxBytes?: number; }): Promise; private getLocal; private fileFromMessage; private download; private getViaCloud; private save; private slack; } /** * The first lines of a text file, for a one-glance preview. * * @param localPath - Saved file * @returns Up to PREVIEW_LINES lines / PREVIEW_CHARS characters */ export declare function previewTextFile(localPath: string): Promise; /** * The process-wide service, wired to this instance's Slack identities and * Cloud sign-in. Built on first use. * * @returns The service */ export declare function getSlackFileFetchService(): Promise; /** Replace the process-wide service (tests). */ export declare function setSlackFileFetchService(service: SlackFileFetchService | null): void; //# sourceMappingURL=slack-file-fetch.service.d.ts.map