Official library for using the Slack Platform's Web API
—
Upload files, manage file permissions, and interact with Slack's file storage system.
Modern file upload implementation using Slack's external upload flow for better performance and reliability.
/**
* Upload files using the v2 external upload method
* @param options - File upload configuration
* @returns Promise resolving to upload results with file details
*/
files.uploadV2(options: FilesUploadV2Arguments): Promise<WebAPICallResult & {
files: FilesCompleteUploadExternalResponse[];
}>;
interface FilesUploadV2Arguments {
/** Channel ID where the file will be shared */
channel_id?: string;
/** Channel names where the file will be shared (comma-separated) */
channels?: string;
/** Title of the file */
title?: string;
/** File content as Buffer, Stream, or string */
file?: Buffer | NodeJS.ReadableStream | string;
/** Filename for the uploaded file */
filename?: string;
/** File type/extension */
filetype?: string;
/** Alternative file content (for text files) */
content?: string;
/** Initial comment to add with the file */
initial_comment?: string;
/** Thread timestamp to upload file to a specific thread */
thread_ts?: string;
/** Alt text for accessibility */
alt_text?: string;
/** Snippet type for code files */
snippet_type?: string;
}Usage Examples:
import { WebClient } from "@slack/web-api";
import { createReadStream } from "fs";
const web = new WebClient(token);
// Upload file from filesystem
const result = await web.files.uploadV2({
channels: '#general',
file: createReadStream('./report.pdf'),
filename: 'monthly-report.pdf',
title: 'Monthly Sales Report',
initial_comment: 'Here is this month\'s sales report with key metrics.'
});
console.log('Uploaded files:', result.files.map(f => f.id));
// Upload text content as a file
await web.files.uploadV2({
channels: 'D1234567890', // Direct message
content: JSON.stringify({ data: 'example' }, null, 2),
filename: 'data.json',
filetype: 'json',
title: 'Sample Data'
});
// Upload to specific thread with alt text
await web.files.uploadV2({
channel_id: 'C1234567890',
file: Buffer.from('Debug info:\n\nError occurred at line 42'),
filename: 'debug.log',
thread_ts: '1234567890.123456',
alt_text: 'Debug log file showing error details'
});
// Upload code snippet
await web.files.uploadV2({
channels: '#dev-team',
content: `
function greet(name) {
return \`Hello, \${name}!\`;
}
`.trim(),
filename: 'greeting.js',
snippet_type: 'javascript',
title: 'Greeting Function'
});Retrieve detailed information about uploaded files.
/**
* Get information about a file
* @param options - File info parameters
* @returns Promise resolving to file details
*/
files.info(options: FilesInfoArguments): Promise<FilesInfoResponse>;
interface FilesInfoArguments {
/** File ID to get info about */
file: string;
/** Number of items to return per page for comments */
count?: number;
/** Page number of comments to return */
page?: number;
}Usage Examples:
// Get basic file information
const fileInfo = await web.files.info({
file: 'F1234567890'
});
console.log('File name:', fileInfo.file.name);
console.log('File size:', fileInfo.file.size, 'bytes');
console.log('File type:', fileInfo.file.pretty_type);
console.log('Created by:', fileInfo.file.user);
// Get file info with comments
const fileWithComments = await web.files.info({
file: 'F1234567890',
count: 50,
page: 1
});
console.log('Comments:', fileWithComments.comments);Retrieve lists of files with filtering and pagination.
/**
* List files uploaded to the workspace
* @param options - List parameters
* @returns Promise resolving to files list
*/
files.list(options?: FilesListArguments): Promise<FilesListResponse>;
interface FilesListArguments {
/** Filter files by user ID */
user?: string;
/** Filter files by channel ID */
channel?: string;
/** Filter by file type (e.g., 'images', 'pdfs', 'zips') */
types?: string;
/** End of time range of files to include */
ts_to?: number;
/** Start of time range of files to include */
ts_from?: number;
/** Number of items to return per page */
count?: number;
/** Page number to return */
page?: number;
/** Show files hidden by limit */
show_files_hidden_by_limit?: boolean;
}Usage Examples:
// List recent files
const recentFiles = await web.files.list({
count: 20,
page: 1
});
console.log(`Found ${recentFiles.files.length} files`);
// List files by specific user
const userFiles = await web.files.list({
user: 'U1234567890',
count: 50
});
// List files in specific channel
const channelFiles = await web.files.list({
channel: 'C1234567890',
count: 100
});
// List files by type and date range
const lastWeek = Math.floor((Date.now() - 7 * 24 * 60 * 60 * 1000) / 1000);
const imageFiles = await web.files.list({
types: 'images',
ts_from: lastWeek,
count: 30
});Remove files from the workspace.
/**
* Delete a file
* @param options - Delete parameters
* @returns Promise resolving to deletion confirmation
*/
files.delete(options: FilesDeleteArguments): Promise<FilesDeleteResponse>;
interface FilesDeleteArguments {
/** File ID to delete */
file: string;
}Usage Examples:
// Delete a file
const result = await web.files.delete({
file: 'F1234567890'
});
if (result.ok) {
console.log('File deleted successfully');
}
// Delete multiple files
const filesToDelete = ['F1111111111', 'F2222222222', 'F3333333333'];
for (const fileId of filesToDelete) {
try {
await web.files.delete({ file: fileId });
console.log(`Deleted file: ${fileId}`);
} catch (error) {
console.error(`Failed to delete file ${fileId}:`, error.message);
}
}Manage public sharing URLs for files.
/**
* Enable public sharing for a file and get the URL
* @param options - Share parameters
* @returns Promise resolving to public URL details
*/
files.sharedPublicURL(options: FilesSharedPublicURLArguments): Promise<FilesSharedPublicURLResponse>;
/**
* Revoke public sharing for a file
* @param options - Revoke parameters
* @returns Promise resolving to revocation confirmation
*/
files.revokePublicURL(options: FilesRevokePublicURLArguments): Promise<FilesRevokePublicURLResponse>;
interface FilesSharedPublicURLArguments {
/** File ID to enable public sharing for */
file: string;
}
interface FilesRevokePublicURLArguments {
/** File ID to revoke public sharing for */
file: string;
}Usage Examples:
// Enable public sharing
const publicURL = await web.files.sharedPublicURL({
file: 'F1234567890'
});
console.log('Public URL:', publicURL.file.permalink_public);
// Revoke public sharing
await web.files.revokePublicURL({
file: 'F1234567890'
});
console.log('Public sharing revoked');Legacy file upload method (use uploadV2 for new applications).
/**
* Upload a file (legacy method - use uploadV2 instead)
* @param options - Upload parameters
* @returns Promise resolving to upload result
*/
files.upload(options: FilesUploadArguments): Promise<FilesUploadResponse>;
interface FilesUploadArguments {
/** File contents as string, Buffer, or Stream */
file?: string | Buffer | NodeJS.ReadableStream;
/** File contents (alternative to file parameter) */
content?: string;
/** Filename of file */
filename?: string;
/** Title of file */
title?: string;
/** Initial comment to add to file */
initial_comment?: string;
/** Comma-separated list of channel names or IDs */
channels?: string;
/** A file type identifier */
filetype?: string;
/** Syntax type of the snippet being uploaded */
snippet_type?: string;
/** Thread timestamp to upload to a thread */
thread_ts?: string;
}Usage Examples:
// Legacy upload (prefer uploadV2)
const legacyUpload = await web.files.upload({
channels: '#general',
content: 'Hello, world!',
filename: 'hello.txt',
title: 'Greeting File'
});
console.log('Legacy upload result:', legacyUpload.file.id);Manage comments on files.
/**
* Delete a comment on a file
* @param options - Delete comment parameters
* @returns Promise resolving to deletion result
*/
files.comments.delete(options: FilesCommentsDeleteArguments): Promise<FilesCommentsDeleteResponse>;
interface FilesCommentsDeleteArguments {
/** File to delete comment from */
file: string;
/** ID of the comment to delete */
id: string;
}Usage Examples:
// Delete a file comment
await web.files.comments.delete({
file: 'F1234567890',
id: 'Fc1234567890'
});
console.log('Comment deleted');Manage external files stored outside of Slack.
/**
* Add a remote file
* @param options - Add remote file parameters
* @returns Promise resolving to remote file details
*/
files.remote.add(options: FilesRemoteAddArguments): Promise<FilesRemoteAddResponse>;
/**
* Get information about a remote file
* @param options - Remote file info parameters
* @returns Promise resolving to remote file details
*/
files.remote.info(options: FilesRemoteInfoArguments): Promise<FilesRemoteInfoResponse>;
/**
* Remove a remote file
* @param options - Remove parameters
* @returns Promise resolving to removal confirmation
*/
files.remote.remove(options: FilesRemoteRemoveArguments): Promise<FilesRemoteRemoveResponse>;
interface FilesRemoteAddArguments {
/** Creator defined GUID for the file */
external_id: string;
/** URL of the remote file */
external_url: string;
/** Title of the file */
title: string;
/** Type of file */
filetype?: string;
/** File size in bytes */
indexable_file_contents?: string;
/** Preview of the document */
preview_image?: string;
}Usage Examples:
// Add remote file
const remoteFile = await web.files.remote.add({
external_id: 'gdrive-doc-123',
external_url: 'https://docs.google.com/document/d/abc123',
title: 'Project Specification',
filetype: 'gdoc'
});
// Get remote file info
const remoteInfo = await web.files.remote.info({
file: remoteFile.file.id
});
// Remove remote file
await web.files.remote.remove({
file: remoteFile.file.id
});interface FilesCompleteUploadExternalResponse {
id: string;
created: number;
timestamp: number;
name: string;
title: string;
mimetype: string;
filetype: string;
pretty_type: string;
user: string;
size: number;
mode: string;
is_external: boolean;
external_type: string;
is_public: boolean;
public_url_shared: boolean;
display_as_bot: boolean;
username: string;
url_private: string;
url_private_download: string;
permalink: string;
permalink_public?: string;
thumb_64?: string;
thumb_80?: string;
thumb_360?: string;
thumb_360_w?: number;
thumb_360_h?: number;
thumb_480?: string;
thumb_480_w?: number;
thumb_480_h?: number;
thumb_160?: string;
thumb_720?: string;
thumb_720_w?: number;
thumb_720_h?: number;
thumb_800?: string;
thumb_800_w?: number;
thumb_800_h?: number;
thumb_960?: string;
thumb_960_w?: number;
thumb_960_h?: number;
thumb_1024?: string;
thumb_1024_w?: number;
thumb_1024_h?: number;
original_w?: number;
original_h?: number;
thumb_tiny?: string;
}
interface FilesInfoResponse extends WebAPICallResult {
file: {
id: string;
created: number;
timestamp: number;
name: string;
title: string;
mimetype: string;
filetype: string;
pretty_type: string;
user: string;
size: number;
url_private: string;
url_private_download: string;
permalink: string;
permalink_public?: string;
channels: string[];
groups: string[];
ims: string[];
comments_count?: number;
};
comments?: FileComment[];
paging?: {
count: number;
total: number;
page: number;
pages: number;
};
}
interface FileComment {
id: string;
created: number;
timestamp: number;
user: string;
comment: string;
}
interface FilesListResponse extends WebAPICallResult {
files: FilesInfoResponse['file'][];
paging: {
count: number;
total: number;
page: number;
pages: number;
};
}Install with Tessl CLI
npx tessl i tessl/npm-slack--web-api