Skip to content

/modmail slash command #329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

talentedasian
Copy link
Contributor

Pull-request

Changes

  • Existing code
  • New feature

Closes Issue: #311

Description

This is a draft of my PR on the /modmail command. The commit body contains
most of my work but I also wanted to address one more thing. I'm not entirely
sure if I should use the findMemberWithRoles on Guild class by JDA because:

  * Add a "guildId" config in Config.json for later use in finding the
    moderators of the guild.
  * Initially, the bot response should've been ephemeral but since I was
    using a selection menu, the way I was disabling it does not work if
    I set the bot response to ephemeral.
@Tais993
Copy link
Member

Tais993 commented Dec 15, 2021

There's a big issue in this code, it retrieves every single member of the server each time you call findMemberWithRoles
So this should only be used once preferably at all time, maybe even never depending on how you solve it.

So instead, retrieve once and create an selection menu in advance.

This means you find all the members with the role, create a selection menu based on the members found.
And you always re-use this selection menu.

To improve UX for the moderators, add a command only moderators can use to reload the list

@Zabuzard Zabuzard added new command Add a new command or group of commands to the bot priority: normal labels Dec 15, 2021
@Zabuzard Zabuzard added this to the Improvement phase 1 milestone Dec 15, 2021
and use it for subsequent invocation of the command.
@CLAassistant
Copy link

CLAassistant commented Dec 16, 2021

CLA assistant check
All committers have signed the CLA.

highly unlikely, send an ephemeral message and log the unusual behavior
@talentedasian
Copy link
Contributor Author

talentedasian commented Dec 16, 2021

Right now, the private message does get sent and the buttons are getting disabled as well but the interaction somehow fails.

…. This also fixes the failed interaction by discord
  the /modmail command.

* Introduce a utility class for use by other classes when interacting with the ModMailCommand.

* Some javadoc.
@talentedasian
Copy link
Contributor Author

Most of the work now is done, I'll now put this up as ready for review.

@talentedasian talentedasian marked this pull request as ready for review December 16, 2021 15:30
@talentedasian talentedasian requested review from a team as code owners December 16, 2021 15:30
}

/**
* Creates a list of options containing the moderators for use in the modmail slash command.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Forgot to change the javadoc for this. I'll just do it tomorrow.

Comment on lines 33 to 34
Guild guild = Objects.requireNonNull(jda.getGuildById(config.getGuildId()),
"A Guild is required to use this command. Perhaps the bot isn't on the guild yet");
Copy link
Member

Choose a reason for hiding this comment

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

you should be able to do event.getGuild(), no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could but I didn't due to some pedantic reason. If the command was called on Guild A, but the guildId was Guild B, then it would have inconsistent results.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thinking about that, I think I could perhaps do event.getGuild() on the ModMailCommand as well.

Copy link
Member

Choose a reason for hiding this comment

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

I do think you should SlashCommandEvent#getGuild ^^

If you run the command in Guild B, right now it runs it like it's in Guild A, which is really weird imo

The bot is only in 1 guild, and it'll never join another one

Comment on lines 33 to 34
Guild guild = Objects.requireNonNull(jda.getGuildById(config.getGuildId()),
"A Guild is required to use this command. Perhaps the bot isn't on the guild yet");
Copy link
Member

Choose a reason for hiding this comment

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

I do think you should SlashCommandEvent#getGuild ^^

If you run the command in Guild B, right now it runs it like it's in Guild A, which is really weird imo

The bot is only in 1 guild, and it'll never join another one

Comment on lines 28 to 29
static final List<SelectOption> mods = new ArrayList<>();
static final Map<String, User> modsMap = new HashMap<>();
Copy link
Member

Choose a reason for hiding this comment

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

It shouldn't be done this way, keep the variables private, use the onReady event to load the options/mods.

So keep it within this class, make the variables private and don't make them static.

Comment on lines 56 to 58
if (mods.size() == 1) {
loadMenuOptions();
}
Copy link
Member

Choose a reason for hiding this comment

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

Remove this in favor of the onReady event, see above

Comment on lines 131 to 136
private void loadMenuOptions() {
Guild guild = Objects.requireNonNull(jda.getGuildById(config.getGuildId()),
"A Guild is required to use this command. Perhaps the bot isn't on the guild yet");

ModMailUtil.loadMenuOptions(guild);
}
Copy link
Member

Choose a reason for hiding this comment

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

See review above, remove this in favor of the onReady event

// guild.
String userId = args.get(0);
if (event.isFromGuild()
&& !userId.equals(Objects.requireNonNull(event.getMember()).getId())) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
&& !userId.equals(Objects.requireNonNull(event.getMember()).getId())) {
&& !userId.equals(event.getMember().getId())) {

You're effectively doing

if (member == null) {
    member.toString();
}

Here, which is, useless

Role modRole = getModRole(guild)
.orElseThrow(() -> new IllegalStateException("No moderator role found"));

guild.findMembersWithRoles(modRole).get().stream().forEach(mod -> {
Copy link
Member

Choose a reason for hiding this comment

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

Why the get and the stream?

Just use onSuccess?

private static final Config config = Config.getInstance();

static final List<SelectOption> mods = new ArrayList<>();
static final Map<String, User> modsMap = new HashMap<>();
Copy link
Member

Choose a reason for hiding this comment

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

Another note, NEVER store Discord entities.

They can be invalidated (garbage collected) which will result in really weird errors.

Instead, store their ID (or username in this case)

  Replace all loadOptions with the onReady event but still delegating to
  the ModmailUtils to query discord.

* Move ReloadModmailCommand from a separate class to the ModmailCommand
  class.
@@ -70,6 +71,10 @@
commands.add(new MuteCommand(actionsStore));
commands.add(new UnmuteCommand(actionsStore));

ModmailCommand modmailCommand = new ModmailCommand();
commands.add(modmailCommand);
commands.add(modmailCommand.new ReloadModmailCommand());
Copy link
Contributor

Choose a reason for hiding this comment

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

This will not compile.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Really? I'm sure I've tested and ran it on my machine numerous times.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also ran gradle build so I'm really sure it works. Do you mind checking it again?

Copy link
Member

Choose a reason for hiding this comment

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

It doesn't compile no, I'm not sure what you're doing there modmailCommand.new ReloadModmailCommand()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The ReloadModmailCommand is an inner class since it's the only solution I could think of to reload the mods in the /modmail command. Thus, I am instantiating the ReloadModmailCommand from the Modmail object.

Copy link
Member

Choose a reason for hiding this comment

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

Ah that explains

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am genuinely confused why it doesn't compile. Do you mind helping me out on this one?

Copy link
Member

@Tais993 Tais993 Dec 18, 2021

Choose a reason for hiding this comment

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

Well, it compiles like you said, it's just done in a weird way.
To my knowledge, you can remove modmailCommand. from modmailCommand.new ReloadModmailCommand()
So please do that, if you can't, refer to the class instead of an instance?

Copy link
Contributor

Choose a reason for hiding this comment

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

You can't. That's the required syntax for instantiating a non-static inner class. It's really weird.

@github-actions
Copy link

This pull request is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the stale label Jan 18, 2022
@Tais993
Copy link
Member

Tais993 commented Jan 20, 2022

@talentedasian do you've the time to work on this PR (this week, next week)? Otherwise I'll take this PR over so it can be merged

@talentedasian
Copy link
Contributor Author

I do but you can take over this PR if you want.

@Tais993
Copy link
Member

Tais993 commented Jan 20, 2022

If you've the time, you can handle it, it takes some time setting up and you deserve most of the credits :p

@Zabuzard
Copy link
Member

If you've the time, you can handle it, it takes some time setting up and you deserve most of the credits :p

If you take over, you can also copy their branch and hence basically keep their commits. Or alternatively manually add them as author to a commit of urs (for credits).

@Tais993
Copy link
Member

Tais993 commented Jan 20, 2022

I'll work in the branch in that case, your branch will be copied so you'll be credited ^^

@Tais993
Copy link
Member

Tais993 commented Jan 20, 2022

This PR will be closed in favor of a new PR (will be linked)

In advance, thanks for your help talentedasian! Your branch will be the base of the new PR

@Tais993 Tais993 closed this Jan 20, 2022
@Tais993 Tais993 mentioned this pull request Jan 20, 2022
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new command Add a new command or group of commands to the bot priority: normal stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants