Skip to content

Slack: authenticate as a real member with a user token - #22

Merged
TroyHernandez merged 3 commits into
cornball-ai:mainfrom
user9208212:slack-user-token
Sep 8, 2026
Merged

TroyHernandez merged 3 commits into
cornball-ai:mainfrom
user9208212:slack-user-token

Conversation

@user9208212

Copy link
Copy Markdown
Contributor

Summary

  • chat_slack()'s token is a bot token, and chat_send()'s identity/username only relabel that bot's own post with a cosmetic name and icon (needs chat:write.customize) — there was no way to actually authenticate as a real workspace member.
  • Adds an optional user_token (xoxp-...) to chat_slack(), and an as_user = TRUE flag on chat_send()/chat_whoami() that authenticates with it instead of the bot token — a send then shows the member's real name and photo in Slack, confirmed via auth.test.
  • Confined entirely to the Slack adapter (R/slack.R) — no changes to contract.R or any other adapter. identity/username and as_user are separate mechanisms and can't be combined meaningfully (a user-token send carries no bot identity to relabel, so username/icon_emoji are simply not sent on that path).
  • chat_capabilities()$user_identity reports whether a given client instance was configured with a user token — flagged in review as a deliberate departure from every other capability flag here (per-instance rather than static-per-adapter), since there's no construction-time failure to fail with the way a missing bot token already has.

Raised with Troy first; this PR follows his go-ahead.

Test plan

  • tinytest::test_package("chat.api", pattern = "slack") — all 134 tests pass (100 pre-existing + 34 new, covering constructor storage, as_user send routing, missing-token errors, dual chat_whoami() caching, and the capability flag)
  • Confirmed the pre-existing test_matrix_mxclient.R failures on this box are present on unmodified main too (local mx.client version mismatch, unrelated to this change)
  • tinyrox::document() regenerates chat_slack.Rd correctly once merged (the local run also picked up an unrelated, pre-existing tinyrox-version formatting change across ~24 other man pages; excluded from this diff to keep it focused — happy to open that separately if wanted)

🤖 Generated with Claude Code

https://claude.ai/code/session_01F1QZ4ESCCu2V94jus4rzM3

user9208212 and others added 3 commits September 8, 2026 13:19
chat_slack()'s token is a bot token, and chat_send()'s identity/
username only relabel that bot's own post with a cosmetic name and
icon -- there was no way to actually post or resolve identity as a
real workspace member.

Add an optional user_token (xoxp-...) to chat_slack(), and an
as_user = TRUE flag on chat_send()/chat_whoami() that authenticates
with it instead of the bot token, so a send shows the member's real
name and photo. Confined to the Slack adapter; identity/username and
as_user are separate mechanisms and chat_capabilities()$user_identity
reports whether a given client is configured for the latter.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F1QZ4ESCCu2V94jus4rzM3
- Send username and icon_emoji as empty strings on the as_user path
  too. Omitted, slackr fills them from SLACK_USERNAME and
  SLACK_ICON_EMOJI, which is exactly what the bot path suppresses.
- Every adapter answers user_identity, FALSE outside Slack, and the
  contract loop checks it: a consumer reading NULL cannot tell an
  adapter with no such thing from a client not given a token. The
  flag is documented on chat_capabilities().
- Note in chat_slack()'s docs that an as_user post is the member's own
  message to this client's poll as well, since Slack carries no self.
- Regenerate man pages with the repo's tinyrox.
@TroyHernandez TroyHernandez reopened this Sep 8, 2026
@TroyHernandez
TroyHernandez merged commit b99e179 into cornball-ai:main Sep 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants