/** * Slack Image Service * * Handles downloading, validating, and managing Slack image files. * Downloads images sent by users in Slack to a local temp directory * so that agents can read them via their file-reading tools. * * @module services/slack/slack-image */ import type { SlackFile, SlackImageInfo } from '../../types/slack.types.js'; /** * SlackImageService manages downloading and lifecycle of images * sent by Slack users. Downloaded files are stored under * `~/.crewly/tmp/slack-images/` and cleaned up periodically. * * @example * ```typescript * const service = new SlackImageService(); * await service.cleanupOnStartup(); * service.startCleanup(); * const imageInfo = await service.downloadImage(slackFile, botToken); * ``` */ export declare class SlackImageService { private logger; private tempDir; private cleanupTimer; /** * Create a new SlackImageService. * * @param crewlyHome - Base crewly home directory (defaults to ~/.crewly) */ constructor(crewlyHome?: string); /** * Get the temp directory path for downloaded images. * * @returns Absolute path to the temp directory */ getTempDir(): string; /** * Download a Slack image file to the local temp directory. * * Validates the file MIME type and size before downloading. * Uses the Slack bot token to authenticate the download request. * * @param file - Slack file object from the event payload * @param botToken - Bot OAuth token for authenticating the download * @returns Downloaded image info with local path * @throws Error if file validation fails or download errors occur */ downloadImage(file: SlackFile, botToken: string): Promise; /** * Start the periodic cleanup timer for expired temp files. * Runs every hour by default (configured by CLEANUP_INTERVAL). */ startCleanup(): void; /** * Stop the periodic cleanup timer. */ stopCleanup(): void; /** * Delete temp files older than the configured TTL. * * @returns Number of files deleted */ cleanupExpired(): Promise; /** * Clean up all stale temp files on startup. * Called once during server initialization. */ cleanupOnStartup(): Promise; /** * Verify that a file on disk starts with valid image magic bytes. * Reads the first 8 bytes and checks against known signatures * for PNG, JPEG, GIF, and WebP formats. * * @param filePath - Path to the downloaded file * @returns True if the file matches a known image signature */ verifyImageMagicBytes(filePath: string): Promise; /** * Fetch a URL with manual redirect handling to preserve the Authorization header. * Node.js fetch strips the Authorization header on cross-origin redirects * (per the Fetch specification), but Slack file URLs redirect from * files.slack.com to CDN domains that may require the token. * * @param url - URL to fetch * @param botToken - Bot OAuth token for the Authorization header * @returns Final response after following any redirects * @throws Error if too many redirects or a redirect has no Location header */ private authenticatedFetch; /** * Check temp directory total size and log a warning if it exceeds the threshold. */ private checkTempDirSize; } /** * Get the SlackImageService singleton. * * @returns The service instance */ export declare function getSlackImageService(): SlackImageService; /** * Set the SlackImageService singleton. * * @param service - The service instance to set */ export declare function setSlackImageService(service: SlackImageService): void; /** * Reset the SlackImageService singleton (for testing). */ export declare function resetSlackImageService(): void; //# sourceMappingURL=slack-image.service.d.ts.map