Skip to content

Feature/context commands - #404

Merged
Pierre-Demessence merged 10 commits into
masterfrom
feature/context-commands
Sep 15, 2026
Merged

Pierre-Demessence merged 10 commits into
masterfrom
feature/context-commands

Conversation

@Pierre-Demessence

Copy link
Copy Markdown
Member

No description provided.

…ntext command

- /bday show now takes an optional user to show that member's birthday

- remove the standalone /bday user slash command

- add a View Birthday user context-menu command (ephemeral)
- extract shared duel logic into StartDuel so both entry points reuse it

- context menu always starts a non-mute duel (no silent 5-minute timeout)
…mounts

- add a Gift Tokens user context command that prompts for the amount via a modal

- share gift validation between the slash command and the modal path

- SECURITY: reject amount <= 0. TransferTokens reversed the transfer direction on a negative amount, so /casino tokens gift <user> -100 drained the target's tokens.
…ext command

- /profile takes an optional user and defaults to the caller

- View Profile is an ephemeral user context-menu command

- card is removed after 3 minutes and the failure message after 10 seconds, matching the legacy !profile behaviour
Copilot AI lite review requested due to automatic review settings September 14, 2026 00:38
@github-actions

Copy link
Copy Markdown

🚀 Deploy this PR

Code-only changes

  1. Make sure the udc-bot-dev ArgoCD app target revision is set to master.
  2. Go to the Deploy to Dev workflow and click Run workflow with this PR number.

Manifest changes (e.g. new services in k8s/dev/)

  1. Comment /build on this PR to build the Docker image (without deploying to master).
  2. Once the build succeeds, update the image tag in k8s/dev/bot.yaml on your branch with the SHA from the build comment, then push.
  3. In ArgoCD, switch the udc-bot-dev app target revision from master to your branch (App Details → Source → Edit → Save).
  4. ArgoCD will sync your manifest changes + new image. Test your changes.
  5. When done, switch ArgoCD target revision back to master.

Comment on lines +43 to +47
catch (Exception e)
{
await LoggingService.LogAction($"Error while generating profile card for {user.Username}.\nEx:{e}",
ExtendedLogSeverity.LowWarning);
}

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There is at least one confirmed interaction-flow bug (deferred interaction can fail without a follow-up on exception) that can leave users with a stuck/failed command execution.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds Discord user context-menu commands and expands slash-command support so common user-focused actions (profile viewing, dueling, token gifting, birthday lookup) are accessible from Discord’s right-click UI, and updates docs to reflect the new entry points.

Changes:

  • Add /profile slash command + View Profile user context command via a new ProfileSlashModule.
  • Add Duel and Gift Tokens user context commands, including a modal-driven token amount prompt.
  • Extend /bday show to support optional per-user lookup and add View Birthday user context command; update feature/codebase docs accordingly.
File summaries
File Description
docs/features.md Documents the new context-menu entry points for profiles, casino gifting, duels, and birthdays.
docs/codebase.md Adds ProfileSlashModule to the documented module layout and domain grouping.
DiscordBot/Modules/Profiles/ProfileSlashModule.cs Implements /profile and View Profile user context command.
DiscordBot/Modules/Fun/DuelSlashModule.cs Adds Duel user context command that starts a normal duel.
DiscordBot/Modules/Fun/Casino/CasinoSlashModule.cs Adds Gift Tokens user context command using a modal for amount entry and shared validation.
DiscordBot/Modules/BirthdaySlashModule.cs Updates /bday show to optionally target a user and adds View Birthday user context command.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +43 to +47
catch (Exception e)
{
await LoggingService.LogAction($"Error while generating profile card for {user.Username}.\nEx:{e}",
ExtendedLogSeverity.LowWarning);
}
public string Amount { get; set; } = string.Empty;
}

[ModalInteraction("casino_gift_tokens:*", true)]
…mmands

- Set Birthday: modal prompts for the date, then sets it (admin only)

- Remove Birthday: confirm/cancel buttons guard the destructive right-click action

- Remove Badge: multi-select menu of the member badges doubles as confirmation; a modal cannot list per-user badges because modal select options are declared at compile time

Slash commands keep identical behaviour and now share helpers with the context commands so the two cannot drift.
…ext commands

- View Casino History: opens the member token transaction history (admin only)

- Set Tokens / Add Tokens: share one amount modal, with the action carried in the custom id

- Amounts are digits only, so a negative value cannot invert the meaning of add or set

- Casino channel restriction plus admin and opener checks enforced on every new path, including the modal submit

Slash commands keep identical behaviour and now share helpers with the context commands.
Adds /coinflip, /roll and /slap and removes !coinflip, !roll, !d20 and !slap.

Dice notation moves into Domain/Dice as a pure parser and now accepts flat
additive modifiers, so /roll 2d6+4 and /roll 1d20+1d4-1 work. A lone bare
number keeps its legacy meaning (20 is 1d20). Keep/drop, exploding, reroll
and success-counting remain unsupported.

Reply wording is extracted to FunRollFormatter so it can be unit tested, and
/slap reads its FuzzTable at most once per process instead of awaiting a
Discord log call on every invocation.

!d20 is not ported; /roll 1d20 covers it.
Adds /ftoc, /ctof and /curr, and deletes ConvertModule along with !translate
and !currencyname.

/curr autocompletes currency codes, matching on code prefix or currency name,
so both sek and krona find SEK. Discord requires required options to precede
optional ones, so the required 'from' option comes first and amount/to follow
with defaults of 1 and usd.

CurrencyService gains GetCurrenciesAsync and a semaphore-guarded lazy build,
since autocomplete and command handling can now populate the currency list
concurrently. GetCurrencyName loses its only caller to the autocomplete
accessor and is removed.

Program now sets EnableAutocompleteHandlers explicitly. It already defaults to
true, but /curr depends on it.
…mands

Adds /members, /join-date [user], /karma, /top and /top-karma [interval], and
deletes RankModule and ProfileModule along with !top, !topk, !topkw, !topkm,
!topky, !karma and !join-date.

/top-karma collapses four commands into one Choice option covering all time,
week, month and year.

Leaderboard row formatting moves to RankEmbedFormatter so the padding rules are
covered by tests. The legacy embed builder blocked on async work inside a LINQ
Select via .Result; the rewrite awaits the lookups directly.

The leaderboard commands used to return without replying when the database
query was unavailable, which would hang a slash interaction. That path now
answers ephemerally.
Comment on lines +139 to +146
catch (Exception)
{
_slapObjectsLoaded = true;

await LoggingService.LogChannelAndFile($"Error while loading '{Settings.FunCommands.SlapObjectsTable}'.",
ExtendedLogSeverity.LowWarning);
return false;
}
Comment on lines +91 to +98
catch (Exception e)
{
// Without this the interaction would never be answered and Discord would show a timeout.
await LoggingService.LogChannelAndFile($"Failed to generate a leaderboard embed.\n{e}",
ExtendedLogSeverity.LowWarning);
await Context.Interaction.RespondAsync("❌ Could not build the leaderboard right now.", ephemeral: true);
return;
}
Comment on lines +55 to +58
if (target < 1)
message = " :game_die: " + message;
else
message = $"{(result.Total >= target ? " :white_check_mark: " : " :x: ")}{message} [Needed: {target}]";
}
catch (Exception)
{
_slapObjectsLoaded = true;
{
SlapObjects.Unique = true;
SlapObjects.Load(Settings.FunCommands.SlapObjectsTable!);
_slapObjectsLoaded = true;
udc-bot-deploy Bot pushed a commit that referenced this pull request Sep 14, 2026
@github-actions

Copy link
Copy Markdown

✅ PR deployed to dev!

Image: ghcr.io/unity-developer-community/udc-bot-dev:741be50
ArgoCD will sync shortly.

@github-actions
github-actions Bot temporarily deployed to dev September 14, 2026 23:15 Inactive
The Assign Badge user context command now offers the target's assignable badges
in a multi-select menu, matching the Remove Badge command.

Only badges the target does not already hold are listed, since offering one they
own can only fail. The first 25 options are shown, with a notice pointing at
/admin badge assign for the rest.

The modal, BadgeIdentifierMaxLength and this module's ResolveBadgeByIdentifier
are deleted; the latter only existed to resolve text typed into the modal. The
/admin badge commands keep their own copy and are unaffected.

Assign Badge now assigns any number of badges and reports a summary rather than
a single-assignment embed.

SanitizeSelectText moves from AdminSlashModule to StringExtensions as
ToSelectOptionText so both select menu builders share one implementation.
udc-bot-deploy Bot pushed a commit that referenced this pull request Sep 15, 2026
@github-actions

Copy link
Copy Markdown

✅ PR deployed to dev!

Image: ghcr.io/unity-developer-community/udc-bot-dev:041dc4d
ArgoCD will sync shortly.

@github-actions
github-actions Bot deployed to dev September 15, 2026 01:48 Active
@Pierre-Demessence
Pierre-Demessence added this pull request to the merge queue Sep 15, 2026
Merged via the queue into master with commit 1ea8d80 Sep 15, 2026
6 checks passed
@Pierre-Demessence
Pierre-Demessence deleted the feature/context-commands branch September 15, 2026 17:18

This branch was successfully deployed

1 active deployment
dev — 041dc4d3 Deployed Sep 15, 2026 by github-actions[bot]
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