← Back to PRs

#9166: Fix: Use userToken for Slack file downloads

by vishaltandale00 open 2026-02-04 23:28 View on GitHub →
channel: slack stale
## Summary Fixes #9153 - Slack file downloads now correctly use `userToken` for authentication when configured, instead of always using `botToken`. ## Problem When users configured both `botToken` and `userToken`, OpenClaw always used `botToken` for file downloads, which lacks the necessary permissions in many Slack workspaces. This resulted in: - HTML login pages saved instead of actual files - Downloaded files in `media/inbound/` were corrupted - Users had to manually download files using the `userToken` as a workaround ## Root Cause The `resolveSlackMedia()` function in `prepareSlackMessage()` always passed `ctx.botToken` for file downloads, even when `userToken` was configured. The `userToken` was defined in the config but never propagated to the message handler. ## Solution This PR implements a 3-step fix: ### 1. Add `userToken` to SlackMonitorContext **File:** `src/slack/monitor/context.ts` - Added optional `userToken?: string` field to `SlackMonitorContext` type - Added `userToken` parameter to `createSlackMonitorContext()` function - Included `userToken` in the returned context object ### 2. Pass `userToken` from config **File:** `src/slack/monitor/provider.ts` - Pass `slackCfg.userToken?.trim()` when creating the monitor context - This ensures the userToken from config reaches the context ### 3. Use `userToken` for file downloads **File:** `src/slack/monitor/message-handler/prepare.ts` - Changed `resolveSlackMedia()` call from `token: ctx.botToken` to `token: ctx.userToken || ctx.botToken` - Uses `userToken` when available, falls back to `botToken` if not configured ## Why This Works - **userToken**: Has broader file access permissions (user-level scope) - **botToken**: Has limited file access (bot-level scope) - **Fallback**: Maintains backward compatibility for configs without userToken ## Impact ✅ **Fixes authentication** for Slack file downloads when userToken is configured ✅ **Backward compatible** - falls back to botToken if userToken not set ✅ **Minimal changes** - surgical 3-file fix affecting only file download flow ✅ **No breaking changes** - existing configurations continue working ## Testing - ✅ Code follows existing patterns (`resolveToken` logic already used elsewhere) - ✅ Properly handles optional `userToken` field - ✅ Maintains existing behavior when userToken is not configured 🤖 Implemented by agent-af5f50c9d7c7 <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR threads an optional Slack `userToken` through the Slack monitor context (context.ts, provider.ts) and prefers it over `botToken` when downloading attachments for inbound messages (prepare.ts), fixing cases where bot tokens lack file access. One attachment path is still using the bot token: when handling a thread reply where the current message has no files but the thread-starter message has files, the code hydrates the starter attachments using the bot token only. That scenario will continue to fail in the same workspaces this PR aims to fix, so it should be updated to use the same user-token-first fallback. <h3>Confidence Score: 4/5</h3> - Mostly safe to merge, but one remaining token path can still break Slack attachment downloads in a common thread scenario. - Changes are small and localized, but the thread-starter attachment hydration path still uses botToken, which contradicts the PR’s stated fix and will cause real download failures for some configurations. - src/slack/monitor/message-handler/prepare.ts <!-- greptile_other_comments_section --> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs