Skip to content

Commit bb51b84

Browse files
committed
Added DiscordClientAction
This allows the user to generate URL's which link to items in the Discord app (a channel, settings etc)
1 parent ec6390b commit bb51b84

File tree

2 files changed

+243
-4
lines changed

2 files changed

+243
-4
lines changed

application/src/main/java/org/togetherjava/tjbot/commands/Features.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
import net.dv8tion.jda.api.JDA;
44
import org.jetbrains.annotations.NotNull;
5-
import org.togetherjava.tjbot.commands.basic.PingCommand;
6-
import org.togetherjava.tjbot.commands.basic.RoleSelectCommand;
7-
import org.togetherjava.tjbot.commands.basic.SuggestionsUpDownVoter;
8-
import org.togetherjava.tjbot.commands.basic.VcActivityCommand;
5+
import org.togetherjava.tjbot.commands.basic.*;
96
import org.togetherjava.tjbot.commands.free.FreeCommand;
107
import org.togetherjava.tjbot.commands.mathcommands.TeXCommand;
118
import org.togetherjava.tjbot.commands.moderation.*;
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
package org.togetherjava.tjbot.commands.utils;
2+
3+
import net.dv8tion.jda.api.interactions.components.Button;
4+
import net.dv8tion.jda.api.interactions.components.ButtonStyle;
5+
import org.jetbrains.annotations.Contract;
6+
import org.jetbrains.annotations.NotNull;
7+
8+
import java.util.regex.Pattern;
9+
10+
/**
11+
* Class which contains all actions a Discord client accepts.
12+
*
13+
* This allows you to open DM's {@link Channels#DM_CHANNEL}, specific settings
14+
* {@link Settings.App#VOICE} and much more.
15+
*
16+
* <p>
17+
* A few notes;
18+
* <ul>
19+
* <li>iOS and Android are NOT supported</li>
20+
* <li>It opens the LAST installed Discord version (Discord, Canary, PTB)</li>
21+
* </ul>
22+
*/
23+
public class DiscordClientAction {
24+
25+
/**
26+
* Contains some of the more general actions
27+
*/
28+
public static class General {
29+
public static final DiscordClientAction HOME = new DiscordClientAction("discord://-/");
30+
public static final DiscordClientAction FRIENDS = new DiscordClientAction("discord://-/");
31+
32+
public static final DiscordClientAction USER =
33+
new DiscordClientAction("discord://-/users/{USER-ID}");
34+
public static final DiscordClientAction JOIN_INVITE =
35+
new DiscordClientAction("discord://-/invite/{INVITE-CODE}");
36+
public static final DiscordClientAction HUB_MEMBERSHIP_SCREENING =
37+
new DiscordClientAction("discord://-/member-verification-for-hub/{HUB-ID}");
38+
public static final DiscordClientAction STORE =
39+
new DiscordClientAction("discord://-/store");
40+
41+
public static final DiscordClientAction HYPESQUAD =
42+
new DiscordClientAction("discord://-/settings/hypesquad_online");
43+
public static final DiscordClientAction CHANGELOGS =
44+
new DiscordClientAction("discord://-/settings/changelogs");
45+
}
46+
47+
/**
48+
* Contains guild specific actions
49+
*/
50+
public static class Guild {
51+
public static final DiscordClientAction GUILD =
52+
new DiscordClientAction("discord://-/channels/{GUILD-ID}");
53+
public static final DiscordClientAction GUILD_CHANNEL =
54+
new DiscordClientAction("discord://-/channels/{GUILD-ID}/{CHANNEL-ID}");
55+
56+
public static final DiscordClientAction GUILD_DISCOVERY =
57+
new DiscordClientAction("discord://-/guild-discovery");
58+
public static final DiscordClientAction GUILDS_CREATE =
59+
new DiscordClientAction("discord://-/guilds/create");
60+
61+
/** Beta Discord feature */
62+
public static final DiscordClientAction GUILD_HOME_CHANNEL =
63+
new DiscordClientAction("discord://-/channels/{GUILD-ID}/@home");
64+
public static final DiscordClientAction GUILD_EVENT =
65+
new DiscordClientAction("discord://-/events/{GUILD-ID}/{EVENT-ID}");
66+
public static final DiscordClientAction GUILD_MEMBERSHIP_SCREENING =
67+
new DiscordClientAction("discord://-/member-verification/{GUILD-ID}");
68+
}
69+
70+
/**
71+
* Contains actions related to channels
72+
*/
73+
public static class Channels {
74+
public static final DiscordClientAction DM_CHANNEL =
75+
new DiscordClientAction("discord://-/channels/@me/{CHANNEL-ID}");
76+
public static final DiscordClientAction DM_CHANNEL_MESSAGE =
77+
new DiscordClientAction("discord://-/channels/@me/{CHANNEL-ID}/{MESSAGE-ID}");
78+
public static final DiscordClientAction GUILD_CHANNEL =
79+
new DiscordClientAction("discord://-/channels/{GUILD-ID}/{CHANNEL-ID}");
80+
public static final DiscordClientAction GUILD_CHANNEL_MESSAGE = new DiscordClientAction(
81+
"discord://-/channels/{GUILD-ID}/{CHANNEL-ID}/{MESSAGE-ID}");
82+
}
83+
84+
/**
85+
* Contains actions related to the settings menu
86+
*/
87+
public static class Settings {
88+
89+
/**
90+
* Contains all user settings
91+
*/
92+
public static class User {
93+
public static final DiscordClientAction ACCOUNT =
94+
new DiscordClientAction("discord://-/settings/account");
95+
public static final DiscordClientAction PROFILE_CUSTOMIZATION =
96+
new DiscordClientAction("discord://-/settings/profile-customization");
97+
public static final DiscordClientAction PRIVACY_AND_SAFETY =
98+
new DiscordClientAction("discord://-/settings/privacy-and-safety");
99+
public static final DiscordClientAction AUTHORIZED_APPS =
100+
new DiscordClientAction("discord://-/settings/authorized-apps");
101+
public static final DiscordClientAction CONNECTIONS =
102+
new DiscordClientAction("discord://-/settings/connections");
103+
}
104+
105+
/**
106+
* Contains all payment settings
107+
*/
108+
public static class Payment {
109+
public static final DiscordClientAction PREMIUM =
110+
new DiscordClientAction("discord://-/settings/premium");
111+
public static final DiscordClientAction SUBSCRIPTIONS =
112+
new DiscordClientAction("discord://-/settings/subscriptions");
113+
public static final DiscordClientAction INVENTORY =
114+
new DiscordClientAction("discord://-/settings/inventory");
115+
public static final DiscordClientAction BILLING =
116+
new DiscordClientAction("discord://-/settings/billing");
117+
}
118+
119+
/**
120+
* Contains all app settings
121+
*/
122+
public static class App {
123+
public static final DiscordClientAction APPEARANCE =
124+
new DiscordClientAction("discord://-/settings/appearance");
125+
public static final DiscordClientAction ACCESSIBILITY =
126+
new DiscordClientAction("discord://-/settings/accessibility");
127+
public static final DiscordClientAction VOICE =
128+
new DiscordClientAction("discord://-/settings/voice");
129+
public static final DiscordClientAction TEXT =
130+
new DiscordClientAction("discord://-/settings/text");
131+
public static final DiscordClientAction NOTIFICATIONS =
132+
new DiscordClientAction("discord://-/settings/notifications");
133+
public static final DiscordClientAction KEYBINDS =
134+
new DiscordClientAction("discord://-/settings/keybinds");
135+
public static final DiscordClientAction LOCALE =
136+
new DiscordClientAction("discord://-/settings/locale");
137+
138+
/** @see #LINUX */
139+
public static final DiscordClientAction WINDOWS =
140+
new DiscordClientAction("discord://-/settings/windows");
141+
142+
/** @see #WINDOWS */
143+
public static final DiscordClientAction LINUX =
144+
new DiscordClientAction("discord://-/settings/linux");
145+
146+
public static final DiscordClientAction STREAMER_MODE =
147+
new DiscordClientAction("discord://-/settings/streamer-mode");
148+
public static final DiscordClientAction ADVANCED =
149+
new DiscordClientAction("discord://-/settings/advanced");
150+
}
151+
152+
/**
153+
* Contains some of the more general settings
154+
*/
155+
public static class General {
156+
public static final DiscordClientAction ACTIVITY_STATUS =
157+
new DiscordClientAction("discord://-/settings/activity-status");
158+
public static final DiscordClientAction ACTIVITY_OVERLAY =
159+
new DiscordClientAction("discord://-/settings/overlay");
160+
public static final DiscordClientAction HYPESQUAD =
161+
new DiscordClientAction("discord://-/settings/hypesquad_online");
162+
public static final DiscordClientAction CHANGELOGS =
163+
new DiscordClientAction("discord://-/settings/changelogs");
164+
}
165+
}
166+
167+
public static class Library {
168+
public static final DiscordClientAction LIBRARY_GAMES =
169+
new DiscordClientAction("discord://-/library");
170+
public static final DiscordClientAction LIBRARY_SETTINGS =
171+
new DiscordClientAction("discord://-/library/settings");
172+
public static final DiscordClientAction LIBRARY_ITEM_ACTION =
173+
new DiscordClientAction("discord://-/library/{SKU-ID}/LAUNCH");
174+
public static final DiscordClientAction SKU_STORE_PAGE =
175+
new DiscordClientAction("discord://-/store/skus/{SKU-ID}");
176+
public static final DiscordClientAction APPLICATION_STORE_PAGE =
177+
new DiscordClientAction("discord://-/store/applications/{APPLICATION-ID}");
178+
}
179+
180+
/* pattern for the arguments, finds everything within {} */
181+
public final static Pattern argumentPattern = Pattern.compile("\\{[^}]*}");
182+
183+
private final String url;
184+
185+
@Contract(pure = true)
186+
private DiscordClientAction(String url) {
187+
this.url = url;
188+
}
189+
190+
/**
191+
* The raw URL without any arguments.
192+
*
193+
* <p>
194+
* Most likely you should use {@link #formatUrl(String...)} instead, that one throws when an
195+
* argument is lacking.
196+
*
197+
* @return A {@link String} of the URL
198+
*
199+
* @see #formatUrl(String...)
200+
*/
201+
public String getRawUrl() {
202+
return url;
203+
}
204+
205+
/**
206+
* Format's the URL with the given arguments.
207+
*
208+
* @param arguments An array of the arguments this action requires
209+
*
210+
* @return The formatted URL as an {@link String}
211+
*
212+
* @throws IllegalArgumentException When missing arguments
213+
*/
214+
public String formatUrl(String @NotNull... arguments) {
215+
String localUrl = url;
216+
217+
for (String argument : arguments) {
218+
localUrl = argumentPattern.matcher(localUrl).replaceFirst(argument);
219+
}
220+
221+
if (argumentPattern.matcher(localUrl).find()) {
222+
throw new IllegalArgumentException("Missing arguments for URL " + localUrl + "!");
223+
}
224+
225+
return localUrl;
226+
}
227+
228+
/**
229+
* Format's the action as a link button.
230+
*
231+
* @param label The label of the button, see {@link Button#link(String, String)} for the
232+
* requirements
233+
* @param arguments An array of the arguments this action requires
234+
*
235+
* @return A {@link Button} of {@link ButtonStyle#LINK} with the given label
236+
*
237+
* @throws IllegalArgumentException When missing arguments
238+
*/
239+
public Button asLinkButton(@NotNull String label, String... arguments) {
240+
return Button.link(formatUrl(arguments), label);
241+
}
242+
}

0 commit comments

Comments
 (0)