Skip to content

Commit

Permalink
Refactor Spotify song handling and add DieCommand for enhanced user i…
Browse files Browse the repository at this point in the history
…nteraction
  • Loading branch information
andre-carbajal committed Feb 8, 2025
1 parent 4627d3b commit a9cde8d
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 68 deletions.
6 changes: 1 addition & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@ COPY pom.xml .
RUN mvn dependency:resolve

COPY src ./src
RUN mvn compile
RUN mvn package

FROM eclipse-temurin:21-jre

WORKDIR /app

COPY --from=build /app/target/*.jar /app/NaviMusic.jar

ENV DISCORD_TOKEN=""
ENV SPOTIFY_CLIENT_ID=""
ENV SPOTIFY_SECRET=""

ENTRYPOINT ["java", "-Xmx512m", "-jar", "/app/NaviMusic.jar", "nogui"]
48 changes: 11 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NaviMusic: Your Personal Music Bot for Discord

Welcome to NaviMusic, a highly user-friendly music bot for Discord. Developed using Discord4J, NaviMusic offers a
Welcome to NaviMusic, a highly user-friendly music bot for Discord. Developed using JDA, NaviMusic offers a
seamless music experience for your Discord server.

## Table of Contents
Expand Down Expand Up @@ -29,44 +29,25 @@ Before you begin, ensure you have the following installed on your machine:
Replace x.y with the version number of the last release.
{nogui} is an optional argument to run the bot without the GUI.

First execute the bot with all the environment variables(DISCORD_TOKEN, SPOTIFY_CLIENT_ID, SPOTIFY_SECRET)
Later follow the steps to get the YOUTUBE_OAUTH2_CODE
Finally you need to configure your YOUTUBE_OAUTH2_CODE on the environment variables
First you need to get the YOUTUBE_PO_TOKEN, YOUTUBE_VISITOR. You can get them with [this generator](https://github.com/iv-org/youtube-trusted-session-generator)
Then you need to get the YOUTUBE_OAUTH2_CODE. You can get it by running the bot and following the steps.
- Execute the bot with the environment variables(DISCORD_TOKEN, SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, YOUTUBE_POTOKEN, YOUTUBE_VISITOR) and YOUTUBE_OAUTH2 set to null
- Follow the steps in the console
Finally execute the bot with all the environment variables(DISCORD_TOKEN, SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, YOUTUBE_POTOKEN, YOUTUBE_VISITOR, YOUTUBE_OAUTH2)

### With environment variables

- Set the following environment variables:
- DISCORD_TOKEN: Your Discord bot token
- SPOTIFY_CLIENT_ID: Your Spotify client ID
- SPOTIFY_SECRET: Your Spotify secret
- Run the bot

```bash
java -jar NaviMusic-x.y.jar {nogui}
```

- Complete the steps to get the YOUTUBE_OAUTH2_CODE
- Set the following environment variables:
- SPOTIFY_CLIENT_SECRET: Your Spotify secret
- YOUTUBE_POTOKEN: Your Youtube PO token
- YOUTUBE_VISITOR: Your Youtube visitor
- YOUTUBE_OAUTH2_CODE: Your Youtube OAuth2 code
- Run the bot again

```bash
java -jar NaviMusic-x.y.jar {nogui}
```

### With command line arguments

- Run the bot

```bash
java -jar NaviMusic-x.y.jar DISCORD_TOKEN=your_discord_token SPOTIFY_CLIENT_ID=your_spotify_client_id SPOTIFY_SECRET=your_spotify_secret {nogui}
```

- Complete the steps to get the YOUTUBE_OAUTH2_CODE
- Run the bot again

```bash
java -jar NaviMusic-x.y.jar DISCORD_TOKEN=your_discord_token SPOTIFY_CLIENT_ID=your_spotify_client_id SPOTIFY_SECRET=your_spotify_secret YOUTUBE_OAUTH2_CODE=your_youtube_oauth2_code {nogui}
java -jar NaviMusic-x.y.jar {nogui}
```

## Running the Application with Docker
Expand All @@ -80,14 +61,7 @@ docker pull anvian/navi-music
- Run the Docker container, passing your Discord, Spotify Client ID, and Spotify Secret tokens as arguments:

```bash
docker run anvian/navi-music -e DISCORD_TOKEN=your_discord_token SPOTIFY_CLIENT_ID=your_spotify_client_id SPOTIFY_SECRET=your_spotify_secret
```

- Complete the steps to get the YOUTUBE_OAUTH2_CODE
- Run the Docker container again, passing your Youtube OAuth2 code as an argument:

```bash
docker run anvian/navi-music -e DISCORD_TOKEN=your_discord_token SPOTIFY_CLIENT_ID=your_spotify_client_id SPOTIFY_SECRET=your_spotify_secret YOUTUBE_OAUTH2_CODE=your_youtube_oauth2_code
docker run anvian/navi-music -e DISCORD_TOKEN=your_discord_token SPOTIFY_CLIENT_ID=your_spotify_client_id SPOTIFY_CLIENT_SECRET=your_spotify_secret YOUTUBE_POTOKEN=your_youtube_potoken YOUTUBE_VISITOR=your_youtube_visitor YOUTUBE_OAUTH2_CODE=your_youtube_oauth2_code
```

## License
Expand Down
5 changes: 4 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Release Notes

- Fixing audio reproduction.
- Updated to version 3.0
- Port the bot to Spring Boot
- Play from file command removed
- Die command added
13 changes: 0 additions & 13 deletions docker-compose.yml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void playlistLoaded(AudioPlaylist playlist) {
RichResponse r = new RichResponse();

r.setTitle("Adding Spotify song to queue");
r.setText(String.format("[%s](%s) by `%s`", song.title(), song.url(), song.getArtists()));
r.setText(String.format("%s by `%s`", song.title(), song.getArtists()));

List<MessageEmbed.Field> fields = new ArrayList<>();
fields.add(new MessageEmbed.Field("Duration", new VideoInfo(playlist.getTracks().getFirst().getInfo()).durationToReadable(), true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public SpotifySong fetchSong(String url) {
String id = getID(url);
CompletableFuture<Track> trackFuture = spotify.getTrack(id).build().executeAsync();
Track track = trackFuture.join();
return new SpotifySong(track.getName(), track.getArtists(), uriToUrl(track.getUri()));
return new SpotifySong(track.getName(), track.getArtists());
} catch (Exception e) {
log.error("Error when fetching spotify song `{}`: {}", getID(url), e.getMessage());
return null;
Expand All @@ -64,7 +64,7 @@ public SpotifyPlaylist fetchPlaylist(String url) {

List<SpotifySong> songs = new ArrayList<>();
for (Track track : tracks)
songs.add(new SpotifySong(track.getName(), track.getArtists(), uriToUrl(track.getUri())));
songs.add(new SpotifySong(track.getName(), track.getArtists()));

return new SpotifyPlaylist(playlist.getName(), songs.toArray(SpotifySong[]::new));
} catch (Exception e) {
Expand All @@ -79,7 +79,7 @@ public SpotifyPlaylist fetchAlbum(String url) {
CompletableFuture<Album> albumFuture = spotify.getAlbum(getID(url)).build().executeAsync();
Album album = albumFuture.get();
for (TrackSimplified track : album.getTracks().getItems())
songs.add(new SpotifySong(track.getName(), track.getArtists(), uriToUrl(track.getUri())));
songs.add(new SpotifySong(track.getName(), track.getArtists()));

return new SpotifyPlaylist(album.getName(), songs.toArray(SpotifySong[]::new));
} catch (Exception e) {
Expand All @@ -88,10 +88,6 @@ public SpotifyPlaylist fetchAlbum(String url) {
}
}

private String uriToUrl(String uri) {
return "https://open.spotify.com/track/" + uri.substring(uri.lastIndexOf(":") + 1);
}

private String getID(String link) {
if (!ifValidSpotifyLink(link)) return "";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import se.michaelthelin.spotify.model_objects.specification.ArtistSimplified;

public record SpotifySong(String title, ArtistSimplified[] artists, String url) {
public record SpotifySong(String title, ArtistSimplified[] artists) {

public String getArtists() {
StringBuilder artists = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package net.andrecarbajal.naviMusic.commands.general;

import net.andrecarbajal.naviMusic.commands.SlashCommand;
import net.andrecarbajal.naviMusic.dto.response.RichResponse;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;

@Component
public class DieCommand extends SlashCommand {
public DieCommand() {
super("die", "Rolls a die", Category.GENERAL);
addOption(new OptionData(OptionType.INTEGER, "sides", "Number of sides on the die", false));
}

@Override
public void onCommand(SlashCommandInteractionEvent event) {
Member member = event.getMember();
assert member != null;

int sides = event.getOption("sides") == null ? 6 : (int) event.getOption("sides").getAsLong();
int roll = (int) (Math.random() * sides) + 1;

RichResponse.builder()
.title(String.format("Roll of a %d-sided die", sides))
.text(String.format("%s rolled a %d", member.getEffectiveName(), roll))
.build()
.sendReply(event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ public AudioPlayerManager setupAudioSources() {
new IosWithThumbnail()
);

youtube.useOauth2(oAuthToken, true);


if (!oAuthToken.equals("null")){
youtube.useOauth2(oAuthToken, true);
} else {
youtube.useOauth2(null, false);
}

playerManager.registerSourceManager(youtube);

Expand Down

0 comments on commit a9cde8d

Please sign in to comment.