Skip to content

Commit a1a9be0

Browse files
authored
Merge pull request #405 from danthe1st/fix-help-ping
change /help-ping to post message requesting help in dedicated channel
2 parents b88c4b4 + 3b6cd90 commit a1a9be0

File tree

2 files changed

+119
-18
lines changed

2 files changed

+119
-18
lines changed

src/main/java/net/javadiscord/javabot/data/config/guild/HelpConfig.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import lombok.EqualsAndHashCode;
55
import net.dv8tion.jda.api.entities.Role;
66
import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel;
7+
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
78
import net.javadiscord.javabot.data.config.GuildConfigItem;
89

910
import java.util.Map;
@@ -24,7 +25,7 @@ public class HelpConfig extends GuildConfigItem {
2425
/**
2526
* The id of the help-ping role.
2627
*/
27-
private long helpPingRoleId;
28+
private long helpNotificationChannelId;
2829

2930
/**
3031
* The message that's sent as soon as a user asks a question in an open help
@@ -120,7 +121,7 @@ public Role getHelperRole() {
120121
return getGuild().getRoleById(helperRoleId);
121122
}
122123

123-
public Role getHelpPingRole() {
124-
return getGuild().getRoleById(helpPingRoleId);
124+
public TextChannel getHelpNotificationChannel() {
125+
return getGuild().getTextChannelById(helpNotificationChannelId);
125126
}
126127
}

src/main/java/net/javadiscord/javabot/systems/help/commands/HelpPingSubcommand.java

Lines changed: 115 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,44 @@
33
import net.dv8tion.jda.api.EmbedBuilder;
44
import net.dv8tion.jda.api.entities.Guild;
55
import net.dv8tion.jda.api.entities.Member;
6-
import net.dv8tion.jda.api.entities.Message;
7-
import net.dv8tion.jda.api.entities.MessageEmbed;
86
import net.dv8tion.jda.api.entities.Role;
9-
import net.dv8tion.jda.api.entities.User;
107
import net.dv8tion.jda.api.entities.channel.ChannelType;
8+
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
119
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
10+
import net.dv8tion.jda.api.entities.channel.forums.ForumTag;
11+
import net.dv8tion.jda.api.entities.emoji.EmojiUnion;
1212
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
13+
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
1314
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
15+
import net.dv8tion.jda.api.interactions.components.buttons.Button;
16+
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
17+
import net.javadiscord.javabot.annotations.AutoDetectableComponentHandler;
1418
import net.javadiscord.javabot.data.config.BotConfig;
1519
import net.javadiscord.javabot.data.config.GuildConfig;
1620
import net.javadiscord.javabot.data.config.guild.HelpConfig;
1721
import net.javadiscord.javabot.util.Pair;
1822
import net.javadiscord.javabot.util.Responses;
1923
import org.jetbrains.annotations.NotNull;
2024
import xyz.dynxsty.dih4jda.interactions.commands.application.SlashCommand;
25+
import xyz.dynxsty.dih4jda.interactions.components.ButtonHandler;
26+
import xyz.dynxsty.dih4jda.util.ComponentIdBuilder;
2127

22-
import java.util.EnumSet;
28+
import java.awt.Color;
29+
import java.time.OffsetDateTime;
2330
import java.util.List;
2431
import java.util.Map;
2532
import java.util.Set;
2633
import java.util.concurrent.ConcurrentHashMap;
2734
import java.util.concurrent.ScheduledExecutorService;
2835
import java.util.concurrent.TimeUnit;
36+
import java.util.stream.Collectors;
2937

3038
/**
3139
* Handler for the /help ping sub-command that allows users to occasionally ping
3240
* helpers.
3341
*/
34-
public class HelpPingSubcommand extends SlashCommand.Subcommand {
42+
@AutoDetectableComponentHandler("help-ping")
43+
public class HelpPingSubcommand extends SlashCommand.Subcommand implements ButtonHandler {
3544
private static final String WRONG_CHANNEL_MSG = "This command can only be used in **help forum posts**";
3645
private static final long CACHE_CLEANUP_DELAY = 60L;
3746

@@ -74,23 +83,65 @@ public void execute(@NotNull SlashCommandInteractionEvent event) {
7483
Responses.warning(event, "Sorry, but only the person who reserved this channel, or staff and helpers, may use this command.").queue();
7584
return;
7685
}
86+
if (post.getTimeCreated().isAfter(OffsetDateTime.now().minusSeconds(config.getHelpConfig().getHelpPingTimeoutSeconds()))) {
87+
Responses.warning(event, "Sorry, this command cannot be used directly after a post has been created.").queue();
88+
return;
89+
}
7790
if (isHelpPingTimeoutElapsed(member.getIdLong(), config)) {
7891
lastPingTimes.put(event.getMember().getIdLong(), new Pair<>(System.currentTimeMillis(), config.getGuild()));
79-
Role role = config.getHelpConfig().getHelpPingRole();
80-
event.getChannel().sendMessage(role.getAsMention())
81-
.setAllowedMentions(EnumSet.of(Message.MentionType.ROLE))
82-
.setEmbeds(buildAuthorEmbed(event.getUser()))
83-
.queue();
84-
event.replyFormat("Successfully pinged " + role.getAsMention()).setEphemeral(true).queue();
92+
TextChannel notifChannel = config.getHelpConfig().getHelpNotificationChannel();
93+
notifChannel.sendMessageEmbeds(new EmbedBuilder().setDescription("""
94+
%s requested help in %s
95+
96+
Tags:
97+
%s
98+
99+
[Click to view](%s)
100+
"""
101+
.formatted(
102+
event.getUser().getAsMention(),
103+
post.getAsMention(),
104+
getTagString(post),
105+
post.getJumpUrl()
106+
))
107+
.setAuthor(member.getEffectiveName(), null, member.getEffectiveAvatarUrl())
108+
.setFooter(event.getUser().getId())
109+
.setColor(Color.YELLOW)
110+
.build())
111+
.addActionRow(createAcknowledgementButton())
112+
.queue();
113+
event.reply("""
114+
Successfully requested help.
115+
116+
Note that this does NOT gurantee that anybody here has the time and knowledge to help you.
117+
Abusing this command might result in moderative action taken against you.
118+
""")
119+
.setEphemeral(true)
120+
.queue();
85121
} else {
86122
Responses.warning(event, "Sorry, but you can only use this command occasionally. Please try again later.").queue();
87123
}
88124
}
89125

90-
private @NotNull MessageEmbed buildAuthorEmbed(@NotNull User author) {
91-
return new EmbedBuilder()
92-
.setTitle("Requested by " + author.getAsTag())
93-
.build();
126+
private String getTagString(ThreadChannel post) {
127+
String text = post
128+
.getAppliedTags()
129+
.stream()
130+
.map(this::getForumTagText)
131+
.map(tag -> "- " + tag)
132+
.collect(Collectors.joining("\n"));
133+
if(text.isEmpty()) {
134+
text = "- <no tags>";
135+
}
136+
return text;
137+
}
138+
139+
private Button createAcknowledgementButton() {
140+
return Button.of(ButtonStyle.SECONDARY, ComponentIdBuilder.build("help-ping", "acknowledge"), "Mark as acknowledged");
141+
}
142+
143+
private Button createUndoAcknowledgementButton() {
144+
return Button.of(ButtonStyle.SECONDARY, ComponentIdBuilder.build("help-ping", "unacknowledge"), "Mark as unacknowledged");
94145
}
95146

96147
/**
@@ -142,4 +193,53 @@ private void cleanTimeoutCache() {
142193
lastPingTimes.remove(memberId);
143194
}
144195
}
196+
197+
@Override
198+
public void handleButton(ButtonInteractionEvent event, Button button) {
199+
String[] id = ComponentIdBuilder.split(event.getComponentId());
200+
switch(id[1]) {
201+
case "acknowledge" ->
202+
acknowledgeChangeAction(event, true);
203+
case "unacknowledge" ->
204+
acknowledgeChangeAction(event, false);
205+
default -> event.reply("Unknown button").setEphemeral(true).queue();
206+
}
207+
208+
}
209+
210+
private void acknowledgeChangeAction(ButtonInteractionEvent event, boolean acknowledged) {
211+
event.editMessageEmbeds(
212+
event.getMessage()
213+
.getEmbeds()
214+
.stream()
215+
.map(e->new EmbedBuilder(e)
216+
.setColor(acknowledged ? Color.GRAY : Color.YELLOW)
217+
.addField("marked as " + (acknowledged?"acknowledged":"needs help") + " by",
218+
event.getUser().getAsMention(), false))
219+
.map(this::removeOldField)
220+
.map(EmbedBuilder::build)
221+
.toList())
222+
.setActionRow(acknowledged?createUndoAcknowledgementButton():createAcknowledgementButton())
223+
.queue();
224+
}
225+
226+
private String getForumTagText(ForumTag tag) {
227+
EmojiUnion emoji = tag.getEmoji();
228+
StringBuilder sb=new StringBuilder();
229+
if(emoji!=null) {
230+
sb
231+
.append(emoji.getFormatted())
232+
.append(" ");
233+
}
234+
sb.append(tag.getName());
235+
236+
return sb.toString();
237+
}
238+
239+
private EmbedBuilder removeOldField(EmbedBuilder eb) {
240+
if(eb.getFields().size()>5) {
241+
eb.getFields().remove(0);
242+
}
243+
return eb;
244+
}
145245
}

0 commit comments

Comments
 (0)