Skip to content

feat(discord): clear approval buttons after decision#768

Merged
Aaronontheweb merged 4 commits intodevfrom
claude-wt-discord-approval-blocks
Apr 27, 2026
Merged

feat(discord): clear approval buttons after decision#768
Aaronontheweb merged 4 commits intodevfrom
claude-wt-discord-approval-blocks

Conversation

@Aaronontheweb
Copy link
Copy Markdown
Collaborator

Summary

  • Update Discord approval prompt messages in-place after a user clicks an approval button or types a text response (A/B/C/D), matching Slack's existing behavior
  • Add UpdateMessageAsync to IDiscordReplyClient using Discord.Net's ModifyMessageAsync API
  • Capture sent message ID from SendMessageAsync and track it in PendingApprovalRequest so the original prompt can be edited on resolution
  • Replace buttons with a resolved status showing tool name, action, decision, and who approved

Test plan

  • dotnet build — 0 warnings, 0 errors
  • dotnet test --filter "FullyQualifiedName~Discord" — 121 tests pass
  • dotnet test --filter "FullyQualifiedName~SessionBindingContract" — 48 contract tests pass (both Slack and Discord)
  • Manual test in Docker container: trigger tool approval, click button, verify original message updates with resolved status and buttons removed
  • Manual test: verify text-based approval ("A", "B", "C", "D") also updates the original message

…ng Slack behavior

Discord approval buttons remained active after clicking — unlike Slack, which
replaces the original message with a resolved status. Root cause was three gaps:
PostReplyAsync didn't return the sent message ID, PendingApprovalRequest didn't
store it, and IDiscordReplyClient had no message-update method.

Changes:
- Add MessageId to DiscordPostResult; capture from SendMessageAsync return
- Add UpdateMessageAsync to IDiscordReplyClient using ModifyMessageAsync
- Restructure PendingApprovalRequest to store ToolInteractionRequest + PromptMessageId
- Add BuildResolvedPromptText for Discord-markdown resolved status rendering
- Replace SafeReplyAsync(BuildDecisionStatus) with TryResolveApprovalPromptAsync
  in both button and text approval handlers
…ply client

- Extract ResolveMessageChannelAsync in DiscordNetReplyClient to deduplicate
  the socket-cache + REST-fallback channel resolution between PostReplyAsync
  and UpdateMessageAsync
- Cache empty MessageComponent as a static field instead of allocating per call
- Extract AppendToolSummary in DiscordApprovalPromptBuilder to deduplicate
  tool/action/pattern rendering between BuildButtonPrompt and BuildResolvedPromptText
- Fix redundant null-conditional on promptMessageId in catch block
@Aaronontheweb Aaronontheweb marked this pull request as ready for review April 27, 2026 16:28
@Aaronontheweb Aaronontheweb added remote-access Network exposure, device pairing, tunnels, webhooks, and remote ingress channels Discord, Slack, and other channels. and removed remote-access Network exposure, device pairing, tunnels, webhooks, and remote ingress labels Apr 27, 2026
@Aaronontheweb Aaronontheweb merged commit 8efadaa into dev Apr 27, 2026
4 of 6 checks passed
@Aaronontheweb Aaronontheweb deleted the claude-wt-discord-approval-blocks branch April 27, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channels Discord, Slack, and other channels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant