Channel files
Organize and manage files within channels using directories and file metadata.
What are channel files?
Each text channel has a built-in file system where members can upload and organize files. The file system consists of two entities:
- Directories: Folders that organize files hierarchically within a channel
- Files: Uploaded content with metadata like name, size, and MIME type
Directories
A directory is a named folder within a channel. Directories can be nested inside other directories to create a hierarchical structure.
// ChannelDirectory structure
{
id: DirectoryGuid,
parentDirectoryId?: DirectoryGuid, // undefined = root level
name: string
}
When parentDirectoryId is undefined, the directory sits at the channel's root level. Otherwise, it's nested inside the specified parent directory.
Files
A file represents uploaded content stored in a directory. Files are created by first uploading content through the asset system, then registering the file in a directory.
// ChannelFile structure
{
id: FileGuid,
directoryId: DirectoryGuid,
channelId: ChannelGuid,
name: string,
length: bigint,
mimeType: string,
assetId: AssetGuid,
sha256: Uint8Array,
modifiedAt?: Date
}
The assetId links to the actual content in the asset system. Use the asset URI to download or display the file content.
How channel files work
Understanding the file creation process and directory structure helps you build file management features.
Creating files
File creation is a two-step process:
- Upload the content: Use
rootClient.assets.fileUpload()from your client code to upload the file and receive an upload token - Register the file: Call
assetClient.create()to convert the upload token to a permanent asset, then callChannelFileClient.create()to create the file entry
// Step 1: Client uploads file and gets upload token
// (handled by rootClient.assets.fileUpload in your client code)
// Step 2: Convert token to permanent asset (server)
const assets = await assetClient.create({
tokens: [uploadToken]
});
// Step 3: Register in directory (server)
const file = await rootServer.community.channelFiles.create({
channelId: channelId,
directoryId: directoryId,
uploadTokenUri: uploadToken
});
Directory hierarchy
Directories form a tree structure within each channel. To build a complete view of the file system:
- Call
list()to get all directories in the channel - Use
parentDirectoryIdto reconstruct the hierarchy - Call
ChannelFileClient.list()for each directory to get its files
// Get all directories in a channel
const directories = await rootServer.community.channelDirectories.list({
channelId: channelId
});
// Get files in a specific directory
const files = await rootServer.community.channelFiles.list({
channelId: channelId,
directoryId: directoryId
});
Moving files and directories
Both files and directories can be moved between directories. When moving a directory, all its contents (files and subdirectories) move with it.
Moving requires specifying both the old and new parent:
// Move a directory
await rootServer.community.channelDirectories.move({
channelId: channelId,
id: directoryId,
oldParentDirectoryId: currentParent,
newParentDirectoryId: targetParent
});
// Move a file
await rootServer.community.channelFiles.move({
channelId: channelId,
id: fileId,
oldDirectoryId: currentDirectory,
newDirectoryId: targetDirectory
});
Searching files
Two search methods help users find files:
| Method | Scope | Use case |
|---|---|---|
search | Single channel | Find files within the current channel |
searchCommunity | Multiple channels | Find files across the community |
Both methods perform a case-insensitive substring match on file names. Wildcards and regular expressions are not supported.
// Search within a channel
const results = await rootServer.community.channelFiles.search({
channelId: channelId,
search: 'report'
});
// Search across multiple channels
const communityResults = await rootServer.community.channelFiles.searchCommunity({
channelIds: [channel1, channel2, channel3],
search: 'report'
});
Search pagination
Single-channel search uses cursor-based pagination. Each request returns up to 10 matching files. To retrieve additional results, pass the id of the last file as lastFileId:
// First page
const page1 = await rootServer.community.channelFiles.search({
channelId: channelId,
search: 'report'
});
// Get next page using last file's ID
if (page1.length === 10) {
const lastFile = page1[page1.length - 1];
const page2 = await rootServer.community.channelFiles.search({
channelId: channelId,
search: 'report',
lastFileId: lastFile.id
});
}
Community-wide search does not support pagination. It returns up to 10 matching files per channel, along with a totalCount indicating the total matches in each channel.
Deleting directories
When you delete a directory, all files and subdirectories within it are also deleted. This is a cascading delete with no recovery. To preserve files, move them to another directory before deleting.
When to use channel files
- Document libraries: Create organized folders for team documents, with subdirectories for different projects or topics
- Media galleries: Build image or video collections with categorized folders
- File search: Help users find content across channels using the search APIs
- Automated file management: Move files to archive directories based on age or clean up unused directories
- Content indexing: Monitor file events to build search indexes or trigger processing workflows