From 71a2d737209dc864ef4059ef8865eb2399a79c10 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Tue, 21 Apr 2026 13:04:56 +0000
Subject: [PATCH] Consolidate Streamer.bot link commands into single entrypoint
Consolidated InitiateLinking, ClaimLinkingCode, ConfirmLinking,
UnlinkAccounts, and GetLinkingStatus into a single ManageLinking
command within the C# Streamer.bot wrapper. This reduces the
number of distinct '!linkX' commands users need to know,
unifying them under a single '!link [action]' structure based
on arguments.
Updated ResponseFormatter strings to reflect the new command
usage and adjusted the Discord integration slash command instructions
accordingly. Also closed the relevant item in docs/issues/todo.txt.
Co-authored-by: osse101 <4764184+osse101@users.noreply.github.com>
---
client/csharp/BrandishBotWrapper.cs | 182 +++++++---------------------
client/csharp/ResponseFormatter.cs | 4 +-
docs/issues/todo.txt | 1 -
internal/discord/cmd_link.go | 2 +-
internal/info/loader.go | 3 -
5 files changed, 49 insertions(+), 143 deletions(-)
diff --git a/client/csharp/BrandishBotWrapper.cs b/client/csharp/BrandishBotWrapper.cs
index afb8d576..790e19af 100644
--- a/client/csharp/BrandishBotWrapper.cs
+++ b/client/csharp/BrandishBotWrapper.cs
@@ -1716,166 +1716,76 @@ public bool GetUnlockedRecipes()
#region Account Linking
///
- /// Initiate account linking process
- /// Command: !linkAccount
+ /// Consolidates account linking operations under a single command (!link)
+ /// Command: !link [status|confirm|unlink|]
///
- public bool InitiateLinking()
+ public bool ManageLinking()
{
EnsureInitialized();
string error = null;
if (!ValidateContext(out string platform, out string platformId, out string username, ref error))
{
- CPH.LogWarn($"InitiateLinking Failed: {error}");
+ CPH.LogWarn($"ManageLinking Failed: {error}");
return false;
}
- try
- {
- var result = client.InitiateLinking(platform, platformId, username).Result;
- var formatted = ResponseFormatter.FormatLinkInitiate(result);
- CPH.SetArgument("response", formatted);
- return true;
- }
- catch (Exception ex)
- {
- LogWarning("InitiateLinking", ex);
- CPH.SetArgument("response", StripStatusCode(GetErrorMessage(ex)));
- return true;
- }
- }
-
- ///
- /// Claim a linking code from another platform
- /// Command: !claimCode
- ///
- public bool ClaimLinkingCode()
- {
- EnsureInitialized();
- string error = null;
-
- if (!ValidateContext(out string platform, out string platformId, out string username, ref error))
- {
- CPH.LogWarn($"ClaimLinkingCode Failed: {error}");
- return false;
- }
-
- if (!GetInputString(0, "code", true, out string code, ref error))
- {
- CPH.SetArgument("response", $"{error} Usage: !claimCode ");
- return true;
- }
+ GetInputString(0, "action", false, out string action, ref error);
try
{
- var result = client.ClaimLinkingCode(platform, platformId, username, code).Result;
- var formatted = ResponseFormatter.FormatLinkClaim(result);
- CPH.SetArgument("response", formatted);
- return true;
- }
- catch (Exception ex)
- {
- LogWarning("ClaimLinkingCode", ex);
- CPH.SetArgument("response", StripStatusCode(GetErrorMessage(ex)));
- return true;
- }
- }
-
- ///
- /// Confirm account linking
- /// Command: !confirmLink
- ///
- public bool ConfirmLinking()
- {
- EnsureInitialized();
- string error = null;
-
- if (!ValidateContext(out string platform, out string platformId, out string discardedUsername, ref error))
- {
- CPH.LogWarn($"ConfirmLinking Failed: {error}");
- return false;
- }
-
- try
- {
- var result = client.ConfirmLinking(platform, platformId).Result;
- var formatted = ResponseFormatter.FormatLinkConfirm(result);
- CPH.SetArgument("response", formatted);
- return true;
- }
- catch (Exception ex)
- {
- LogWarning("ConfirmLinking", ex);
- CPH.SetArgument("response", StripStatusCode(GetErrorMessage(ex)));
- return true;
- }
- }
-
- ///
- /// Unlink accounts
- /// Command: !unlink
- ///
- public bool UnlinkAccounts()
- {
- EnsureInitialized();
- string error = null;
-
- if (!ValidateContext(out string platform, out string platformId, out string discardedUsername, ref error))
- {
- CPH.LogWarn($"UnlinkAccounts Failed: {error}");
- return false;
- }
+ if (string.IsNullOrWhiteSpace(action) || action.ToLower() == "initiate" || action.ToLower() == "start")
+ {
+ var result = client.InitiateLinking(platform, platformId, username).Result;
+ CPH.SetArgument("response", ResponseFormatter.FormatLinkInitiate(result));
+ }
+ else if (action.ToLower() == "status")
+ {
+ var result = client.GetLinkingStatus(platform, platformId).Result;
+ CPH.SetArgument("response", ResponseFormatter.FormatLinkingStatus(result));
+ }
+ else if (action.ToLower() == "confirm")
+ {
+ var result = client.ConfirmLinking(platform, platformId).Result;
+ CPH.SetArgument("response", ResponseFormatter.FormatLinkConfirm(result));
+ }
+ else if (action.ToLower() == "unlink")
+ {
+ if (!GetInputString(1, "target_platform", true, out string targetPlatform, ref error))
+ {
+ CPH.SetArgument("response", $"{error} Usage: !link unlink ");
+ return true;
+ }
+ var result = client.UnlinkAccounts(platform, platformId, targetPlatform).Result;
+ CPH.SetArgument("response", ResponseFormatter.FormatMessage(result));
+ }
+ else
+ {
+ string code = action;
+ if (action.ToLower() == "claim")
+ {
+ if (!GetInputString(1, "code", true, out string claimCode, ref error))
+ {
+ CPH.SetArgument("response", $"{error} Usage: !link claim ");
+ return true;
+ }
+ code = claimCode;
+ }
- if (!GetInputString(0, "target_platform", true, out string targetPlatform, ref error))
- {
- CPH.SetArgument("response", $"{error} Usage: !unlink ");
- return true;
- }
+ var result = client.ClaimLinkingCode(platform, platformId, username, code).Result;
+ CPH.SetArgument("response", ResponseFormatter.FormatLinkClaim(result));
+ }
- try
- {
- var result = client.UnlinkAccounts(platform, platformId, targetPlatform).Result;
- var formatted = ResponseFormatter.FormatMessage(result);
- CPH.SetArgument("response", formatted);
return true;
}
catch (Exception ex)
{
- LogWarning("UnlinkAccounts", ex);
+ LogWarning("ManageLinking", ex);
CPH.SetArgument("response", StripStatusCode(GetErrorMessage(ex)));
return true;
}
}
- ///
- /// Get linking status for a user
- /// Command: !linkStatus
- ///
- public bool GetLinkingStatus()
- {
- EnsureInitialized();
- string error = null;
-
- if (!ValidateContext(out string platform, out string platformId, out string discardedUsername, ref error))
- {
- CPH.LogWarn($"GetLinkingStatus Failed: {error}");
- return false;
- }
-
- try
- {
- var result = client.GetLinkingStatus(platform, platformId).Result;
- CPH.SetArgument("response", ResponseFormatter.FormatLinkingStatus(result));
- return true;
- }
- catch (Exception ex)
- {
- LogWarning("GetLinkingStatus", ex);
- CPH.SetArgument("response", $"Error: {StripStatusCode(GetErrorMessage(ex))}");
- return true;
- }
- }
-
#endregion
#region Admin Utilities
diff --git a/client/csharp/ResponseFormatter.cs b/client/csharp/ResponseFormatter.cs
index 91bbd339..82259ef1 100644
--- a/client/csharp/ResponseFormatter.cs
+++ b/client/csharp/ResponseFormatter.cs
@@ -452,7 +452,7 @@ public static string FormatLinkInitiate(LinkInitiateResponse response)
return "Failed to initiate linking: No token received.";
string expireMsg = response.ExpiresIn > 0 ? $" (Expires in {response.ExpiresIn / 60}m)" : "";
- return $"Linking code: {response.Token}{expireMsg}. Run '!claimCode {response.Token}' on your other platform.";
+ return $"Linking code: {response.Token}{expireMsg}. Run '!link {response.Token}' on your other platform.";
}
///
@@ -463,7 +463,7 @@ public static string FormatLinkClaim(LinkClaimResponse response)
if (response == null) return "Claim request failed.";
if (response.AwaitingConfirmation)
{
- return $"Code claimed! Please return to {response.SourcePlatform} and run '!confirmLink' to complete the process.";
+ return $"Code claimed! Please return to {response.SourcePlatform} and run '!link confirm' to complete the process.";
}
return "Code claimed successfully.";
}
diff --git a/docs/issues/todo.txt b/docs/issues/todo.txt
index 8a8fa450..481ace98 100644
--- a/docs/issues/todo.txt
+++ b/docs/issues/todo.txt
@@ -1,3 +1,2 @@
-Client: reduce number of !link commands and sort based on arguments
Expedition journal too long for 1 discord post
Bomb usage message is outdated.
\ No newline at end of file
diff --git a/internal/discord/cmd_link.go b/internal/discord/cmd_link.go
index 25dafeca..64c54ceb 100644
--- a/internal/discord/cmd_link.go
+++ b/internal/discord/cmd_link.go
@@ -84,7 +84,7 @@ func LinkCommand() (*discordgo.ApplicationCommand, CommandHandler) {
embed = createEmbed("🔗 Link Started", fmt.Sprintf("**Your link code:** `%s`\n\n"+
"**1. Copy Code:** `%s`\n"+
"**2. Go to External Chat:** Twitch or YouTube chat\n"+
- "**3. Type Command:** `!link %s`\n"+
+ "**3. Type Command:** `!link claim %s`\n"+
"**4. Return Here:** Come back to this channel\n"+
"**5. Confirm:** Type `/link confirm:true`\n\n"+
"⏰ This code expires in **%d minutes**.",
diff --git a/internal/info/loader.go b/internal/info/loader.go
index 0fdc0cb3..54316512 100644
--- a/internal/info/loader.go
+++ b/internal/info/loader.go
@@ -24,7 +24,6 @@ func NewLoader(dir string) *Loader {
}
func (l *Loader) Load() error {
-
entries, err := os.ReadDir(l.dir)
if err != nil {
return fmt.Errorf("failed to read info directory: %w", err)
@@ -64,7 +63,6 @@ func (l *Loader) loadFeatureFile(path string) (*Feature, error) {
}
func (l *Loader) GetFeature(name string) (*Feature, bool) {
-
feature, ok := l.cache[name]
return feature, ok
}
@@ -84,7 +82,6 @@ func (l *Loader) GetTopic(featureName, topicName string) (*Topic, bool) {
}
func (l *Loader) SearchTopic(topicName string) (*Topic, string, bool) {
-
for featureName, feature := range l.cache {
if topic, ok := feature.Topics[topicName]; ok {
return &topic, featureName, true