#21147: feat(slack): support chat:write.customize for custom bot name/avatar
channel: slack
size: S
Cluster:
Slack Integration Enhancements
## Summary
Closes #21133
When `ui.assistant.name` is configured and the bot token includes the `chat:write.customize` scope, OpenClaw now passes `username` and `icon_emoji` (or `icon_url`) to `chat.postMessage` so the bot appears in Slack with the configured assistant identity instead of the default app name.
## Changes
### `src/slack/monitor/replies.ts`
- Added optional `identity?: SlackSendIdentity` parameter to `deliverReplies`
- Forwarded it to both `sendMessageSlack` call sites (text and media paths)
### `src/slack/monitor/message-handler/dispatch.ts`
- Added `buildSlackCustomIdentity(cfg, agentId)` helper that reads `ui.assistant.name` / `ui.assistant.avatar` (with per-agent identity fallback via `resolveAgentIdentity`)
- Resolves identity once at start of `dispatchPreparedSlackMessage` and passes it through `deliverNormally` and the inline `deliverReplies` call
- The lower-level `send.ts` already had `chat:write.customize` scope-error fallback (retries without custom identity if scope is absent)
### `skills/slack/SKILL.md`
- Added new **Custom bot name and avatar (`chat:write.customize`)** section
- Documents what it does, how to add the scope in api.slack.com, and how to configure `ui.assistant.name` / `ui.assistant.avatar` in openclaw.json
## Behavior
- **When `ui.assistant.name` is set**: Slack messages from the bot show the configured name and `:robot_face:` emoji (or `icon_url` if avatar is an `https://` URL)
- **When scope is absent**: Message is silently retried without custom identity — no error, no breakage
- **When no name is configured**: Identity customization is skipped entirely
## Testing
- No name configured → identity is `undefined` → `sendMessageSlack` called without identity → no change in behavior ✅
- Name configured, scope present → `username` + `icon_emoji`/`icon_url` sent ✅
- Name configured, scope absent → Slack returns `missing_scope` → `isSlackCustomizeScopeError` detects it → retry without identity → message delivered ✅
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds support for `chat:write.customize` scope to customize bot name and avatar in Slack messages. When `ui.assistant.name` is configured, the bot posts with custom identity (name + emoji/avatar) instead of default app name. Implementation includes graceful fallback when scope is missing - messages retry without custom identity on scope errors.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- Clean implementation with proper error handling, graceful fallback for missing scope, backward compatibility, clear documentation, and follows existing patterns in the codebase
- No files require special attention
<sub>Last reviewed commit: e203f73</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#9985: feat(slack): add channel-aware context for AI Assistant threads
by natedenh · 2026-02-05
79.3%
#7404: feat(slack): add Socket Mode bot + auto-join + bridge scaffolding; ad…
by zprager · 2026-02-02
77.8%
#9671: feat(slack): add AI Assistant loading states support
by natedenh · 2026-02-05
77.6%
#9954: feat(slack): add Agents & AI Apps (assistant) support
by natedenh · 2026-02-05
76.4%
#20047: fix(googlechat): typing indicator shows 'OpenClaw' instead of agent...
by xinhuagu · 2026-02-18
76.3%
#23268: feat(slack): Add App Home tab support
by slurpyone · 2026-02-22
76.2%
#8318: feat(webchat): Add configurable user display name
by vishaltandale00 · 2026-02-03
76.1%
#8024: fix(slack): resolve channel names via directory for cross-account m...
by emma-digital-assistant · 2026-02-03
76.1%
#21029: Feature/telegram bot avatar clean
by aleonnet · 2026-02-19
76.0%
#7656: docs(slack): improve skill documentation with thread support and AP...
by pswpswpsw · 2026-02-03
75.3%