Receive files via Slack
Task
Accept files attached to Slack messages so the agent can read, analyze, or process them.
Result
Users attach a file in a thread or DM, @mention the bot (or post in a channel where the bot responds), and the agent sees an <attachments> block. The agent calls tools like vision_analyze or read_file to work with the file.
Prereqs
- A working Slack bot connected to Ethos (see the Slack platform guide).
- At least one personality with
vision_analyzeorread_filein itstoolset.yaml.
Steps
1. Verify the files:read scope
The Slack adapter needs the files:read bot token scope to download files from messages. If you created your app from the manifest in the Slack adapter quickstart, this scope is already included. If you are upgrading from a pre-attachment build, add the scope:
- Open the Slack API dashboard.
- Select your app.
- Go to OAuth & Permissions > Scopes > Bot Token Scopes.
- Add
files:read. - Reinstall to Workspace to apply the new scope.
Without files:read, Slack does not return the file bytes from url_private_download. It returns its HTML "loading" page instead with HTTP 200, so the adapter cannot tell the request failed: it caches the HTML under the original filename. The first tool that opens the attachment (vision_analyze, read_file) then rejects the bytes as not a valid image, PDF, or text file, and the agent surfaces a confusing error about the file format. Add the scope and the symptom disappears.
2. Verify the personality has attachment-capable tools
Check your personality's toolset.yaml:
# ~/.ethos/personalities/<id>/toolset.yaml
- read_file # reads attached documents via ref argument
- vision_analyze # analyzes attached images via ref argument
Without these tools (or custom tools declaring capabilities.attachments), the agent sees the <attachments> block but cannot open the files.
3. Send a file and observe
- Open a DM with the bot, or go to a channel where the bot is active.
- Attach a file (click the
+button or drag and drop). - Add a message like "Summarize this document" or send the file without text.
- @mention the bot if the channel mode requires it.
- The agent sees the attachment metadata and calls the appropriate tool.
When no text accompanies the file, the adapter surfaces (file attachment) as the message text so the agent has context.
Verify
- The bot replies referencing the file's contents (not just the filename).
- The agent's response includes output from the attachment-aware tool (
vision_analyzefor images,read_filefor documents). - No "file format" error appears in the reply (a format error indicates the
files:readscope is missing — see Troubleshoot).
Supported types
| Category | Extensions | Attachment type |
|---|---|---|
| Images | jpg, jpeg, png, gif, webp, heic, bmp, svg, tiff | image |
| Documents | pdf, txt, csv, json, yaml, md, and all other non-skipped extensions | file |
Not supported yet
Audio (mp3, wav, ogg, flac, aac, m4a) and video (mp4, mov, webm, avi, mkv) files are intentionally skipped. These types are deferred until transcription and media analysis tools ship.
Limits
- Size cap: 25 MB per file. Files exceeding this limit are silently skipped.
- Required scope:
files:read. Without this scope, the adapter cannot fetch file bytes from Slack's API. - No additional bot permissions needed. The standard scopes from the app manifest are sufficient.
How it works
- User attaches a file to a message and @mentions the bot (or the channel mode allows the message through).
- Slack delivers the message as a
file_sharesubtype with afilesarray. - The adapter classifies each file by extension: image extensions become
type: 'image', everything else becomestype: 'file', and audio/video extensions are skipped. - The adapter fetches each file from
url_private_downloadwith the bot token in theAuthorizationheader. - The file is written to the
AttachmentCacheat~/.ethos/cache/attachments/. - The
InboundMessagecarries anattachmentsarray withtype,ref,url(afile://path),mimeType, and optionalfilenameandsizeBytes. buildAttachmentAnnotation()prepends an<attachments>XML block to the user's text.- The LLM sees the block and can call
vision_analyzeorread_filewith therefargument (e.g.ref: "att-0").
Troubleshoot
Agent ignores the attached file. -- Check that the personality's toolset.yaml includes vision_analyze (for images) or read_file (for documents). Without attachment-capable tools, the agent cannot open the file.
Agent says the file is not a valid image / PDF / text file even though Slack shows it as one. -- The files:read scope is missing. Slack returns an HTML page in place of the file bytes and the adapter caches it. Verify the scope under OAuth & Permissions in the Slack app dashboard, add it if absent, and Reinstall to Workspace to mint a fresh bot token. Update slack.apps.<n>.botToken in ~/.ethos/config.yaml with the new xoxb-…. To confirm the cache contains HTML rather than image bytes, run file ~/.ethos/cache/attachments/<session-hash>/<message-hash>/<filename> — the line will read HTML document text instead of PNG image data / JPEG image data / PDF document.
Bot does not respond to file-only messages. -- Check the channel mode. In mention_only mode (the default), you must @mention the bot even when attaching a file. DMs always respond regardless of mode.
"(file attachment)" appears but no tool call. -- The agent sees the attachment metadata but has no tool to process it. Add read_file or vision_analyze to the personality's toolset.