Skip to content

Commit

Permalink
Add #insiders-info interactions
Browse files Browse the repository at this point in the history
  • Loading branch information
FloatingMilkshake committed Dec 31, 2024
1 parent 3c75a57 commit 2598bb5
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 0 deletions.
27 changes: 27 additions & 0 deletions Commands/InteractionCommands/InsidersInteractions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace Cliptok.Commands.InteractionCommands
{
public class InsidersInteractions : ApplicationCommandModule
{
[SlashCommand("send-insiders-info-buttons", "Sends a message with buttons to get Insider roles for #insiders-info.")]
public static async Task SendInsidersInfoButtonMessage(InteractionContext ctx)
{
if (Program.cfgjson.InsiderInfoChannel != 0 && ctx.Channel.Id != Program.cfgjson.InsiderInfoChannel)
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} This command only works in <#{Program.cfgjson.InsiderInfoChannel}>!", ephemeral: true);
return;
}

DiscordComponent[] buttons =
[
new DiscordButtonComponent(DiscordButtonStyle.Primary, "insiders-info-roles-menu-callback", "Choose your Insider roles"),
new DiscordButtonComponent(DiscordButtonStyle.Secondary, "insiders-info-chat-btn-callback", "I just want to chat for now")
];

var builder = new DiscordInteractionResponseBuilder()
.WithContent($"{Program.cfgjson.Emoji.Insider} Choose your Insider roles here! Or, you can choose to chat in <#{Program.cfgjson.InsidersChannel}> without being notified about new builds.")
.AddComponents(buttons);

await ctx.CreateResponseAsync(builder);
}
}
}
146 changes: 146 additions & 0 deletions Events/InteractionEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,152 @@ await LogChannelHelper.LogDeletedMessagesAsync(
// Respond
await e.Message.ModifyAsync(new DiscordMessageBuilder().WithContent($"{cfgjson.Emoji.Success} Override successfully added. <@{newOverwrite.Id}> already had an override in <#{pendingOverride.ChannelId}>, so here are their new permissions:\n**Allowed:** {newOverwrite.Allowed}\n**Denied:** {newOverwrite.Denied}"));
}
else if (e.Id == "insiders-info-roles-menu-callback")
{
// Shows a menu in #insider-info that allows a user to toggle their Insider roles

// Defer interaction
await e.Interaction.DeferAsync(ephemeral: true);

// Fetch member
var member = await e.Guild.GetMemberAsync(e.User.Id);

// Fetch Insider roles to check whether member already has them
var insiderCanaryRole = await e.Guild.GetRoleAsync(cfgjson.UserRoles.InsiderCanary);
var insiderDevRole = await e.Guild.GetRoleAsync(cfgjson.UserRoles.InsiderDev);
var insiderBetaRole = await e.Guild.GetRoleAsync(cfgjson.UserRoles.InsiderBeta);
var insiderRPRole = await e.Guild.GetRoleAsync(cfgjson.UserRoles.InsiderRP);
var insider10RPRole = await e.Guild.GetRoleAsync(cfgjson.UserRoles.Insider10RP);
var patchTuesdayRole = await e.Guild.GetRoleAsync(cfgjson.UserRoles.PatchTuesday);

// Show menu with current Insider roles, apply new roles based on user selection
var menu = new DiscordSelectComponent("insiders-info-roles-menu-response-callback", "Choose your Insider roles",
new List<DiscordSelectComponentOption>()
{
new("Windows 11 Canary channel", "insiders-info-w11-canary", isDefault: member.Roles.Contains(insiderCanaryRole)),
new("Windows 11 Dev channel", "insiders-info-w11-dev", isDefault: member.Roles.Contains(insiderDevRole)),
new("Windows 11 Beta channel", "insiders-info-w11-beta", isDefault: member.Roles.Contains(insiderBetaRole)),
new("Windows 11 Release Preview channel", "insiders-info-w11-rp", isDefault: member.Roles.Contains(insiderRPRole)),
new("Windows 10 Release Preview channel", "insiders-info-w10-rp", isDefault: member.Roles.Contains(insider10RPRole)),
new("Patch Tuesday", "insiders-info-pt", isDefault: member.Roles.Contains(patchTuesdayRole)),
}, minOptions: 0, maxOptions: 6);

var builder = new DiscordFollowupMessageBuilder()
.WithContent($"{cfgjson.Emoji.Insider} Use the menu below to toggle your Insider roles!")
.AddComponents(menu)
.AsEphemeral(true);

await e.Interaction.CreateFollowupMessageAsync(builder);
}
else if (e.Id == "insiders-info-roles-menu-response-callback")
{
// User has selected new Insider roles w/ menu above
// Compare selection against current roles; add or remove roles as necessary to match selection

// Defer
await e.Interaction.DeferAsync(ephemeral: true);

// Get member
var member = await e.Guild.GetMemberAsync(e.User.Id);

// Map role select options to role IDs
var insiderRoles = new Dictionary<string, ulong>
{
{ "insiders-info-w11-canary", cfgjson.UserRoles.InsiderCanary },
{ "insiders-info-w11-dev", cfgjson.UserRoles.InsiderDev },
{ "insiders-info-w11-beta", cfgjson.UserRoles.InsiderBeta },
{ "insiders-info-w11-rp", cfgjson.UserRoles.InsiderRP },
{ "insiders-info-w10-rp", cfgjson.UserRoles.Insider10RP },
{ "insiders-info-pt", cfgjson.UserRoles.PatchTuesday }
};

// Get a list of the member's current roles that we can add to or remove from
// Then we can apply this in a single request with member.ReplaceRolesAsync to avoid making repeated member update requests
List<DiscordRole> memberRoles = member.Roles.ToList();

var selection = e.Values.Select(x => insiderRoles[x]).ToList();

foreach (var roleId in insiderRoles.Values)
{
var role = await e.Guild.GetRoleAsync(roleId);

if (selection.Contains(roleId))
{
// Member should have the role
if (!memberRoles.Contains(role))
memberRoles.Add(role);
}
else
{
// Member should not have the role
if (memberRoles.Contains(role))
memberRoles.Remove(role);
}
}

await member.ReplaceRolesAsync(memberRoles, "Applying Insider roles chosen in #insiders-info");

await e.Interaction.CreateFollowupMessageAsync(new DiscordFollowupMessageBuilder().WithContent($"{cfgjson.Emoji.Success} Your Insider roles have been updated!").AsEphemeral(true));
}
else if (e.Id == "insiders-info-chat-btn-callback")
{
// Button in #insiders-info that checks whether user has 'insiderChat' role and asks them to confirm granting/revoking it

// Defer
await e.Interaction.DeferAsync(ephemeral: true);

// Get member
var member = await e.Guild.GetMemberAsync(e.User.Id);

var insiderChatRole = await e.Guild.GetRoleAsync(cfgjson.UserRoles.InsiderChat);
if (member.Roles.Contains(insiderChatRole))
{
// Member already has the role
// Ask them if they'd like to remove it
var confirmResponse = new DiscordFollowupMessageBuilder()
.WithContent($"{cfgjson.Emoji.Warning} You already have the {insiderChatRole.Mention} role! Would you like to remove it?")
.AddComponents(new DiscordButtonComponent(DiscordButtonStyle.Danger, "insiders-info-chat-btn-remove-confirm-callback", "Remove"));

await e.Interaction.CreateFollowupMessageAsync(confirmResponse);
}
else
{
// Member does not have the role; show a confirmation message with a button that will give it to them
await e.Interaction.CreateFollowupMessageAsync(new DiscordFollowupMessageBuilder()
.WithContent($"{cfgjson.Emoji.Warning} Please note that <#{cfgjson.InsidersChannel}> is **not for tech support**! If you need tech support, please ask in the appropriate channels instead. Press the button to acknowledge this and get the {insiderChatRole.Mention} role.")
.AddComponents(new DiscordButtonComponent(DiscordButtonStyle.Secondary, "insiders-info-chat-btn-confirm-callback", "I understand")));
}
}
else if (e.Id == "insiders-info-chat-btn-confirm-callback")
{
// Confirmation for granting insiderChat role, see above

// Defer
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.DeferredMessageUpdate);

// Give member insider chat role
var member = await e.Guild.GetMemberAsync(e.User.Id);
var insiderChatRole = await e.Guild.GetRoleAsync(cfgjson.UserRoles.InsiderChat);
await member.GrantRoleAsync(insiderChatRole);

// Respond
await e.Interaction.EditFollowupMessageAsync(e.Message.Id, new DiscordWebhookBuilder().WithContent($"{cfgjson.Emoji.Success} You have been given the {insiderChatRole.Mention} role!"));
}
else if (e.Id == "insiders-info-chat-btn-remove-confirm-callback")
{
// Confirmation for revoking insiderChat role, see above

// Defer
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.DeferredMessageUpdate);

// Get member
var member = await e.Guild.GetMemberAsync(e.User.Id);

var insiderChatRole = await e.Guild.GetRoleAsync(cfgjson.UserRoles.InsiderChat);
await member.RevokeRoleAsync(insiderChatRole);

await e.Interaction.EditFollowupMessageAsync(e.Message.Id, new DiscordWebhookBuilder().WithContent($"{cfgjson.Emoji.Success} You have been removed from the {insiderChatRole.Mention} role!"));
}
else
{
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Unknown interaction. I don't know what you are asking me for.").AsEphemeral(true));
Expand Down
9 changes: 9 additions & 0 deletions Structs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,15 @@ public class ConfigJson

[JsonProperty("forumIntroPosts")]
public List<ulong> ForumIntroPosts { get; private set; } = new();

[JsonProperty("insiderInfoChannel")]
public ulong InsiderInfoChannel { get; private set; }

[JsonProperty("insiderAnnouncementChannel")]
public ulong InsiderAnnouncementChannel { get; private set; } = 0;

[JsonProperty("insidersChannel")]
public ulong InsidersChannel { get; private set; }

[JsonProperty("insiderCommandLockedToChannel")]
public ulong InsiderCommandLockedToChannel { get; private set; } = 0;
Expand Down Expand Up @@ -486,6 +492,9 @@ public class UserRoleConfig

[JsonProperty("insider10RP")]
public ulong Insider10RP { get; private set; }

[JsonProperty("insiderChat")]
public ulong InsiderChat { get; private set; }

[JsonProperty("patchTuesday")]
public ulong PatchTuesday { get; private set; }
Expand Down
3 changes: 3 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@
"insiderBeta": 643712828217360394,
"insiderRP": 288729239921098752,
"insider10RP": 910319453491839069,
"insiderChat": 0,
"patchTuesday": 445773142233710594,
"giveaways": 1169336992455200820
},
Expand Down Expand Up @@ -315,6 +316,8 @@
1065659890036646019
],
"insiderAnnouncementChannel": 1043898319883219004,
"insiderInfoChannel": 1279201622651572317,
"insidersChannel": 187649467611086849,
"insiderCommandLockedToChannel": 187649467611086849,
"dmAutoresponseTimeLimit": 6,
"autoDeleteEmptyThreads": true,
Expand Down

0 comments on commit 2598bb5

Please sign in to comment.