Working with files can feel like a free-for-all, but we're here to help! Think of files as just messages with extra information included.
Since files can represent complex information, an app that uses files well can communicate more succinctly and precisely. We'll explore the two ways to work with files and their distinct differences below.
Uploading files to Slack allows you to:
This is the easiest way to use files in Slack!
Adding remote files allows you to:
When you upload a file to Slack, Slack becomes the host for your file, taking charge of its safe storage. Uploading files is by far the easiest way to use files in Slack.
In order to upload a file to Slack, there are a couple of scopes your app should have. There are also some events you may want your app to subscribe to.
Under the Apps page of your app, choose the OAuth & Permissions sidebar to select scopes.
files:read
allows access to, well, methods that read files. That's files.info
and files.list
.files:write
allows your app to upload files. It also allows your app to remove files that your app has control over.If you'd like to do your work as a user instead, request the files:write:user
scope to upload files on behalf of your users.
A bevy of events inform your app about file happenings in your workspace. To subscribe to any file events, use the Event Subscriptions tab under your Apps page. Here's a list of file events:
file_change
: A file was changed.file_created
: A file was created.file_deleted
: A file was deleted.file_public
: A file was made public.file_shared
: A file was shared.file_unshared
: A file was unshared.With your app set up, read on to learn how to upload files.
When a user uploads a file, Slack will scan the file for malware or other suspicious bits before making it available. This means the bigger the file, the longer it might take before your uploaded file is available. As such, we've broken down the uploading process into three steps:
files.getUploadURLExternal
. The response will contain a URL that you can POST the contents of your file to.files.completeUploadExternal
. You can optionally specify a sharing destination for your file or files using this API's arguments. This finalizes the file upload started in step 1.As always, life is easier with a Slack SDK. Use your programming language of choice, and get file uploading as primitive building blocks that you don't have to think about. In particular, there are helpful uploadV2
methods available in our node.js, Python, and Java SDKs that wrap the above ceremony into a single convenient method. You can also use the Slack file object
to host files in Slack using Block Kit. Refer to Slack file object for more details.
If you've got the necessary scopes, your file should appear in the channels specified.
Here's a potentially confusing bit when you use the channel_id
parameter during your upload: supplying channel_id
will "share" the file to a channel. If you don't use the channel_id
parameter, this only "uploads" the file — hosting the file in Slack — but doesn't "share" the file anywhere. Crucially, only the uploader will have access to the file if it is not shared anywhere.
Either way, once your upload succeeds, you'll see an HTTP response from Slack containing an "ok": true
field, plus a files
array containing file
objects. For more detail on file objects and the fields contained inside, taking a look at the file object documentation is highly recommended.
Slack provides some other methods for working with files:
files.delete
: Delete a file.files.info
: Get information on a file.files.list
: List visible files.files.revokePublicURL
: Disable a file for public sharing.files.sharedPublicURL
: Enable a file for public sharing.Slack also sends events when files are uploaded or changed in your workspace. Here are some of the relevant events:
file_change
: A file was changed.file_created
: A file was created.file_deleted
: A file was deleted.file_public
: A file was made public.file_shared
: A file was shared.file_unshared
: A file was unshared.If, however, you wish to flex your file skills by sharing files hosted outside of Slack, providing custom unfurls, or fine-tuning the way your files appear in Slack searches: continue reading for guidance on remote files.
Remote files are files not hosted inside Slack. Think of a remote file as a pointer, a forwarding address, or a reference to a file that lives elsewhere.
For most apps, uploading files directly to Slack is preferred over adding remote files. Adding remote files involves extra steps that may not be necessary for your use case.
There are a few benefits to adding and sharing remote files to Slack:
indexable content
. That way, you can ensure your file appears when users search for certain terms.Note on terminology
Remote files are "added" to Slack, not "uploaded." Adding a remote file to Slack makes Slack aware of its existence. Once that's done, "sharing" a remote file, like sharing a direct upload file, brings the file into a conversation. So a remote file must be "added" before it is "shared".
You can add, update, remove, share, and unfurl remote files in Slack.
In order to add a remote file to Slack, there are a couple of scopes your app should have. There are also some events you may want your app to subscribe to.
Working with remote files requires a distinct set of scopes from those involved in direct upload. Again, under the Apps page of your app, choose the OAuth & Permissions sidebar to select scopes.
remote_files:read
allows your app to read information about remote files visible to the user associated with your user token.remote_files:share
allows your app to share remote files visible to the user associated with your user token.remote_files:write
allows your app to add, edit, or delete remote files on a user's behalf.chat:write
allows your app to post messages in approved channels & conversations. This is especially useful for an app that provides a custom unfurl for remote files.links:read
allows your app to view and subscribe to events about links that have been shared in conversation. Again, this is useful for knowing when a link to your remote file has been shared, so that you can unfurl it.links:write
allows your app to unfurl links (like to remote files) using the chat.unfurl
method.Once you've obtained the necessary scopes, you can add, update, remove, share, and unfurl remote files in Slack.
To subscribe to any file events, use the Event Subscriptions tab under your Apps page. One event that can be especially useful to apps that work with remote files is the link_shared
event, which notifies your app when a link has been shared so that you can unfurl it. Add any App Unfurl Domains that relate to your file service under that same tab in the Apps page.
Once you've obtained the necessary scopes and subscribed to any desired events, you can add, update, remove, share, and unfurl remote files in Slack.
To add a remote file, use the files.remote.add
method from the Web API.
Remote files exist across the whole workspace (or organization, for Enterprise Grid).
Here's a sample call:
curl -F token=<token> \
-F external_id=ABCD1 \
-F external_url=https://mydocuments.com/document/d/1TA9fIaph4eSz2fC_1JGMuYaYUc4IvieIop0WqfCXw5Y/edit?usp=sharing \
-F title=LeadvilleAndBackAgain \
-F preview_image=@cycling.jpg \
-F indexable_file_contents=search_terms.txt
https://slack.com/api/files.remote.add
Pay particular attention to the preview_image
parameter. preview_image
should be a binary image file, and it will be stored in Slack. That's going to allow a more beautiful unfurl in the next step, when the app actually shares the remote file.
indexable_file_contents
also deserves a mention. Use this parameter to specify a file containing the search terms that correspond to this remote file. When a user searches in Slack, their query will be compared against the contents of this text file for matching.
Think of this text file like the alt
parameter on an HTML <img>
tag — a textual representation of a non-textual object. The text file can contain a description of the remote file, or it can contain search keywords, or anything else text-based.
Once your upload succeeds, you'll see an HTTP response from Slack containing an "ok": true
field, plus a file
object. For more detail on file objects and the fields contained inside, a look at the file object documentation is highly recommended.
You'll see the external_id
returned to you on the file
object in the Slack response, as well as a file_id
. Either of these ids can be stored and used to query the files.remote.info
method to access other information about the file.
Adding is nice, but sharing is caring.
In other words, adding a remote file does not, by itself, share the file to a conversation. Without sharing the file, it remains an orphan inside Slack—you can view information on it via files.remote.info
method, but it won't actually be visible anywhere. Let's make it visible with a call to the files.remote.share
method.
curl -F token=<token> \
-F external_id=ABCD1 \
-F channels=C12345 \
https://slack.com/api/files.remote.share
Now we get a lovely message in channel that shows off the remote file as it should be seen.
Now we have a custom preview_image
, which we specified during the add
step, instead of the ugly raw URL and a small picture of text.
A word about tokens: the files.remote.share
method may be called with either a bot or a user token. The bot token shares the file from your app, while the user token shares the file from the user associated with your user token. Use the bot token to share to channels that the bot has access to; use the user token to share to channels that the user has access to.
We've already mentioned how to add a custom preview_image
that makes our remote files appear nicer when they're shared. But what about when someone else shares our remote file as a link?
The first step to providing lush unfurls is to be armed with the link_shared
event.
When that link_shared
event fires, we receive its payload, including the message_ts
of the message that triggered it, as well as the channel
of that message. Now we can make an HTTP request to chat.unfurl. First, let's set up our unfurls
object using a block:
unfurls: {
'https://mydocuments.com/document/d/1TA9fIaph4eSz2fC_1JGMuYaYUc4IvieIop0WqfCXw5Y/edit?usp=sharing': {
hide_color: true,
blocks: [{
type: 'file',
external_id: 'ABCD1',
source: 'remote',
}]
}
}
For use specifically with a file unfurl, you can set the hide_color
field to true
to remove the color bar from a message. This property works only with a file block; if this property is included along with other blocks (for example, a section block), the chat.unfurl
method will throw an error.
Next, we call chat.unfurl
with the channel
from the link_shared
event, and set the ts
equal to the message_ts
from the event:
curl -F token=<user_token> \
-F ts=123456789.9875 \
-F unfurls=<unfurls json from above> \
-F channel=C12345 \
-F user_auth_required=false \
https://slack.com/api/chat.unfurl
Check out the chat.unfurl
method documentation for more detail on how to use that method to its fullest potential.
Your remote file's contents may change. When that happens, call the files.remote.update
method to update your remote file:
curl -F token=<token> \
-F tile=ACyclistTale \
-F external_id=ABCD1 \
https://slack.com/api/files.remote.update
You cannot update the external_id
or file_id
of a remote file. If you need to change those fields, your best bet is to remove and then add the file.
One other piece of pleasant news: adding a remote file is actually an "upsert" operation, meaning that if you add a file that has been added before, the existing file will be updated.
Removing a remote file follows the same pattern as adding and updating. Use the files.remote.remove
method to remove a remote file from Slack.
This method does not delete the remote file from where it's externally hosted; it only removes the remote file from Slack.
curl -F token=<bot_token> \
-F external_id=ABCD1 \
https://slack.com/api/files.remote.remove
After removal, any place that used to display the file will show a tombstone message containing the text "This file was deleted." instead.