From b2a2840ca08e62fc85737ec6bcf95d63737eeb2e Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:33 -0700 Subject: Added images to README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b1e12e..8a6e3e9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # VStreamTrack -A Java JDA Bot for Tracking VTuber Livestreams and Schedules \ No newline at end of file +A Java JDA Bot for Tracking VTuber Livestreams and Schedules + +# ![image](https://user-images.githubusercontent.com/21994085/230703769-7c88c760-b81f-4798-883f-475c42d97fe1.png) +# ![image](https://user-images.githubusercontent.com/21994085/230703785-7cb3eb80-a1de-4b46-af81-0b9a7820ab5d.png) -- cgit v1.2.3 From 751b5b8d53dbd63de5a1dbf4395e0f1653d7f200 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:33 -0700 Subject: Create config.json --- settings/config.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 settings/config.json diff --git a/settings/config.json b/settings/config.json new file mode 100644 index 0000000..661c5aa --- /dev/null +++ b/settings/config.json @@ -0,0 +1,4 @@ +{ + "discordToken": "BOT_TOKEN", + "holodexAPIKey": "HOLODEX_API_KEY" +} -- cgit v1.2.3 From 5a03b728eef4c843d27c3ec19c44da5c9a9e636c Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:33 -0700 Subject: Fix bug where if channel doesn't have an english name on holodex it is printed as null in chat The Japanese name will be used if an English name is unavailable --- src/main/java/builders/ScheduleMessageBuilder.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/builders/ScheduleMessageBuilder.java b/src/main/java/builders/ScheduleMessageBuilder.java index 9dd77bf..eb47118 100644 --- a/src/main/java/builders/ScheduleMessageBuilder.java +++ b/src/main/java/builders/ScheduleMessageBuilder.java @@ -23,7 +23,7 @@ public class ScheduleMessageBuilder { String pfp = videos.get(0).channel.photo; EmbedBuilder messageBuilder = new EmbedBuilder() .setThumbnail(pfp) - .setTitle("Upcoming and Live Streams for " + videos.get(0).channel.org) + .setTitle("Upcoming and Live Streams") .setDescription("The schedule you asked for") .setColor(new Color(COLOR)) .setTimestamp(OffsetDateTime.now()); @@ -36,6 +36,9 @@ public class ScheduleMessageBuilder { unixTimeStr = "LIVE \uD83D\uDD34"; } String titleText = video.channel.english_name + " - " + unixTimeStr; + if (video.channel.english_name.equals(null)){ + titleText = video.channel.name + " - " + unixTimeStr; + } String videoURL = "https://www.youtube.com/watch?v=" + video.id; messageBuilder.addField(titleText, "["+video.title+"]"+"("+videoURL+")", false); } @@ -46,10 +49,14 @@ public class ScheduleMessageBuilder { public ArrayList getUpcomingLiveListMessages(List simpleVideos){ ArrayList messageEmbeds = new ArrayList<>(); for (SimpleVideo video : simpleVideos){ - String title = video.channel.english_name + " is streaming soon! ⏰"; + String channel_name = video.channel.english_name; + if (channel_name.equals(null)){ + channel_name = video.channel.name; + } + String title = channel_name + " is streaming soon! ⏰"; String fieldTitle = "Scheduled Start Time"; if (video.status.equals("live")){ - title = video.channel.english_name + " is live! \uD83D\uDD34"; + title = channel_name + " is live! \uD83D\uDD34"; fieldTitle = "Live Since"; } String gmtStartTime = video.start_scheduled; -- cgit v1.2.3 From 360c7bc1e417b0a43804d6557ed7cd905123214d Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:33 -0700 Subject: Update README with instructions on steps for configuration --- README.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a6e3e9..e572a0f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,30 @@ # VStreamTrack -A Java JDA Bot for Tracking VTuber Livestreams and Schedules +A Java JDA Bot for Tracking VTuber Livestreams and Schedules. + +## Dependencies +- [JDA](https://github.com/DV8FromTheWorld/JDA) +- [JHolodex](https://github.com/pinapelz/JHolodex) + +## Usage +- Clone and build the project using Maven +- Create a file called `config.json` in the settings folder of the root directory (if it doesn't already exist) +- Fill in necessary credentials and settings in the config file +- Create a file called 'upcomingChannels.txt' in the settings folder of the root directory (if it doesn't already exist) + +### Configuring Custom Feeds +``` +[TYPE]:[INFORMATION]:[DISCORD_CHANNEL_ID] +TYPE: org (organization name) or channel (individual channel) +INFORMATION: If TYPE is channel: insert channel ID. If TYPE is org: insert organization name. +DISCORD_CHANNEL_ID: The ID of the Discord channel you want the feed to be sent to. + +EXAMPLE: +org:Nijisanji:1055710959919976479 +(All upcoming and live streams for members of the Nijisanji organization will be sent to the Discord channel with ID 1055710959919976479) + +channel:UC4WvIIAo89_AzGUh1AZ6Dkg:1094112349163638804 +(All upcoming and live streams for the channel with ID UC4WvIIAo89_AzGUh1AZ6Dkg will be sent to the Discord channel with ID 1094112349163638804) +``` # ![image](https://user-images.githubusercontent.com/21994085/230703769-7c88c760-b81f-4798-883f-475c42d97fe1.png) # ![image](https://user-images.githubusercontent.com/21994085/230703785-7cb3eb80-a1de-4b46-af81-0b9a7820ab5d.png) -- cgit v1.2.3 From f7677bf0ef1357336753b5c073d504b7c05bbc73 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:34 -0700 Subject: Fixed bug where Channel Feed was not being cleared for hours Channels were not being cleared if a channel did not have a specific update (i.e new upcoming or currently live) leaving old streams in feed for hours --- src/main/java/Main.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 78a2f4d..6fdaf1e 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -30,12 +30,9 @@ public class Main extends ListenerAdapter{ commandManager = new CommandManager(fileDataProcessor.readCredential("holodexAPIKey")); jdaBuilder = JDABuilder.createDefault(fileDataProcessor.readCredential("discordToken")); jdaBuilder.addEventListeners(commandManager); + jdaBuilder.addEventListeners(this); try { jda = jdaBuilder.build(); - statusHandler = new StatusHandler(jda); - statusHandler.updateSlashCommands(); - System.out.println("Bot is ready!"); - initializeAutoRefresh(); } catch (LoginException e) { System.out.println("Unable to login with the provided token. Please check your token and try again."); @@ -56,18 +53,19 @@ public class Main extends ListenerAdapter{ } for (OrgChannelTuple orgChannelTuple : refreshChannels) { System.out.println("Refreshing " + orgChannelTuple.getType() + " " + orgChannelTuple.getName()); + jda.getTextChannelById(orgChannelTuple.getDiscordChannelId()).purgeMessages( + jda.getTextChannelById(orgChannelTuple.getDiscordChannelId()).getIterableHistory().complete()); List messageEmbeds = commandManager.updateUpcomingChannel(orgChannelTuple.getName(), orgChannelTuple.getType()); if (messageEmbeds.size() == 0) { continue; } - jda.getTextChannelById(orgChannelTuple.getDiscordChannelId()).purgeMessages( - jda.getTextChannelById(orgChannelTuple.getDiscordChannelId()).getIterableHistory().complete()); for (MessageEmbed messageEmbed : messageEmbeds) { jda.getTextChannelById(orgChannelTuple.getDiscordChannelId()).sendMessageEmbeds(messageEmbed).queue(); } } } catch(NullPointerException ex){ + System.out.println(ex); System.out.println("Channel is empty. Skipping refresh there"); } catch (Exception e) { @@ -85,6 +83,15 @@ public class Main extends ListenerAdapter{ String msg = message.getContentDisplay(); } + + @Override + public void onReady(net.dv8tion.jda.api.events.ReadyEvent event) { + System.out.println("Logged in as " + event.getJDA().getSelfUser().getAsTag()); + statusHandler = new StatusHandler(jda); + statusHandler.updateSlashCommands(); + initializeAutoRefresh(); + System.out.println("Bot is ready!"); + } public static void main(String args[]) { Main main = new Main(); main.initializeBot(); -- cgit v1.2.3 From b4f77ba3b305264fafe7037625894c7dc0b592ae Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:34 -0700 Subject: Add Live_Viewer count to currently live embeds --- src/main/java/builders/ScheduleMessageBuilder.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/builders/ScheduleMessageBuilder.java b/src/main/java/builders/ScheduleMessageBuilder.java index eb47118..4f5f78c 100644 --- a/src/main/java/builders/ScheduleMessageBuilder.java +++ b/src/main/java/builders/ScheduleMessageBuilder.java @@ -3,6 +3,7 @@ package builders; import com.pina.datatypes.SimpleVideo; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.MessageEmbed; +import java.text.NumberFormat; import java.awt.*; import java.time.OffsetDateTime; @@ -11,6 +12,7 @@ import java.util.List; public class ScheduleMessageBuilder { private int COLOR = 8805674; + private NumberFormat numberFormat = NumberFormat.getInstance(); public MessageEmbed buildLiveAndUpcomingMessage(List videos){ if (videos.size() == 0){ return new EmbedBuilder() @@ -31,7 +33,7 @@ public class ScheduleMessageBuilder { for (SimpleVideo video : videos){ String gmtStartTime = video.start_scheduled; long unixTime = OffsetDateTime.parse(gmtStartTime).toEpochSecond(); - String unixTimeStr = " ⏰"; + String unixTimeStr = " ⏰"; if (video.status.equals("live")){ unixTimeStr = "LIVE \uD83D\uDD34"; } @@ -40,7 +42,7 @@ public class ScheduleMessageBuilder { titleText = video.channel.name + " - " + unixTimeStr; } String videoURL = "https://www.youtube.com/watch?v=" + video.id; - messageBuilder.addField(titleText, "["+video.title+"]"+"("+videoURL+")", false); + messageBuilder.addField(titleText, "["+video.title+"]"+"("+videoURL+")", true); } return messageBuilder.build(); @@ -55,19 +57,24 @@ public class ScheduleMessageBuilder { } String title = channel_name + " is streaming soon! ⏰"; String fieldTitle = "Scheduled Start Time"; + String viewerText = "Not Live Yet"; if (video.status.equals("live")){ title = channel_name + " is live! \uD83D\uDD34"; fieldTitle = "Live Since"; + viewerText = "Live Viewers"; } String gmtStartTime = video.start_scheduled; long unixTime = OffsetDateTime.parse(gmtStartTime).toEpochSecond(); EmbedBuilder embedBuilder = new EmbedBuilder() .setTitle(title) .setDescription("["+video.title+"]"+"(https://www.youtube.com/watch?v="+video.id+")") - .addField(fieldTitle, "", false) + .addField(fieldTitle, "", true) .setThumbnail(video.channel.photo) .setImage("https://img.youtube.com/vi/"+video.id+"/maxresdefault.jpg") .setTimestamp(OffsetDateTime.now()); + if (video.status.equals("live")){ //uhhhhhh boilerplate but oh well + embedBuilder.addField(viewerText, numberFormat.format(video.live_viewers), true); + } messageEmbeds.add(embedBuilder.build()); } return messageEmbeds; -- cgit v1.2.3 From 0509738b0af300b1bdda908be10e68f13386a6f8 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:34 -0700 Subject: Added check for if organization schedule is requested for exists. --- src/main/java/builders/ScheduleMessageBuilder.java | 2 +- src/main/java/commands/CommandManager.java | 4 +++ src/main/java/commands/StatusHandler.java | 12 +++++++++ src/main/java/vtuber/ScheduleHandler.java | 30 ++++++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/main/java/builders/ScheduleMessageBuilder.java b/src/main/java/builders/ScheduleMessageBuilder.java index 4f5f78c..2b468d2 100644 --- a/src/main/java/builders/ScheduleMessageBuilder.java +++ b/src/main/java/builders/ScheduleMessageBuilder.java @@ -42,7 +42,7 @@ public class ScheduleMessageBuilder { titleText = video.channel.name + " - " + unixTimeStr; } String videoURL = "https://www.youtube.com/watch?v=" + video.id; - messageBuilder.addField(titleText, "["+video.title+"]"+"("+videoURL+")", true); + messageBuilder.addField(titleText, "["+video.title+"]"+"("+videoURL+")", false); } return messageBuilder.build(); diff --git a/src/main/java/commands/CommandManager.java b/src/main/java/commands/CommandManager.java index e374b21..d56b39a 100644 --- a/src/main/java/commands/CommandManager.java +++ b/src/main/java/commands/CommandManager.java @@ -23,6 +23,10 @@ public class CommandManager extends ListenerAdapter { case "schedule": String organization = e.getOption("organization").getAsString(); organization = organization.replaceAll(" ", "%20"); + if (scheduleHandler.organizationExists(organization) == false) { + e.reply("Sorry, I couldn't find any information on that organization. Please ensure it matches Holodex's spelling").queue(); + return; + } MessageEmbed scheduleMessage = scb.buildLiveAndUpcomingMessage(scheduleHandler.getSchedule(organization, 10)); e.deferReply().queue(); e.getHook().sendMessageEmbeds(scheduleMessage).queue(); diff --git a/src/main/java/commands/StatusHandler.java b/src/main/java/commands/StatusHandler.java index ff48632..090af40 100644 --- a/src/main/java/commands/StatusHandler.java +++ b/src/main/java/commands/StatusHandler.java @@ -15,6 +15,18 @@ public class StatusHandler { "Holodex Organization Name (e.g Hololive, Nijisanji, Phase Connect, PRISM, Production Kawaii)", true)) .queue(); + jda.upsertCommand(new CommandData("schedule-channel", "Shows upcoming streams and events for a given channel ID") + .addOption(OptionType.STRING, "channel-id", + "YouTube Channel ID (e.g UCp6993wxpyDPHUpavwDFqgg)", + true)) + .queue(); + jda.upsertCommand(new CommandData("configure-stream-channel", "Sets channel to be updated with live and upcoming streams for the channel ID provided") + .addOption(OptionType.STRING,"channel-id", "YouTube Channel ID (e.g UCp6993wxpyDPHUpavwDFqgg)", true)) + .queue(); + jda.upsertCommand(new CommandData("configure-org-channel", "Sets channel to be updated with live and upcoming streams for the organization provided") + .addOption(OptionType.STRING,"organization", "Holodex Organization Name (e.g Hololive, Nijisanji, Phase Connect, PRISM, Production Kawaii)", true)) + .queue(); + } diff --git a/src/main/java/vtuber/ScheduleHandler.java b/src/main/java/vtuber/ScheduleHandler.java index 094309b..2990bbf 100644 --- a/src/main/java/vtuber/ScheduleHandler.java +++ b/src/main/java/vtuber/ScheduleHandler.java @@ -2,7 +2,10 @@ package vtuber; import com.pina.Holodex; import com.pina.HolodexException; +import com.pina.datatypes.Channel; +import com.pina.datatypes.SimpleChannel; import com.pina.datatypes.SimpleVideo; +import com.pina.query.ChannelQueryBuilder; import com.pina.query.VideoQueryBuilder; import java.util.ArrayList; @@ -62,4 +65,31 @@ public class ScheduleHandler { return upcomingAndLiveVideos; } + + public boolean organizationExists(String org) { + List channels = new ArrayList<>(); + try { + channels = holodex.getChannels(new ChannelQueryBuilder().setOrg(org)); + } catch (HolodexException e) { + System.out.println("Couldn't find organization with name " + org); + return false; + } + return channels.size() > 0; + } + + public boolean channelExists(String channelId) { + Channel channel = new Channel(); + try{ + channel = holodex.getChannel(channelId); + if (channel.name == null) { + throw new HolodexException("Searching channel successful but no results found"); + } + } catch (HolodexException e) { + System.out.println("Couldn't find channel with id " + channelId); + return false; + } + return true; + } + } + -- cgit v1.2.3 From afeef3ace684fedd6be1114684526cf62be47ea9 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:34 -0700 Subject: Implemented method to purge all slash commands --- src/main/java/Main.java | 1 + src/main/java/commands/StatusHandler.java | 10 ++++++++++ src/main/java/vtuber/ScheduleHandler.java | 5 ++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 6fdaf1e..bf4cd99 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -88,6 +88,7 @@ public class Main extends ListenerAdapter{ public void onReady(net.dv8tion.jda.api.events.ReadyEvent event) { System.out.println("Logged in as " + event.getJDA().getSelfUser().getAsTag()); statusHandler = new StatusHandler(jda); + //statusHandler.purgeSlashCommands(); statusHandler.updateSlashCommands(); initializeAutoRefresh(); System.out.println("Bot is ready!"); diff --git a/src/main/java/commands/StatusHandler.java b/src/main/java/commands/StatusHandler.java index 090af40..814f71f 100644 --- a/src/main/java/commands/StatusHandler.java +++ b/src/main/java/commands/StatusHandler.java @@ -10,6 +10,7 @@ public class StatusHandler { } public void updateSlashCommands(){ + System.out.println("Adding slash commands"); jda.upsertCommand(new CommandData("schedule", "Shows upcoming streams and events for a given organization") .addOption(OptionType.STRING, "organization", "Holodex Organization Name (e.g Hololive, Nijisanji, Phase Connect, PRISM, Production Kawaii)", @@ -30,5 +31,14 @@ public class StatusHandler { } + public void purgeSlashCommands(){ + System.out.println("Purging all slash commands"); + jda.retrieveCommands().queue(commands -> { + for (int i = 0; i < commands.size(); i++) { + commands.get(i).delete().queue(); + } + }); + } + } diff --git a/src/main/java/vtuber/ScheduleHandler.java b/src/main/java/vtuber/ScheduleHandler.java index 2990bbf..d921237 100644 --- a/src/main/java/vtuber/ScheduleHandler.java +++ b/src/main/java/vtuber/ScheduleHandler.java @@ -3,7 +3,6 @@ package vtuber; import com.pina.Holodex; import com.pina.HolodexException; import com.pina.datatypes.Channel; -import com.pina.datatypes.SimpleChannel; import com.pina.datatypes.SimpleVideo; import com.pina.query.ChannelQueryBuilder; import com.pina.query.VideoQueryBuilder; @@ -67,7 +66,7 @@ public class ScheduleHandler { } public boolean organizationExists(String org) { - List channels = new ArrayList<>(); + List channels; try { channels = holodex.getChannels(new ChannelQueryBuilder().setOrg(org)); } catch (HolodexException e) { @@ -78,7 +77,7 @@ public class ScheduleHandler { } public boolean channelExists(String channelId) { - Channel channel = new Channel(); + Channel channel; try{ channel = holodex.getChannel(channelId); if (channel.name == null) { -- cgit v1.2.3 From 43264d01c17f3dee707d7d1e79c4f00f663aafd0 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:34 -0700 Subject: Implemented /schedule-channel command (schedule for individual channels) --- src/main/java/builders/ScheduleMessageBuilder.java | 6 +++++- src/main/java/commands/CommandManager.java | 13 ++++++++++++- src/main/java/vtuber/ScheduleHandler.java | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/main/java/builders/ScheduleMessageBuilder.java b/src/main/java/builders/ScheduleMessageBuilder.java index 2b468d2..28c69a0 100644 --- a/src/main/java/builders/ScheduleMessageBuilder.java +++ b/src/main/java/builders/ScheduleMessageBuilder.java @@ -38,7 +38,11 @@ public class ScheduleMessageBuilder { unixTimeStr = "LIVE \uD83D\uDD34"; } String titleText = video.channel.english_name + " - " + unixTimeStr; - if (video.channel.english_name.equals(null)){ + try { + if (video.channel.english_name.equals(null)) { + titleText = video.channel.name + " - " + unixTimeStr; + } + } catch (NullPointerException e){ titleText = video.channel.name + " - " + unixTimeStr; } String videoURL = "https://www.youtube.com/watch?v=" + video.id; diff --git a/src/main/java/commands/CommandManager.java b/src/main/java/commands/CommandManager.java index d56b39a..03de1f5 100644 --- a/src/main/java/commands/CommandManager.java +++ b/src/main/java/commands/CommandManager.java @@ -19,7 +19,18 @@ public class CommandManager extends ListenerAdapter { @Override public void onSlashCommand(SlashCommandEvent e) { String command = e.getName(); + MessageEmbed scheduleMessage; switch (command) { + case "schedule-channel": + String channelId = e.getOption("channel-id").getAsString(); + if (scheduleHandler.channelExists(channelId) == false) { + e.reply("Sorry, I couldn't find any information on that channel. Please ensure it matches Holodex's spelling").queue(); + return; + } + scheduleMessage = scb.buildLiveAndUpcomingMessage(scheduleHandler.getScheduleChannelId(channelId, 10)); + e.deferReply().queue(); + e.getHook().sendMessageEmbeds(scheduleMessage).queue(); + break; case "schedule": String organization = e.getOption("organization").getAsString(); organization = organization.replaceAll(" ", "%20"); @@ -27,7 +38,7 @@ public class CommandManager extends ListenerAdapter { e.reply("Sorry, I couldn't find any information on that organization. Please ensure it matches Holodex's spelling").queue(); return; } - MessageEmbed scheduleMessage = scb.buildLiveAndUpcomingMessage(scheduleHandler.getSchedule(organization, 10)); + scheduleMessage = scb.buildLiveAndUpcomingMessage(scheduleHandler.getSchedule(organization, 10)); e.deferReply().queue(); e.getHook().sendMessageEmbeds(scheduleMessage).queue(); break; diff --git a/src/main/java/vtuber/ScheduleHandler.java b/src/main/java/vtuber/ScheduleHandler.java index d921237..990b285 100644 --- a/src/main/java/vtuber/ScheduleHandler.java +++ b/src/main/java/vtuber/ScheduleHandler.java @@ -63,6 +63,24 @@ public class ScheduleHandler { } return upcomingAndLiveVideos; + } + public List getScheduleChannelId(String channelId, int limit) { + System.out.println("Getting schedule for " + channelId); + List upcomingAndLiveVideos = new ArrayList<>(); + try { + List upcomingVideos = holodex.getLiveAndUpcomingVideos(new VideoQueryBuilder().setChannelId(channelId).setStatus("upcoming")); + List liveVideos = holodex.getLiveAndUpcomingVideos(new VideoQueryBuilder().setStatus("live").setChannelId(channelId)); + upcomingAndLiveVideos.addAll(liveVideos); + upcomingAndLiveVideos.addAll(upcomingVideos); + if (upcomingAndLiveVideos.size() > limit) { + upcomingAndLiveVideos = upcomingAndLiveVideos.subList(0, limit); + } + } catch (HolodexException e) { + System.out.println("Error getting schedule for " + channelId); + System.out.println(e.getMessage()); + } + return upcomingAndLiveVideos; + } public boolean organizationExists(String org) { -- cgit v1.2.3 From 1f234263f766ff48c28801d3ae4ca279a9e9a2ea Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:34 -0700 Subject: Implemented configuring channel feeds using /commands --- src/main/java/commands/CommandManager.java | 35 +++++++++++++++++++++- src/main/java/commands/StatusHandler.java | 30 +++++++++++-------- .../java/fileutils/UpcomingChannelsManager.java | 20 +++++++++++++ 3 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 src/main/java/fileutils/UpcomingChannelsManager.java diff --git a/src/main/java/commands/CommandManager.java b/src/main/java/commands/CommandManager.java index 03de1f5..34896bb 100644 --- a/src/main/java/commands/CommandManager.java +++ b/src/main/java/commands/CommandManager.java @@ -1,6 +1,7 @@ package commands; import builders.ScheduleMessageBuilder; +import fileutils.UpcomingChannelsManager; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; @@ -11,9 +12,11 @@ import java.util.ArrayList; public class CommandManager extends ListenerAdapter { ScheduleHandler scheduleHandler; ScheduleMessageBuilder scb; + UpcomingChannelsManager ucm; public CommandManager(String holodexAPIKey) { scheduleHandler = new ScheduleHandler(holodexAPIKey); scb = new ScheduleMessageBuilder(); + ucm = new UpcomingChannelsManager(); System.out.println("CommandManager initialized"); } @Override @@ -21,10 +24,21 @@ public class CommandManager extends ListenerAdapter { String command = e.getName(); MessageEmbed scheduleMessage; switch (command) { + case "configure": + String type = e.getOption("type").getAsString(); + String id = e.getOption("id").getAsString(); + long discordChannelId = e.getChannel().getIdLong(); + if (checkValidConfig(type, id) == false){ + e.reply("Sorry, I couldn't find any information on that channel. Please check the ID you provided").queue(); + return; + } + ucm.addNewEntry(type, id, Long.toString(discordChannelId)); + e.reply("Successfully added " + type + " " + id + " feed to this channel. Please restart the bot for this to take effect").queue(); + break; case "schedule-channel": String channelId = e.getOption("channel-id").getAsString(); if (scheduleHandler.channelExists(channelId) == false) { - e.reply("Sorry, I couldn't find any information on that channel. Please ensure it matches Holodex's spelling").queue(); + e.reply("Sorry, I couldn't find any information on that channel. Please check the ID you provided").queue(); return; } scheduleMessage = scb.buildLiveAndUpcomingMessage(scheduleHandler.getScheduleChannelId(channelId, 10)); @@ -64,4 +78,23 @@ public class CommandManager extends ListenerAdapter { return messageEmbeds; } + public boolean checkValidConfig(String type, String id){ + switch (type) { + case "org": + if (scheduleHandler.organizationExists(id) == false) { + return false; + } + break; + case "channel": + if (scheduleHandler.channelExists(id) == false) { + return false; + } + break; + default: + System.out.println("Unknown type"); + throw new IllegalArgumentException("Unknown type"); + } + return true; + } + } diff --git a/src/main/java/commands/StatusHandler.java b/src/main/java/commands/StatusHandler.java index 814f71f..f6631d2 100644 --- a/src/main/java/commands/StatusHandler.java +++ b/src/main/java/commands/StatusHandler.java @@ -1,37 +1,41 @@ package commands; + import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.CommandData; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; public class StatusHandler { JDA jda; + public StatusHandler(JDA jda) { this.jda = jda; } - public void updateSlashCommands(){ + + public void updateSlashCommands() { System.out.println("Adding slash commands"); jda.upsertCommand(new CommandData("schedule", "Shows upcoming streams and events for a given organization") - .addOption(OptionType.STRING, "organization", - "Holodex Organization Name (e.g Hololive, Nijisanji, Phase Connect, PRISM, Production Kawaii)", - true)) + .addOption(OptionType.STRING, "organization", + "Holodex Organization Name (e.g Hololive, Nijisanji, Phase Connect, PRISM, Production Kawaii)", + true)) .queue(); jda.upsertCommand(new CommandData("schedule-channel", "Shows upcoming streams and events for a given channel ID") - .addOption(OptionType.STRING, "channel-id", - "YouTube Channel ID (e.g UCp6993wxpyDPHUpavwDFqgg)", - true)) - .queue(); - jda.upsertCommand(new CommandData("configure-stream-channel", "Sets channel to be updated with live and upcoming streams for the channel ID provided") - .addOption(OptionType.STRING,"channel-id", "YouTube Channel ID (e.g UCp6993wxpyDPHUpavwDFqgg)", true)) + .addOption(OptionType.STRING, "channel-id", + "YouTube Channel ID (e.g UCp6993wxpyDPHUpavwDFqgg)", + true)) .queue(); - jda.upsertCommand(new CommandData("configure-org-channel", "Sets channel to be updated with live and upcoming streams for the organization provided") - .addOption(OptionType.STRING,"organization", "Holodex Organization Name (e.g Hololive, Nijisanji, Phase Connect, PRISM, Production Kawaii)", true)) + jda.upsertCommand(new CommandData("configure", "Sets channel to be updated with live and upcoming streams for the organization provided") + .addOptions(new OptionData(OptionType.STRING, "type", "Individual Channel or Organization", true) + .addChoice("Channel", "channel") + .addChoice("Organization", "org")) + .addOption(OptionType.STRING, "id", "The name of the organization or the channel ID", true)) .queue(); } - public void purgeSlashCommands(){ + public void purgeSlashCommands() { System.out.println("Purging all slash commands"); jda.retrieveCommands().queue(commands -> { for (int i = 0; i < commands.size(); i++) { diff --git a/src/main/java/fileutils/UpcomingChannelsManager.java b/src/main/java/fileutils/UpcomingChannelsManager.java new file mode 100644 index 0000000..7c8ade7 --- /dev/null +++ b/src/main/java/fileutils/UpcomingChannelsManager.java @@ -0,0 +1,20 @@ +package fileutils; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class UpcomingChannelsManager { + public void addNewEntry(String type, String information, String discordChannelID){ + File f = new File("settings//upcomingChannels.txt"); + try { + System.out.printf("Written data to upcomingChannels.txt"); + FileWriter fw = new FileWriter(f, true); + fw.write(type + ":" + information + ":" + discordChannelID+"\n"); + fw.close(); + } + catch(IOException e){ + System.out.println("Unable to open upcomingChannels.txt for writing"); + } + } +} -- cgit v1.2.3 From 8abc1312b35703174dedd991ff96d514e85d6ec5 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:34 -0700 Subject: Renamed credential function to getField --- src/main/java/Main.java | 4 ++-- src/main/java/fileutils/FileDataProcessor.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index bf4cd99..9838c1b 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -27,8 +27,8 @@ public class Main extends ListenerAdapter{ public void initializeBot(){ fileDataProcessor = new FileDataProcessor(); - commandManager = new CommandManager(fileDataProcessor.readCredential("holodexAPIKey")); - jdaBuilder = JDABuilder.createDefault(fileDataProcessor.readCredential("discordToken")); + commandManager = new CommandManager(fileDataProcessor.getField("holodexAPIKey")); + jdaBuilder = JDABuilder.createDefault(fileDataProcessor.getField("discordToken")); jdaBuilder.addEventListeners(commandManager); jdaBuilder.addEventListeners(this); try { diff --git a/src/main/java/fileutils/FileDataProcessor.java b/src/main/java/fileutils/FileDataProcessor.java index 0315fbb..ac260f0 100644 --- a/src/main/java/fileutils/FileDataProcessor.java +++ b/src/main/java/fileutils/FileDataProcessor.java @@ -16,7 +16,7 @@ import java.util.List; public class FileDataProcessor { - public static String readCredential(String parameter){ + public static String getField(String parameter){ try { Object obj = new JSONParser().parse(new FileReader("settings//config.json")); JSONObject jo = (JSONObject) obj; -- cgit v1.2.3 From f952d3dad6183b38062bd8d5fdecbddb41b48b6d Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 13 Apr 2023 14:27:35 -0700 Subject: Update README with new /configure --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index e572a0f..dca8e7d 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ A Java JDA Bot for Tracking VTuber Livestreams and Schedules. - Create a file called 'upcomingChannels.txt' in the settings folder of the root directory (if it doesn't already exist) ### Configuring Custom Feeds +/configure command is used to configure a custom feed related to a particular channel or organizaton. +The command will use the channel the message is sent in as the channel to send the upcoming/live feed to + +This can also be manually configured through the upcomingChannels.txt file: ``` [TYPE]:[INFORMATION]:[DISCORD_CHANNEL_ID] TYPE: org (organization name) or channel (individual channel) @@ -28,3 +32,4 @@ channel:UC4WvIIAo89_AzGUh1AZ6Dkg:1094112349163638804 # ![image](https://user-images.githubusercontent.com/21994085/230703769-7c88c760-b81f-4798-883f-475c42d97fe1.png) # ![image](https://user-images.githubusercontent.com/21994085/230703785-7cb3eb80-a1de-4b46-af81-0b9a7820ab5d.png) +# ![image](https://user-images.githubusercontent.com/21994085/231882006-23f86f82-ad05-4842-9057-4e66fac8a3b1.png) -- cgit v1.2.3