diff --git a/src/main/java/cc/fascinated/bat/Emojis.java b/src/main/java/cc/fascinated/bat/Emojis.java new file mode 100644 index 0000000..b358b2d --- /dev/null +++ b/src/main/java/cc/fascinated/bat/Emojis.java @@ -0,0 +1,27 @@ +package cc.fascinated.bat; + +import cc.fascinated.bat.service.DiscordService; +import lombok.extern.log4j.Log4j2; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.emoji.Emoji; + +/** + * @author Fascinated (fascinated7) + */ +@Log4j2 +public class Emojis { + public static final Emoji SPOTIFY_EMOJI; + public static final Emoji CHECK_MARK_EMOJI; + public static final Emoji CROSS_MARK_EMOJI; + public static final Emoji SAD_FACE_EMOJI; + + static { + log.info("Loading emojis..."); + JDA jda = DiscordService.JDA; + SPOTIFY_EMOJI = jda.getEmojiById("1256629771975266479"); + CHECK_MARK_EMOJI = jda.getEmojiById("1256633734065557676"); + CROSS_MARK_EMOJI = jda.getEmojiById("1256634487429922897"); + SAD_FACE_EMOJI = jda.getEmojiById("1256636078258131055"); + log.info("Loaded emojis!"); + } +} diff --git a/src/main/java/cc/fascinated/bat/command/impl/fun/image/DuckSubCommand.java b/src/main/java/cc/fascinated/bat/command/impl/fun/image/DuckSubCommand.java index 26d2121..73f4cc6 100644 --- a/src/main/java/cc/fascinated/bat/command/impl/fun/image/DuckSubCommand.java +++ b/src/main/java/cc/fascinated/bat/command/impl/fun/image/DuckSubCommand.java @@ -7,7 +7,6 @@ import cc.fascinated.bat.common.WebRequest; import cc.fascinated.bat.model.BatGuild; import cc.fascinated.bat.model.BatUser; import cc.fascinated.bat.model.token.randomd.RandomDuck; -import cc.fascinated.bat.model.token.thecatapi.CatImageToken; import lombok.NonNull; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; diff --git a/src/main/java/cc/fascinated/bat/exception/spotify/SpotifyForbiddenException.java b/src/main/java/cc/fascinated/bat/exception/spotify/SpotifyTokenRefreshException.java similarity index 59% rename from src/main/java/cc/fascinated/bat/exception/spotify/SpotifyForbiddenException.java rename to src/main/java/cc/fascinated/bat/exception/spotify/SpotifyTokenRefreshException.java index 897ba17..e363d4c 100644 --- a/src/main/java/cc/fascinated/bat/exception/spotify/SpotifyForbiddenException.java +++ b/src/main/java/cc/fascinated/bat/exception/spotify/SpotifyTokenRefreshException.java @@ -6,8 +6,8 @@ import lombok.experimental.StandardException; * @author Fascinated (fascinated7) */ @StandardException -public class SpotifyForbiddenException extends RuntimeException { - public SpotifyForbiddenException(String message) { +public class SpotifyTokenRefreshException extends RuntimeException { + public SpotifyTokenRefreshException(String message) { super(message); } } \ No newline at end of file diff --git a/src/main/java/cc/fascinated/bat/features/spotify/SpotifyFeature.java b/src/main/java/cc/fascinated/bat/features/spotify/SpotifyFeature.java index 06a220f..8529cae 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/SpotifyFeature.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/SpotifyFeature.java @@ -1,5 +1,6 @@ package cc.fascinated.bat.features.spotify; +import cc.fascinated.bat.Emojis; import cc.fascinated.bat.command.Category; import cc.fascinated.bat.common.EmbedUtils; import cc.fascinated.bat.features.Feature; @@ -24,7 +25,7 @@ public class SpotifyFeature extends Feature { */ public static MessageEmbed linkAccountEmbed() { return EmbedUtils.genericEmbed() - .setDescription("You need to link your Spotify account before you can use this command.") + .setDescription("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI)) .build(); } } diff --git a/src/main/java/cc/fascinated/bat/features/spotify/command/CurrentSubCommand.java b/src/main/java/cc/fascinated/bat/features/spotify/command/CurrentSubCommand.java index b79f091..2599e49 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/command/CurrentSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/command/CurrentSubCommand.java @@ -1,5 +1,6 @@ package cc.fascinated.bat.features.spotify.command; +import cc.fascinated.bat.Emojis; import cc.fascinated.bat.command.BatSubCommand; import cc.fascinated.bat.command.CommandInfo; import cc.fascinated.bat.common.EmbedUtils; @@ -44,7 +45,7 @@ public class CurrentSubCommand extends BatSubCommand { if (!spotifyService.hasTrackPlaying(user)) { interaction.replyEmbeds(EmbedUtils.errorEmbed() - .setDescription("You are not currently playing a track.") + .setDescription("%s You are not currently playing a track.".formatted(Emojis.CROSS_MARK_EMOJI)) .build()) .queue(); return; diff --git a/src/main/java/cc/fascinated/bat/features/spotify/command/LinkSubCommand.java b/src/main/java/cc/fascinated/bat/features/spotify/command/LinkSubCommand.java index e92027f..9998579 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/command/LinkSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/command/LinkSubCommand.java @@ -1,5 +1,7 @@ package cc.fascinated.bat.features.spotify.command; +import cc.fascinated.bat.Consts; +import cc.fascinated.bat.Emojis; import cc.fascinated.bat.command.BatSubCommand; import cc.fascinated.bat.command.CommandInfo; import cc.fascinated.bat.common.EmbedUtils; @@ -38,25 +40,33 @@ public class LinkSubCommand extends BatSubCommand implements EventListener { @Override public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) { + if (!user.getId().equals(Consts.BOT_OWNER)) { + interaction.replyEmbeds(EmbedUtils.genericEmbed() + .setDescription(""" + %s We are currently awaiting Spotify's approval for our application. Please check back later. + Submitted on: + """.formatted(Emojis.CROSS_MARK_EMOJI)) + .build()).queue(); + return; + } + SpotifyProfile profile = user.getProfile(SpotifyProfile.class); + if (profile.hasLinkedAccount()) { + interaction.replyEmbeds(EmbedUtils.errorEmbed() + .setDescription("%s You have already linked your Spotify account!".formatted(Emojis.CROSS_MARK_EMOJI)) + .build()) + .setEphemeral(true) + .queue(); + return; + } + interaction.replyEmbeds(EmbedUtils.genericEmbed() - .setDescription("We are currently awaiting Spotify's approval for our application. Please check back later.") - .build()).queue(); -// SpotifyProfile profile = user.getProfile(SpotifyProfile.class); -// if (profile.hasLinkedAccount()) { -// interaction.replyEmbeds(EmbedUtils.errorEmbed() -// .setDescription("You have already linked your Spotify account!") -// .build()) -// .setEphemeral(true) -// .queue(); -// return; -// } -// -// interaction.replyEmbeds(EmbedUtils.genericEmbed() -// .setDescription("You can link your Spotify account by clicking [here](%s)".formatted(spotifyService.getAuthorizationUrl())) -// .build()) -// .addComponents(ActionRow.of(Button.primary("spotify_link", "Link Spotify"))) -// .setEphemeral(true) -// .queue(); + .setDescription("%s You can link your Spotify account by clicking [here](%s)".formatted( + Emojis.SPOTIFY_EMOJI.getFormatted(), + spotifyService.getAuthorizationUrl() + )).build()) + .addComponents(ActionRow.of(Button.primary("spotify_link", "Link Code").withEmoji(Emojis.SPOTIFY_EMOJI))) + .setEphemeral(true) + .queue(); } @Override @@ -91,8 +101,8 @@ public class LinkSubCommand extends BatSubCommand implements EventListener { String code = codeMapping.getAsString(); spotifyService.linkAccount(user, code); event.replyEmbeds(EmbedUtils.successEmbed() - .setDescription("Successfully linked your Spotify account!") - .build()) + .setDescription("%s You have linked your Spotify account!".formatted(Emojis.CHECK_MARK_EMOJI.getFormatted())) + .build()) .setEphemeral(true) .queue(); } diff --git a/src/main/java/cc/fascinated/bat/features/spotify/command/PauseSubCommand.java b/src/main/java/cc/fascinated/bat/features/spotify/command/PauseSubCommand.java index c60c015..1c7ed41 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/command/PauseSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/command/PauseSubCommand.java @@ -1,5 +1,6 @@ package cc.fascinated.bat.features.spotify.command; +import cc.fascinated.bat.Emojis; import cc.fascinated.bat.command.BatSubCommand; import cc.fascinated.bat.command.CommandInfo; import cc.fascinated.bat.common.EmbedUtils; @@ -38,7 +39,7 @@ public class PauseSubCommand extends BatSubCommand { if (!spotifyService.hasTrackPlaying(user)) { interaction.replyEmbeds(EmbedUtils.errorEmbed() - .setDescription("You need to be playing a track to pause it.") + .setDescription("%s You need to be playing a track to pause it.".formatted(Emojis.CROSS_MARK_EMOJI)) .build()) .queue(); return; @@ -46,7 +47,8 @@ public class PauseSubCommand extends BatSubCommand { boolean didPause = spotifyService.pausePlayback(user); interaction.replyEmbeds(EmbedUtils.successEmbed() - .setDescription(didPause ? "Paused the current track." : "The current track is already paused.") + .setDescription(didPause ? ":pause_button: Paused the current track.".formatted(Emojis.CHECK_MARK_EMOJI) : + "%s The current track is already paused.".formatted(Emojis.CROSS_MARK_EMOJI)) .build()) .queue(); } diff --git a/src/main/java/cc/fascinated/bat/features/spotify/command/ResumeSubCommand.java b/src/main/java/cc/fascinated/bat/features/spotify/command/ResumeSubCommand.java index f341d99..3234477 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/command/ResumeSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/command/ResumeSubCommand.java @@ -1,5 +1,6 @@ package cc.fascinated.bat.features.spotify.command; +import cc.fascinated.bat.Emojis; import cc.fascinated.bat.command.BatSubCommand; import cc.fascinated.bat.command.CommandInfo; import cc.fascinated.bat.common.EmbedUtils; @@ -38,7 +39,7 @@ public class ResumeSubCommand extends BatSubCommand { if (!spotifyService.hasTrackPlaying(user)) { interaction.replyEmbeds(EmbedUtils.errorEmbed() - .setDescription("You need to be playing a track to resume it.") + .setDescription("%s You need to be playing a track to resume it.".formatted(Emojis.CROSS_MARK_EMOJI)) .build()) .queue(); return; @@ -46,7 +47,8 @@ public class ResumeSubCommand extends BatSubCommand { boolean didPause = spotifyService.resumePlayback(user); interaction.replyEmbeds(EmbedUtils.successEmbed() - .setDescription(didPause ? "Resumed the current track." : "The current track is already playing.") + .setDescription(didPause ? "%s Resumed the current track.".formatted(Emojis.CHECK_MARK_EMOJI) : + "%s The current track is already playing.".formatted(Emojis.CROSS_MARK_EMOJI)) .build()) .queue(); } diff --git a/src/main/java/cc/fascinated/bat/features/spotify/command/UnlinkSubCommand.java b/src/main/java/cc/fascinated/bat/features/spotify/command/UnlinkSubCommand.java index bdae693..ef0c3c3 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/command/UnlinkSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/command/UnlinkSubCommand.java @@ -1,5 +1,6 @@ package cc.fascinated.bat.features.spotify.command; +import cc.fascinated.bat.Emojis; import cc.fascinated.bat.command.BatSubCommand; import cc.fascinated.bat.command.CommandInfo; import cc.fascinated.bat.common.EmbedUtils; @@ -33,7 +34,7 @@ public class UnlinkSubCommand extends BatSubCommand implements EventListener { SpotifyProfile profile = user.getProfile(SpotifyProfile.class); if (!profile.hasLinkedAccount()) { interaction.replyEmbeds(EmbedUtils.errorEmbed() - .setDescription("You do not have a linked Spotify account.") + .setDescription("%s You do not have a linked Spotify account.".formatted(Emojis.CROSS_MARK_EMOJI)) .build()) .setEphemeral(true) .queue(); @@ -43,7 +44,7 @@ public class UnlinkSubCommand extends BatSubCommand implements EventListener { profile.reset(); userService.saveUser(user); interaction.replyEmbeds(EmbedUtils.successEmbed() - .setDescription("Successfully unlinked your Spotify account.") + .setDescription("%s Successfully unlinked your Spotify account.".formatted(Emojis.CHECK_MARK_EMOJI)) .build()) .setEphemeral(true) .queue(); diff --git a/src/main/java/cc/fascinated/bat/model/token/randomd/RandomDuck.java b/src/main/java/cc/fascinated/bat/model/token/randomd/RandomDuck.java index a5f34c7..a3f3b31 100644 --- a/src/main/java/cc/fascinated/bat/model/token/randomd/RandomDuck.java +++ b/src/main/java/cc/fascinated/bat/model/token/randomd/RandomDuck.java @@ -1,7 +1,6 @@ package cc.fascinated.bat.model.token.randomd; import lombok.Getter; -import lombok.Setter; /** * @author Fascinated (fascinated7) diff --git a/src/main/java/cc/fascinated/bat/service/CommandService.java b/src/main/java/cc/fascinated/bat/service/CommandService.java index 9c97498..aadacb3 100644 --- a/src/main/java/cc/fascinated/bat/service/CommandService.java +++ b/src/main/java/cc/fascinated/bat/service/CommandService.java @@ -216,7 +216,7 @@ public class CommandService extends ListenerAdapter { log.error("An error occurred while executing command \"{}\"", commandName, ex); event.replyEmbeds(EmbedUtils.successEmbed() - .setDescription("An error occurred while executing the command\n\n" + ex.getLocalizedMessage()) + .setDescription("An error occurred while executing the command:\n```java%s```".formatted(ex.getLocalizedMessage())) .build()) .queue(); } diff --git a/src/main/java/cc/fascinated/bat/service/DiscordService.java b/src/main/java/cc/fascinated/bat/service/DiscordService.java index fa0d4c8..192b03b 100644 --- a/src/main/java/cc/fascinated/bat/service/DiscordService.java +++ b/src/main/java/cc/fascinated/bat/service/DiscordService.java @@ -40,13 +40,12 @@ public class DiscordService { JDA = JDABuilder.create(token, EnumSet.of( GatewayIntent.GUILD_MESSAGES, GatewayIntent.MESSAGE_CONTENT, - GatewayIntent.GUILD_MEMBERS + GatewayIntent.GUILD_MEMBERS, + GatewayIntent.GUILD_EMOJIS_AND_STICKERS )) .disableCache( CacheFlag.ACTIVITY, CacheFlag.VOICE_STATE, - CacheFlag.EMOJI, - CacheFlag.STICKER, CacheFlag.CLIENT_STATUS, CacheFlag.ONLINE_STATUS, CacheFlag.SCHEDULED_EVENTS diff --git a/src/main/java/cc/fascinated/bat/service/SpotifyService.java b/src/main/java/cc/fascinated/bat/service/SpotifyService.java index 42f28a5..839e9a9 100644 --- a/src/main/java/cc/fascinated/bat/service/SpotifyService.java +++ b/src/main/java/cc/fascinated/bat/service/SpotifyService.java @@ -1,6 +1,7 @@ package cc.fascinated.bat.service; import cc.fascinated.bat.common.StringUtils; +import cc.fascinated.bat.exception.spotify.SpotifyTokenRefreshException; import cc.fascinated.bat.features.spotify.profile.SpotifyProfile; import cc.fascinated.bat.model.BatUser; import lombok.Getter; @@ -12,6 +13,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import se.michaelthelin.spotify.SpotifyApi; import se.michaelthelin.spotify.enums.AuthorizationScope; +import se.michaelthelin.spotify.exceptions.SpotifyWebApiException; import se.michaelthelin.spotify.model_objects.credentials.AuthorizationCodeCredentials; import se.michaelthelin.spotify.model_objects.miscellaneous.CurrentlyPlaying; @@ -81,12 +83,9 @@ public class SpotifyService { * @param user the user to check * @return the currently playing track */ + @SneakyThrows public CurrentlyPlaying getCurrentlyPlayingTrack(BatUser user) { - try { - return getSpotifyApi(user).getUsersCurrentlyPlayingTrack().build().execute(); - } catch (Exception e) { - throw new RuntimeException("Failed to get currently playing track", e); - } + return getSpotifyApi(user).getUsersCurrentlyPlayingTrack().build().execute(); } /** @@ -117,13 +116,10 @@ public class SpotifyService { * @param user the user to start playback for * @return if the playback was paused */ + @SneakyThrows public boolean resumePlayback(BatUser user) { - try { - getSpotifyApi(user).startResumeUsersPlayback().build().execute(); - return true; - } catch (Exception e) { - throw new RuntimeException("Failed to resume playback", e); - } + getSpotifyApi(user).startResumeUsersPlayback().build().execute(); + return true; } /** @@ -177,10 +173,7 @@ public class SpotifyService { public SpotifyApi getSpotifyApi(BatUser user) { SpotifyProfile profile = user.getProfile(SpotifyProfile.class); ensureValidToken(profile, user); - return new SpotifyApi.Builder() - .setAccessToken(profile.getAccessToken()) - .setRefreshToken(profile.getRefreshToken()) - .build(); + return new SpotifyApi.Builder().setAccessToken(profile.getAccessToken()).build(); } /** @@ -193,10 +186,20 @@ public class SpotifyService { if (profile.getExpiresAt() == null || profile.getExpiresAt() > System.currentTimeMillis()) { return; } - AuthorizationCodeCredentials credentials = spotifyApi.authorizationCodeRefresh().build().execute(); - profile.setAccessToken(credentials.getAccessToken()); - profile.setRefreshToken(credentials.getRefreshToken()); - profile.setExpiresAt(System.currentTimeMillis() + (credentials.getExpiresIn() * 1000)); - userService.saveUser(user); + SpotifyApi api = new SpotifyApi.Builder() + .setClientId(clientId) + .setClientSecret(clientSecret) + .setAccessToken(profile.getAccessToken()) + .setRefreshToken(profile.getRefreshToken()) + .build(); + try { + AuthorizationCodeCredentials credentials = api.authorizationCodeRefresh().build().execute(); + profile.setAccessToken(credentials.getAccessToken()); + profile.setExpiresAt(System.currentTimeMillis() + (credentials.getExpiresIn() * 1000)); + userService.saveUser(user); + } catch (SpotifyWebApiException ex) { + log.error("Failed to refresh Spotify token", ex); + throw new SpotifyTokenRefreshException("Failed to refresh Spotify token", ex); + } } }