diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/SettingsCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/SettingsCommand.java index 9493f5a7..6509c522 100644 --- a/src/main/java/de/kittybot/kittybot/commands/admin/SettingsCommand.java +++ b/src/main/java/de/kittybot/kittybot/commands/admin/SettingsCommand.java @@ -1,21 +1,10 @@ package de.kittybot.kittybot.commands.admin; -import de.kittybot.kittybot.modules.SettingsModule; -import de.kittybot.kittybot.modules.StreamAnnouncementModule; -import de.kittybot.kittybot.objects.enums.Emoji; -import de.kittybot.kittybot.objects.streams.StreamType; +import de.kittybot.kittybot.commands.admin.settings.*; import de.kittybot.kittybot.slashcommands.application.Category; import de.kittybot.kittybot.slashcommands.application.Command; -import de.kittybot.kittybot.slashcommands.application.options.*; -import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; -import de.kittybot.kittybot.slashcommands.interaction.Options; -import de.kittybot.kittybot.slashcommands.interaction.response.InteractionResponse; -import de.kittybot.kittybot.utils.Config; -import de.kittybot.kittybot.utils.MessageUtils; import net.dv8tion.jda.api.Permission; -import java.util.stream.Collectors; - @SuppressWarnings("unused") public class SettingsCommand extends Command{ @@ -30,391 +19,10 @@ public SettingsCommand(){ new NsfwCommand(), new LogMessagesCommand(), new SnipesCommand(), - new StreamAnnouncementsCommand(), + new StreamsCommand(), new RoleSaverCommand() ); addPermissions(Permission.ADMINISTRATOR); } - private static class ListCommand extends GuildSubCommand{ - - public ListCommand(){ - super("list", "Lists the current settings"); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var guildId = ia.getGuildId(); - var settings = ia.get(SettingsModule.class).getSettings(guildId); - ia.reply(builder -> builder - .setAuthor("Guild settings:", Config.ORIGIN_URL + "/guilds/" + guildId + "/dashboard", Emoji.SETTINGS.getUrl()) - .addField("Announcement Channel: ", settings.getAnnouncementChannel(), false) - .addField("Join Messages: " + MessageUtils.getBoolEmote(settings.areJoinMessagesEnabled()), settings.getJoinMessage(), false) - .addField("Leave Messages: " + MessageUtils.getBoolEmote(settings.areLeaveMessagesEnabled()), settings.getLeaveMessage(), false) - .addField("Stream Announcement Channel:", settings.getStreamAnnouncementChannel(), false) - .addField("DJ Role: ", settings.getDjRole(), false) - .addField("NSFW Enabled: ", MessageUtils.getBoolEmote(settings.isNsfwEnabled()), false) - .addField("Log Messages: " + MessageUtils.getBoolEmote(settings.areLogMessagesEnabled()), settings.getLogChannel(), false) - .addField("Snipes Enabled:", MessageUtils.getBoolEmote(settings.areSnipesEnabled()), false) - .addField("Role Saver Enabled:", MessageUtils.getBoolEmote(settings.isRoleSaverEnabled()), false) - //.addField("Inactive Role: " + TimeUtils.formatDurationDHMS(settings.getInactiveDuration()), settings.getLogChannel(), false) - ); - } - - } - - private static class DJRoleCommand extends GuildSubCommand{ - - public DJRoleCommand(){ - super("djrole", "Sets the dj role"); - addOptions( - new CommandOptionRole("role", "The new dj role").required() - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var role = options.getRole("role"); - ia.get(SettingsModule.class).setDjRoleId(ia.getGuildId(), role.getIdLong()); - ia.reply(new InteractionResponse.Builder().setContent("DJ Role set to: " + role.getAsMention()).build()); - } - - } - - private static class AnnouncementChannelCommand extends GuildSubCommand{ - - public AnnouncementChannelCommand(){ - super("announcementchannel", "Sets the announcement channel"); - addOptions( - new CommandOptionChannel("channel", "The new announcement channel").required() - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var channel = options.getTextChannel("channel"); - ia.get(SettingsModule.class).setAnnouncementChannelId(ia.getGuildId(), channel.getIdLong()); - ia.reply(new InteractionResponse.Builder().setContent("Announcement channel set to: " + channel.getAsMention()).build()); - } - - } - - private static class JoinMessageCommand extends GuildSubCommand{ - - public JoinMessageCommand(){ - super("joinmessage", "Sets or enable/disables join messages"); - addOptions( - new CommandOptionBoolean("enabled", "Whether join messages are enabled"), - new CommandOptionString("message", "The join message template") - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var settings = ia.get(SettingsModule.class); - var returnMessage = ""; - if(options.has("enabled")){ - var enabled = options.getBoolean("enabled"); - settings.setJoinMessagesEnabled(ia.getGuildId(), enabled); - returnMessage += "Join messages `" + (enabled ? "enabled" : "disabled") + "`\n"; - } - - if(options.has("message")){ - var message = options.getString("message"); - settings.setJoinMessage(ia.getGuildId(), message); - returnMessage += "Join message to:\n" + message + "\n"; - } - - if(returnMessage.isBlank()){ - ia.reply(new InteractionResponse.Builder().setContent("Join message `" + (settings.areJoinMessagesEnabled(ia.getGuildId()) ? "enabled" : "disabled") + "` and set to:\n" + settings.getJoinMessage(ia.getGuildId())).build()); - return; - } - ia.reply(new InteractionResponse.Builder().setContent(returnMessage).build()); - } - - } - - private static class LeaveMessageCommand extends GuildSubCommand{ - - public LeaveMessageCommand(){ - super("leavemessage", "Sets or enable/disables leave messages"); - addOptions( - new CommandOptionBoolean("enabled", "Whether leave messages are enabled"), - new CommandOptionString("message", "The leave message template") - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var settings = ia.get(SettingsModule.class); - var returnMessage = ""; - if(options.has("enabled")){ - var enabled = options.getBoolean("enabled"); - settings.setLeaveMessagesEnabled(ia.getGuildId(), enabled); - returnMessage += "Leave messages `" + (enabled ? "enabled" : "disabled") + "`\n"; - } - - if(options.has("message")){ - var message = options.getString("message"); - settings.setLeaveMessage(ia.getGuildId(), message); - returnMessage += "Leave message to:\n" + message + "\n"; - } - - if(returnMessage.isBlank()){ - ia.reply(new InteractionResponse.Builder().setContent("Leave message `" + (settings.areLeaveMessagesEnabled(ia.getGuildId()) ? "enabled" : "disabled") + "` and set to:\n" + settings.getLeaveMessage(ia.getGuildId())).build()); - return; - } - ia.reply(new InteractionResponse.Builder().setContent(returnMessage).build()); - } - - } - - private static class NsfwCommand extends GuildSubCommand{ - - public NsfwCommand(){ - super("nsfw", "Enables/Disables nsfw commands"); - addOptions( - new CommandOptionBoolean("enabled", "Whether nsfw commands are enabled").required() - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var enabled = options.getBoolean("enabled"); - ia.get(SettingsModule.class).setNsfwEnabled(ia.getGuildId(), enabled); - ia.reply((enabled ? "Enabled" : "Disabled") + "nsfw commands"); - } - - } - - private static class LogMessagesCommand extends GuildSubCommand{ - - public LogMessagesCommand(){ - super("logmessages", "Sets the logging channel or enable/disables log messages"); - addOptions( - new CommandOptionBoolean("enabled", "Whether log messages are enabled"), - new CommandOptionChannel("channel", "The log message channel") - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var settings = ia.get(SettingsModule.class); - var returnMessage = ""; - if(options.has("enabled")){ - var enabled = options.getBoolean("enabled"); - settings.setLogMessagesEnabled(ia.getGuildId(), enabled); - returnMessage += "Log messages `" + (enabled ? "enabled" : "disabled") + "`\n"; - } - - if(options.has("channel")){ - var channel = options.getTextChannel("channel"); - settings.setLogChannelId(ia.getGuildId(), channel.getIdLong()); - returnMessage += "Log channel to:\n" + channel.getAsMention() + "\n"; - } - - if(returnMessage.isBlank()){ - ia.reply(new InteractionResponse.Builder().setContent("Log message `" + (settings.areLogMessagesEnabled(ia.getGuildId()) ? "enabled" : "disabled") + "` and send to channel " + - MessageUtils.getChannelMention(settings.getLogChannelId(ia.getGuildId()))).build()); - return; - } - ia.reply(new InteractionResponse.Builder().setContent(returnMessage).build()); - } - - } - - private static class SnipesCommand extends SubCommandGroup{ - - public SnipesCommand(){ - super("snipes", "Used to disable snipes"); - addOptions( - new ChannelCommand(), - new EnableCommand() - ); - } - - private static class ChannelCommand extends GuildSubCommand{ - - public ChannelCommand(){ - super("channel", "Used to enable/disable snipes in a specific channel"); - addOptions( - new CommandOptionChannel("channel", "The channel to enable/disable snipes").required(), - new CommandOptionBoolean("enabled", "Whether to enable/disable snipes").required() - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var channel = options.getTextChannel("channel"); - var enabled = options.getBoolean("enabled"); - ia.get(SettingsModule.class).setSnipesDisabledInChannel(ia.getGuildId(), channel.getIdLong(), !enabled); - ia.reply("Snipes `" + (enabled ? "enabled" : "disabled") + "` in " + channel.getAsMention()); - } - - } - - private static class EnableCommand extends GuildSubCommand{ - - public EnableCommand(){ - super("enable", "Used to globally disable snipes"); - addOptions( - new CommandOptionBoolean("enabled", "Whether to enable/disable snipes globally") - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var enabled = options.getBoolean("enabled"); - ia.get(SettingsModule.class).setSnipesEnabled(ia.getGuildId(), enabled); - ia.reply("Snipes globally `" + (enabled ? "enabled" : "disabled") + "`"); - } - - } - - } - - private static class StreamAnnouncementsCommand extends SubCommandGroup{ - - public StreamAnnouncementsCommand(){ - super("streamannouncements", "Used to configure stream announcements"); - addOptions( - new AddCommand(), - new RemoveCommand(), - new ListCommand(), - new MessageCommand(), - new ChannelCommand() - ); - } - - private static class AddCommand extends GuildSubCommand{ - - public AddCommand(){ - super("add", "Adds a new stream announcement for twitch"); - addOptions( - /*new CommandOptionInteger("service", "Which service the stream is from").required() - .addChoices( - new CommandOptionChoice<>("twitch", 1)/*, - new CommandOptionChoice<>("youtube", 2) - ),*/ - new CommandOptionString("username", "The username of the streamer").required() - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var type = StreamType.TWITCH;//StreamType.byId(options.getInt("service")); - var username = options.getString("username"); - var user = ia.get(StreamAnnouncementModule.class).add(username, ia.getGuildId(), type); - if(user == null){ - ia.error("No user found with username " + username + "for " + type.getName()); - return; - } - ia.reply("Stream announcement for " + type.getName() + " with username: " + user.getDisplayName() + " added"); - } - - } - - private static class RemoveCommand extends GuildSubCommand{ - - public RemoveCommand(){ - super("remove", "Removes a stream announcement"); - addOptions( - /*new CommandOptionInteger("service", "Which service the stream is from").required() - .addChoices( - new CommandOptionChoice<>("twitch", 1)/*, - new CommandOptionChoice<>("youtube", 0) - ),*/ - new CommandOptionString("username", "The username of the streamer").required() - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var type = StreamType.TWITCH;//StreamType.byId(options.getInt("service")); - var username = options.getString("username"); - var success = ia.get(StreamAnnouncementModule.class).remove(username, ia.getGuildId(), type); - if(!success){ - ia.error("Could not find stream announcement for " + type.getName() + " with username: " + username + ". Check your spelling"); - return; - } - ia.reply("Stream announcement for " + type.getName() + " with username: " + username + " removed"); - } - - } - - private static class ListCommand extends GuildSubCommand{ - - public ListCommand(){ - super("list", "Lists stream announcements"); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var streamAnnouncements = ia.get(StreamAnnouncementModule.class).get(ia.getGuildId()); - if(streamAnnouncements.isEmpty()){ - ia.error("No stream announcements found. Create them with `/settings streamannouncements add `"); - return; - } - ia.reply("**Stream Announcements:**\n" + streamAnnouncements.stream().map(sa -> MessageUtils.maskLink(sa.getUserName(), "https://twitch.tv/" + sa.getUserName()) + " on " + StreamType.byId(sa.getStreamType()).getName()).collect(Collectors.joining("\n"))); - } - - } - - private static class MessageCommand extends GuildSubCommand{ - - public MessageCommand(){ - super("message", "Sets the stream announcement message template"); - addOptions( - new CommandOptionString("message", "The message template").required() - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var message = options.getString("message"); - - ia.get(SettingsModule.class).setStreamAnnouncementMessage(ia.getGuildId(), message); - ia.reply("Set stream announcements template to:\n" + message); - } - - } - - private static class ChannelCommand extends GuildSubCommand{ - - public ChannelCommand(){ - super("channel", "Sets the stream announcement channel"); - addOptions( - new CommandOptionChannel("channel", "The channel which stream announcements should get send to").required() - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var channel = options.getTextChannel("channel"); - ia.get(SettingsModule.class).setStreamAnnouncementChannelId(ia.getGuildId(), channel.getIdLong()); - ia.reply("Stream announcements now get send to " + channel.getAsMention()); - } - - } - - } - - private static class RoleSaverCommand extends GuildSubCommand{ - - public RoleSaverCommand(){ - super("rolesaver", "Enabled/Disables saving of user roles on leave"); - addOptions( - new CommandOptionBoolean("enabled", "Whether role saving is enabled or disabled").required() - ); - } - - @Override - public void run(Options options, GuildInteraction ia){ - var enabled = options.getBoolean("enabled"); - ia.get(SettingsModule.class).setRoleSaverEnabled(ia.getGuildId(), enabled); - ia.reply((enabled ? "Enabled" : "Disabled") + " role saving"); - } - - } - } diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/AnnouncementChannelCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/AnnouncementChannelCommand.java new file mode 100644 index 00000000..4da5a885 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/AnnouncementChannelCommand.java @@ -0,0 +1,26 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionChannel; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; +import de.kittybot.kittybot.slashcommands.interaction.response.InteractionResponse; + +public class AnnouncementChannelCommand extends GuildSubCommand{ + + public AnnouncementChannelCommand(){ + super("announcementchannel", "Sets the announcement channel"); + addOptions( + new CommandOptionChannel("channel", "The new announcement channel").required() + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var channel = options.getTextChannel("channel"); + ia.get(SettingsModule.class).setAnnouncementChannelId(ia.getGuildId(), channel.getIdLong()); + ia.reply(new InteractionResponse.Builder().setContent("Announcement channel set to: " + channel.getAsMention()).build()); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/DJRoleCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/DJRoleCommand.java new file mode 100644 index 00000000..55f4cf26 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/DJRoleCommand.java @@ -0,0 +1,26 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionRole; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; +import de.kittybot.kittybot.slashcommands.interaction.response.InteractionResponse; + +public class DJRoleCommand extends GuildSubCommand{ + + public DJRoleCommand(){ + super("djrole", "Sets the dj role"); + addOptions( + new CommandOptionRole("role", "The new dj role").required() + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var role = options.getRole("role"); + ia.get(SettingsModule.class).setDjRoleId(ia.getGuildId(), role.getIdLong()); + ia.reply(new InteractionResponse.Builder().setContent("DJ Role set to: " + role.getAsMention()).build()); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/JoinMessageCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/JoinMessageCommand.java new file mode 100644 index 00000000..e06242aa --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/JoinMessageCommand.java @@ -0,0 +1,44 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionBoolean; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionString; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; +import de.kittybot.kittybot.slashcommands.interaction.response.InteractionResponse; + +public class JoinMessageCommand extends GuildSubCommand{ + + public JoinMessageCommand(){ + super("joinmessage", "Sets or enable/disables join messages"); + addOptions( + new CommandOptionBoolean("enabled", "Whether join messages are enabled"), + new CommandOptionString("message", "The join message template") + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var settings = ia.get(SettingsModule.class); + var returnMessage = ""; + if(options.has("enabled")){ + var enabled = options.getBoolean("enabled"); + settings.setJoinMessagesEnabled(ia.getGuildId(), enabled); + returnMessage += "Join messages `" + (enabled ? "enabled" : "disabled") + "`\n"; + } + + if(options.has("message")){ + var message = options.getString("message"); + settings.setJoinMessage(ia.getGuildId(), message); + returnMessage += "Join message to:\n" + message + "\n"; + } + + if(returnMessage.isBlank()){ + ia.reply(new InteractionResponse.Builder().setContent("Join message `" + (settings.areJoinMessagesEnabled(ia.getGuildId()) ? "enabled" : "disabled") + "` and set to:\n" + settings.getJoinMessage(ia.getGuildId())).build()); + return; + } + ia.reply(new InteractionResponse.Builder().setContent(returnMessage).build()); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/LeaveMessageCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/LeaveMessageCommand.java new file mode 100644 index 00000000..8d38e776 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/LeaveMessageCommand.java @@ -0,0 +1,44 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionBoolean; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionString; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; +import de.kittybot.kittybot.slashcommands.interaction.response.InteractionResponse; + +public class LeaveMessageCommand extends GuildSubCommand{ + + public LeaveMessageCommand(){ + super("leavemessage", "Sets or enable/disables leave messages"); + addOptions( + new CommandOptionBoolean("enabled", "Whether leave messages are enabled"), + new CommandOptionString("message", "The leave message template") + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var settings = ia.get(SettingsModule.class); + var returnMessage = ""; + if(options.has("enabled")){ + var enabled = options.getBoolean("enabled"); + settings.setLeaveMessagesEnabled(ia.getGuildId(), enabled); + returnMessage += "Leave messages `" + (enabled ? "enabled" : "disabled") + "`\n"; + } + + if(options.has("message")){ + var message = options.getString("message"); + settings.setLeaveMessage(ia.getGuildId(), message); + returnMessage += "Leave message to:\n" + message + "\n"; + } + + if(returnMessage.isBlank()){ + ia.reply(new InteractionResponse.Builder().setContent("Leave message `" + (settings.areLeaveMessagesEnabled(ia.getGuildId()) ? "enabled" : "disabled") + "` and set to:\n" + settings.getLeaveMessage(ia.getGuildId())).build()); + return; + } + ia.reply(new InteractionResponse.Builder().setContent(returnMessage).build()); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/ListCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/ListCommand.java new file mode 100644 index 00000000..0dcfd6fe --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/ListCommand.java @@ -0,0 +1,36 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.objects.enums.Emoji; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; +import de.kittybot.kittybot.utils.Config; +import de.kittybot.kittybot.utils.MessageUtils; + +public class ListCommand extends GuildSubCommand{ + + public ListCommand(){ + super("list", "Lists the current settings"); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var guildId = ia.getGuildId(); + var settings = ia.get(SettingsModule.class).getSettings(guildId); + ia.reply(builder -> builder + .setAuthor("Guild settings:", Config.ORIGIN_URL + "/guilds/" + guildId + "/dashboard", Emoji.SETTINGS.getUrl()) + .addField("Announcement Channel: ", settings.getAnnouncementChannel(), false) + .addField("Join Messages: " + MessageUtils.getBoolEmote(settings.areJoinMessagesEnabled()), settings.getJoinMessage(), false) + .addField("Leave Messages: " + MessageUtils.getBoolEmote(settings.areLeaveMessagesEnabled()), settings.getLeaveMessage(), false) + .addField("Stream Announcement Channel:", settings.getStreamAnnouncementChannel(), false) + .addField("DJ Role: ", settings.getDjRole(), false) + .addField("NSFW Enabled: ", MessageUtils.getBoolEmote(settings.isNsfwEnabled()), false) + .addField("Log Messages: " + MessageUtils.getBoolEmote(settings.areLogMessagesEnabled()), settings.getLogChannel(), false) + .addField("Snipes Enabled:", MessageUtils.getBoolEmote(settings.areSnipesEnabled()), false) + .addField("Role Saver Enabled:", MessageUtils.getBoolEmote(settings.isRoleSaverEnabled()), false) + //.addField("Inactive Role: " + TimeUtils.formatDurationDHMS(settings.getInactiveDuration()), settings.getLogChannel(), false) + ); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/LogMessagesCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/LogMessagesCommand.java new file mode 100644 index 00000000..dff99ac2 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/LogMessagesCommand.java @@ -0,0 +1,46 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionBoolean; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionChannel; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; +import de.kittybot.kittybot.slashcommands.interaction.response.InteractionResponse; +import de.kittybot.kittybot.utils.MessageUtils; + +public class LogMessagesCommand extends GuildSubCommand{ + + public LogMessagesCommand(){ + super("logmessages", "Sets the logging channel or enable/disables log messages"); + addOptions( + new CommandOptionBoolean("enabled", "Whether log messages are enabled"), + new CommandOptionChannel("channel", "The log message channel") + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var settings = ia.get(SettingsModule.class); + var returnMessage = ""; + if(options.has("enabled")){ + var enabled = options.getBoolean("enabled"); + settings.setLogMessagesEnabled(ia.getGuildId(), enabled); + returnMessage += "Log messages `" + (enabled ? "enabled" : "disabled") + "`\n"; + } + + if(options.has("channel")){ + var channel = options.getTextChannel("channel"); + settings.setLogChannelId(ia.getGuildId(), channel.getIdLong()); + returnMessage += "Log channel to:\n" + channel.getAsMention() + "\n"; + } + + if(returnMessage.isBlank()){ + ia.reply(new InteractionResponse.Builder().setContent("Log message `" + (settings.areLogMessagesEnabled(ia.getGuildId()) ? "enabled" : "disabled") + "` and send to channel " + + MessageUtils.getChannelMention(settings.getLogChannelId(ia.getGuildId()))).build()); + return; + } + ia.reply(new InteractionResponse.Builder().setContent(returnMessage).build()); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/NsfwCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/NsfwCommand.java new file mode 100644 index 00000000..08043bad --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/NsfwCommand.java @@ -0,0 +1,25 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionBoolean; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; + +public class NsfwCommand extends GuildSubCommand{ + + public NsfwCommand(){ + super("nsfw", "Enables/Disables nsfw commands"); + addOptions( + new CommandOptionBoolean("enabled", "Whether nsfw commands are enabled").required() + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var enabled = options.getBoolean("enabled"); + ia.get(SettingsModule.class).setNsfwEnabled(ia.getGuildId(), enabled); + ia.reply((enabled ? "Enabled" : "Disabled") + "nsfw commands"); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/RoleSaverCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/RoleSaverCommand.java new file mode 100644 index 00000000..2595011c --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/RoleSaverCommand.java @@ -0,0 +1,25 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionBoolean; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; + +public class RoleSaverCommand extends GuildSubCommand{ + + public RoleSaverCommand(){ + super("rolesaver", "Enabled/Disables saving of user roles on leave"); + addOptions( + new CommandOptionBoolean("enabled", "Whether role saving is enabled or disabled").required() + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var enabled = options.getBoolean("enabled"); + ia.get(SettingsModule.class).setRoleSaverEnabled(ia.getGuildId(), enabled); + ia.reply((enabled ? "Enabled" : "Disabled") + " role saving"); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/SnipesCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/SnipesCommand.java new file mode 100644 index 00000000..f27ae294 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/SnipesCommand.java @@ -0,0 +1,17 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.commands.admin.settings.snipes.ChannelCommand; +import de.kittybot.kittybot.commands.admin.settings.snipes.EnableCommand; +import de.kittybot.kittybot.slashcommands.application.options.SubCommandGroup; + +public class SnipesCommand extends SubCommandGroup{ + + public SnipesCommand(){ + super("snipes", "Used to disable snipes"); + addOptions( + new ChannelCommand(), + new EnableCommand() + ); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/StreamsCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/StreamsCommand.java new file mode 100644 index 00000000..491efa46 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/StreamsCommand.java @@ -0,0 +1,20 @@ +package de.kittybot.kittybot.commands.admin.settings; + +import de.kittybot.kittybot.commands.admin.settings.streams.*; +import de.kittybot.kittybot.commands.admin.settings.streams.ListCommand; +import de.kittybot.kittybot.slashcommands.application.options.SubCommandGroup; + +public class StreamsCommand extends SubCommandGroup{ + + public StreamsCommand(){ + super("streams", "Used to configure stream announcements"); + addOptions( + new AddCommand(), + new RemoveCommand(), + new ListCommand(), + new MessageCommand(), + new ChannelCommand() + ); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/snipes/ChannelCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/snipes/ChannelCommand.java new file mode 100644 index 00000000..708f5c96 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/snipes/ChannelCommand.java @@ -0,0 +1,28 @@ +package de.kittybot.kittybot.commands.admin.settings.snipes; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionBoolean; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionChannel; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; + +public class ChannelCommand extends GuildSubCommand{ + + public ChannelCommand(){ + super("channel", "Used to enable/disable snipes in a specific channel"); + addOptions( + new CommandOptionChannel("channel", "The channel to enable/disable snipes").required(), + new CommandOptionBoolean("enabled", "Whether to enable/disable snipes").required() + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var channel = options.getTextChannel("channel"); + var enabled = options.getBoolean("enabled"); + ia.get(SettingsModule.class).setSnipesDisabledInChannel(ia.getGuildId(), channel.getIdLong(), !enabled); + ia.reply("Snipes `" + (enabled ? "enabled" : "disabled") + "` in " + channel.getAsMention()); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/snipes/EnableCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/snipes/EnableCommand.java new file mode 100644 index 00000000..39538676 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/snipes/EnableCommand.java @@ -0,0 +1,25 @@ +package de.kittybot.kittybot.commands.admin.settings.snipes; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionBoolean; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; + +public class EnableCommand extends GuildSubCommand{ + + public EnableCommand(){ + super("enable", "Used to globally disable snipes"); + addOptions( + new CommandOptionBoolean("enabled", "Whether to enable/disable snipes globally") + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var enabled = options.getBoolean("enabled"); + ia.get(SettingsModule.class).setSnipesEnabled(ia.getGuildId(), enabled); + ia.reply("Snipes globally `" + (enabled ? "enabled" : "disabled") + "`"); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/AddCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/AddCommand.java new file mode 100644 index 00000000..1c569364 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/AddCommand.java @@ -0,0 +1,36 @@ +package de.kittybot.kittybot.commands.admin.settings.streams; + +import de.kittybot.kittybot.modules.StreamModule; +import de.kittybot.kittybot.objects.streams.StreamType; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionString; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; + +public class AddCommand extends GuildSubCommand{ + + public AddCommand(){ + super("add", "Adds a new stream announcement for twitch"); + addOptions( +/*new CommandOptionInteger("service", "Which service the stream is from").required() +.addChoices( +new CommandOptionChoice<>("twitch", 1)/*, +new CommandOptionChoice<>("youtube", 2) +),*/ + new CommandOptionString("username", "The username of the streamer").required() + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var type = StreamType.TWITCH;//StreamType.byId(options.getInt("service")); + var username = options.getString("username"); + var user = ia.get(StreamModule.class).add(username, ia.getGuildId(), type); + if(user == null){ + ia.error("No user found with username " + username + "for " + type.getName()); + return; + } + ia.reply("Stream announcement for " + type.getName() + " with username: " + user.getDisplayName() + " added"); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/ChannelCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/ChannelCommand.java new file mode 100644 index 00000000..74a39507 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/ChannelCommand.java @@ -0,0 +1,25 @@ +package de.kittybot.kittybot.commands.admin.settings.streams; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionChannel; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; + +public class ChannelCommand extends GuildSubCommand{ + + public ChannelCommand(){ + super("channel", "Sets the stream announcement channel"); + addOptions( + new CommandOptionChannel("channel", "The channel which stream announcements should get send to").required() + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var channel = options.getTextChannel("channel"); + ia.get(SettingsModule.class).setStreamAnnouncementChannelId(ia.getGuildId(), channel.getIdLong()); + ia.reply("Stream announcements now get send to " + channel.getAsMention()); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/ListCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/ListCommand.java new file mode 100644 index 00000000..57ee2283 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/ListCommand.java @@ -0,0 +1,28 @@ +package de.kittybot.kittybot.commands.admin.settings.streams; + +import de.kittybot.kittybot.modules.StreamModule; +import de.kittybot.kittybot.objects.streams.StreamType; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; +import de.kittybot.kittybot.utils.MessageUtils; + +import java.util.stream.Collectors; + +public class ListCommand extends GuildSubCommand{ + + public ListCommand(){ + super("list", "Lists stream announcements"); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var streamAnnouncements = ia.get(StreamModule.class).getStreamAnnouncements(ia.getGuildId()); + if(streamAnnouncements.isEmpty()){ + ia.error("No stream announcements found. Create them with `/settings streamannouncements add `"); + return; + } + ia.reply("**Stream Announcements:**\n" + streamAnnouncements.stream().map(sa -> MessageUtils.maskLink(sa.getUserName(), "https://twitch.tv/" + sa.getUserName()) + " on " + sa.getStreamType().getName()).collect(Collectors.joining("\n"))); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/MessageCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/MessageCommand.java new file mode 100644 index 00000000..13a4f75c --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/MessageCommand.java @@ -0,0 +1,26 @@ +package de.kittybot.kittybot.commands.admin.settings.streams; + +import de.kittybot.kittybot.modules.SettingsModule; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionString; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; + +public class MessageCommand extends GuildSubCommand{ + + public MessageCommand(){ + super("message", "Sets the stream announcement message template"); + addOptions( + new CommandOptionString("message", "The message template").required() + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var message = options.getString("message"); + + ia.get(SettingsModule.class).setStreamAnnouncementMessage(ia.getGuildId(), message); + ia.reply("Set stream announcements template to:\n" + message); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/RemoveCommand.java b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/RemoveCommand.java new file mode 100644 index 00000000..47770f86 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/commands/admin/settings/streams/RemoveCommand.java @@ -0,0 +1,36 @@ +package de.kittybot.kittybot.commands.admin.settings.streams; + +import de.kittybot.kittybot.modules.StreamModule; +import de.kittybot.kittybot.objects.streams.StreamType; +import de.kittybot.kittybot.slashcommands.application.options.CommandOptionString; +import de.kittybot.kittybot.slashcommands.application.options.GuildSubCommand; +import de.kittybot.kittybot.slashcommands.interaction.GuildInteraction; +import de.kittybot.kittybot.slashcommands.interaction.Options; + +public class RemoveCommand extends GuildSubCommand{ + + public RemoveCommand(){ + super("remove", "Removes a stream announcement"); + addOptions( + /*new CommandOptionInteger("service", "Which service the stream is from").required() + .addChoices( + new CommandOptionChoice<>("twitch", 1)/*, + new CommandOptionChoice<>("youtube", 0) + ),*/ + new CommandOptionString("username", "The username of the streamer").required() + ); + } + + @Override + public void run(Options options, GuildInteraction ia){ + var type = StreamType.TWITCH;//StreamType.byId(options.getInt("service")); + var username = options.getString("username"); + var success = ia.get(StreamModule.class).remove(username, ia.getGuildId(), type); + if(!success){ + ia.error("Could not find stream announcement for " + type.getName() + " with username: " + username + ". Check your spelling"); + return; + } + ia.reply("Stream announcement for " + type.getName() + " with username: " + username + " removed"); + } + +} diff --git a/src/main/java/de/kittybot/kittybot/main/KittyBot.java b/src/main/java/de/kittybot/kittybot/main/KittyBot.java index 3452e869..0743b9fc 100644 --- a/src/main/java/de/kittybot/kittybot/main/KittyBot.java +++ b/src/main/java/de/kittybot/kittybot/main/KittyBot.java @@ -61,7 +61,7 @@ public KittyBot() throws IOException, MissingConfigValuesException, LoginExcepti CacheFlag.ROLE_TAGS ) .setMemberCachePolicy(MemberCachePolicy.VOICE) - .setChunkingFilter(ChunkingFilter.NONE) + .setChunkingFilter(ChunkingFilter.include(123456789L)) .addEventListeners(modules.getModules()) .addEventListeners(new BLHEventListener(botListHandler)) .setRawEventsEnabled(true) diff --git a/src/main/java/de/kittybot/kittybot/modules/DatabaseModule.java b/src/main/java/de/kittybot/kittybot/modules/DatabaseModule.java index 5cdaccfe..8f0c6a53 100644 --- a/src/main/java/de/kittybot/kittybot/modules/DatabaseModule.java +++ b/src/main/java/de/kittybot/kittybot/modules/DatabaseModule.java @@ -11,6 +11,7 @@ import org.jooq.conf.Settings; import org.jooq.impl.DSL; import org.jooq.impl.DefaultConfiguration; +import org.jooq.tools.jdbc.JDBCUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +39,6 @@ public void onEnable(){ "snipe_disabled_channels", "bot_ignored_members", "stream_users", - "stream_user_events", "reactive_messages", "self_assignable_role_messages", "notifications", diff --git a/src/main/java/de/kittybot/kittybot/modules/StreamAnnouncementModule.java b/src/main/java/de/kittybot/kittybot/modules/StreamAnnouncementModule.java deleted file mode 100644 index ba09c6c9..00000000 --- a/src/main/java/de/kittybot/kittybot/modules/StreamAnnouncementModule.java +++ /dev/null @@ -1,186 +0,0 @@ -package de.kittybot.kittybot.modules; - -import de.kittybot.kittybot.jooq.tables.records.StreamUsersRecord; -import de.kittybot.kittybot.objects.enums.AnnouncementType; -import de.kittybot.kittybot.objects.module.Module; -import de.kittybot.kittybot.objects.streams.Stream; -import de.kittybot.kittybot.objects.streams.StreamType; -import de.kittybot.kittybot.objects.streams.twitch.TwitchUser; -import de.kittybot.kittybot.objects.streams.twitch.TwitchWrapper; -import de.kittybot.kittybot.objects.streams.youtube.YouTubeWrapper; -import de.kittybot.kittybot.utils.Colors; -import de.kittybot.kittybot.utils.Config; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.events.ReadyEvent; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.time.Instant; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import static de.kittybot.kittybot.jooq.Tables.STREAM_USERS; - -public class StreamAnnouncementModule extends Module{ - - private static final Logger LOG = LoggerFactory.getLogger(StreamAnnouncementModule.class); - - private static final Set> DEPENDENCIES = Set.of(DatabaseModule.class); - - private List streamAnnouncements; - private TwitchWrapper twitchWrapper; - private YouTubeWrapper youTubeWrapper; - - @Override - public Set> getDependencies(){ - return DEPENDENCIES; - } - - @Override - public void onEnable(){ - if(Config.TWITCH_CLIENT_ID.isBlank() || Config.TWITCH_CLIENT_SECRET.isBlank()){ - LOG.error("Twitch disabled because twitch_client_id and twitch_client_secret are missing"); - } - else{ - this.twitchWrapper = new TwitchWrapper(Config.TWITCH_CLIENT_ID, Config.TWITCH_CLIENT_SECRET, this.modules.getHttpClient()); - } - try(var ctx = this.modules.get(DatabaseModule.class).getCtx().selectFrom(STREAM_USERS)){ - var result = ctx.fetch(); - result.detach(); - this.streamAnnouncements = result; - } - } - - @Override - public void onReady(@NotNull ReadyEvent event){ - this.modules.scheduleAtFixedRate(this::checkStreams, 0, 30, TimeUnit.SECONDS); - } - - private void checkStreams(){ - checkTwitch(); - checkYouTube(); - } - - private void checkTwitch(){ - var userIds = this.streamAnnouncements.stream().filter(streamAnnouncement -> streamAnnouncement.getStreamType() == StreamType.TWITCH.getId()) - .map(StreamUsersRecord::getUserId).collect(Collectors.toList()); - if(userIds.isEmpty()){ - return; - } - var streams = this.twitchWrapper.getStreams(userIds, false); - - for(var streamAnnouncement : this.streamAnnouncements){ - var stream = streams.stream().filter(st -> st.getUserId() == streamAnnouncement.getUserId()).findFirst(); - if(stream.isPresent() && !streamAnnouncement.getIsLive()){ - setLiveStatus(streamAnnouncement, true); - // send online - sendAnnouncementMessage(streamAnnouncement, stream.get(), AnnouncementType.START); - } - if(stream.isEmpty() && streamAnnouncement.getIsLive()){ - setLiveStatus(streamAnnouncement, false); - // send offline - //sendAnnouncementMessage(streamAnnouncement, null, AnnouncementType.END); - } - } - } - - private void checkYouTube(){ - - } - - private void setLiveStatus(StreamUsersRecord record, boolean status){ - record.setIsLive(status); - record.attach(this.modules.get(DatabaseModule.class).getConfiguration()); - record.store(); - record.detach(); - } - - private void sendAnnouncementMessage(StreamUsersRecord streamAnnouncement, Stream stream, AnnouncementType announcementType){ - var guildId = streamAnnouncement.getGuildId(); - var guild = this.modules.getGuildById(guildId); - if(guild == null){ - return; - } - var settings = this.modules.get(SettingsModule.class).getSettings(guildId); - - var channel = guild.getTextChannelById(settings.getStreamAnnouncementChannelId()); - if(channel == null || !channel.canTalk()){ - return; - } - var embed = new EmbedBuilder(); - var streamThumbnailUrl = stream.getThumbnailUrl(320, 180); - InputStream thumbnail; - try{ - thumbnail = new URL(streamThumbnailUrl).openStream(); - } - catch(IOException e){ - LOG.error("Failed to get thumbnail url", e); - return; - } - switch(announcementType){ - case END: - embed.setAuthor(stream.getUserName(), stream.getStreamUrl()); - break; - case START: - embed.setTitle(stream.getStreamTitle(), stream.getStreamUrl()) - .setImage("attachment://thumbnail.png") - .setThumbnail(stream.getGame().getThumbnailUrl(144, 192)) - .addField("Game", stream.getGame().getName(), true); - break; - } - channel.sendMessage(settings.getStreamAnnouncementMessage().replace("${user}", stream.getUserName())) - .embed(embed - .setTimestamp(Instant.now()) - .setColor(Colors.TWITCH_PURPLE) - .build() - ) - .addFile(thumbnail, "thumbnail.png") - .queue(); - } - - public TwitchUser add(String name, long guildId, StreamType type){ - var user = this.twitchWrapper.getUserByUsername(name, false); - if(user == null){ - return null; - } - var record = new StreamUsersRecord() - .setUserId(user.getId()) - .setUserName(user.getDisplayName()) - .setGuildId(guildId) - .setStreamType(type.getId()); - - record.attach(this.modules.get(DatabaseModule.class).getConfiguration()); - record.store(); - record.detach(); - this.streamAnnouncements.add(record); - return user; - } - - public List get(long guildId){ - return this.streamAnnouncements.stream().filter(stream -> stream.getGuildId() == guildId).collect(Collectors.toList()); - } - - public boolean remove(String name, long guildId, StreamType type){ - var user = this.twitchWrapper.getUserByUsername(name, false); - if(user == null){ - return false; - } - var optionalRecord = this.streamAnnouncements.stream().filter(stream -> stream.getUserId() == user.getId() && stream.getGuildId() == guildId && stream.getStreamType() == type.getId()).findFirst(); - if(optionalRecord.isEmpty()){ - return false; - } - var record = optionalRecord.get(); - record.attach(this.modules.get(DatabaseModule.class).getConfiguration()); - record.delete(); - record.detach(); - this.streamAnnouncements.remove(record); - return true; - } - -} diff --git a/src/main/java/de/kittybot/kittybot/modules/StreamModule.java b/src/main/java/de/kittybot/kittybot/modules/StreamModule.java new file mode 100644 index 00000000..9c72d0a4 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/modules/StreamModule.java @@ -0,0 +1,167 @@ +package de.kittybot.kittybot.modules; + +import de.kittybot.kittybot.objects.enums.AnnouncementType; +import de.kittybot.kittybot.objects.module.Module; +import de.kittybot.kittybot.objects.settings.StreamAnnouncement; +import de.kittybot.kittybot.objects.streams.Stream; +import de.kittybot.kittybot.objects.streams.StreamType; +import de.kittybot.kittybot.objects.streams.twitch.Subscription; +import de.kittybot.kittybot.objects.streams.twitch.TwitchUser; +import de.kittybot.kittybot.objects.streams.twitch.TwitchWrapper; +import de.kittybot.kittybot.utils.Colors; +import de.kittybot.kittybot.utils.Config; +import net.dv8tion.jda.api.EmbedBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.time.Instant; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import static de.kittybot.kittybot.jooq.Tables.STREAM_USERS; + +public class StreamModule extends Module{ + + private static final Logger LOG = LoggerFactory.getLogger(StreamModule.class); + + private TwitchWrapper twitchWrapper; + + @Override + public Set> getDependencies(){ + return Set.of(DatabaseModule.class); + } + + @Override + public void onEnable(){ + if(Config.TWITCH_CLIENT_ID.isBlank() || Config.TWITCH_CLIENT_SECRET.isBlank() || Config.TWITCH_WEBHOOK_CALLBACK.isBlank() || Config.TWITCH_WEBHOOK_SECRET.isBlank()){ + LOG.error("Twitch disabled because twitch_client_id and twitch_client_secret are missing"); + } + else{ + this.twitchWrapper = new TwitchWrapper(Config.TWITCH_CLIENT_ID, Config.TWITCH_CLIENT_SECRET, Config.TWITCH_WEBHOOK_CALLBACK, Config.TWITCH_WEBHOOK_SECRET, this.modules.getHttpClient()); + } + } + + public void sendAnnouncementMessage(Collection streamAnnouncements, Stream stream, AnnouncementType announcementType){ + var embed = new EmbedBuilder(); + var streamThumbnailUrl = stream.getThumbnailUrl(320, 180); + InputStream thumbnail; + try{ + thumbnail = new URL(streamThumbnailUrl).openStream(); + } + catch(IOException e){ + LOG.error("Failed to get thumbnail url", e); + return; + } + switch(announcementType){ + case END: + embed.setAuthor(stream.getUserName(), stream.getStreamUrl()); + break; + case START: + embed.setTitle(stream.getStreamTitle(), stream.getStreamUrl()) + .setImage("attachment://thumbnail.png") + .setThumbnail(stream.getGame().getThumbnailUrl(144, 192)) + .addField("Game", stream.getGame().getName(), true); + break; + } + for(var streamAnnouncement : streamAnnouncements){ + System.out.println(streamAnnouncement); + var guildId = streamAnnouncement.getGuildId(); + var guild = this.modules.getGuildById(guildId); + if(guild == null){ + return; + } + var settings = this.modules.get(SettingsModule.class).getSettings(guildId); + + var channel = guild.getTextChannelById(settings.getStreamAnnouncementChannelId()); + if(channel == null || !channel.canTalk()){ + return; + } + channel.sendMessage(settings.getStreamAnnouncementMessage().replace("${user}", stream.getUserName())) + .embed(embed + .setTimestamp(Instant.now()) + .setColor(Colors.TWITCH_PURPLE) + .build() + ) + .addFile(thumbnail, "thumbnail.png") + .queue(); + } + } + + public TwitchUser add(String name, long guildId, StreamType type){ + var user = this.twitchWrapper.getUserByUsername(name, false); + if(user == null){ + return null; + } + + var rows = this.modules.get(DatabaseModule.class).getCtx() + .insertInto(STREAM_USERS) + .columns(STREAM_USERS.GUILD_ID, STREAM_USERS.USER_ID, STREAM_USERS.USER_NAME, STREAM_USERS.STREAM_TYPE) + .values(guildId, user.getId(), user.getDisplayName(), type.getId()) + .onConflict(STREAM_USERS.GUILD_ID, STREAM_USERS.USER_ID, STREAM_USERS.STREAM_TYPE) + .doNothing() + .execute(); + if(rows == 0){ + return null; + } + + if(this.twitchWrapper.getSubscriptions().values().stream().noneMatch(subscription -> subscription.getConditions().stream().noneMatch(condition -> condition.getValue() instanceof Long && ((Long) condition.getValue()) == user.getId()))){ + this.twitchWrapper.subscribe(Subscription.Type.STREAM_ONLINE, new Subscription.Condition("broadcaster_user_id", Long.toString(user.getId()))); + this.twitchWrapper.subscribe(Subscription.Type.STREAM_OFFLINE, new Subscription.Condition("broadcaster_user_id", Long.toString(user.getId()))); + } + + return user; + } + + public boolean remove(String name, long guildId, StreamType type){ + var user = this.twitchWrapper.getUserByUsername(name, false); + if(user == null){ + return false; + } + + var records = this.modules.get(DatabaseModule.class).getCtx() + .selectFrom(STREAM_USERS) + .where(STREAM_USERS.USER_ID.eq(user.getId()) + .and(STREAM_USERS.STREAM_TYPE.eq(type.getId())) + ).fetch(); + + var subscription = this.twitchWrapper.getSubscriptions().values().stream().filter(sub -> + sub.getConditions().stream().anyMatch(condition -> + condition.getValue().equals("broadcaster_user_id") && condition.getValue() instanceof Long && ((Long) condition.getValue()) == user.getId() + ) + ).findFirst(); + + if(subscription.isPresent()){ + this.twitchWrapper.unsubscribe(subscription.get().getId()); + this.twitchWrapper.unsubscribe(subscription.get().getId()); + } + + var rows = this.modules.get(DatabaseModule.class).getCtx() + .deleteFrom(STREAM_USERS) + .where(STREAM_USERS.GUILD_ID.eq(guildId) + .and(STREAM_USERS.USER_ID.eq(user.getId()) + .and(STREAM_USERS.STREAM_TYPE.eq(type.getId()))) + ).execute(); + return rows == 1; + } + + public TwitchWrapper getTwitchWrapper(){ + return this.twitchWrapper; + } + + public List getStreamAnnouncements(long userId, StreamType type){ + try(var ctx = this.modules.get(DatabaseModule.class).getCtx().selectFrom(STREAM_USERS)){ + return ctx.where(STREAM_USERS.USER_ID.eq(userId).and(STREAM_USERS.STREAM_TYPE.eq(type.getId()))).fetch(StreamAnnouncement::new); + } + } + + public List getStreamAnnouncements(long guildId){ + try(var ctx = this.modules.get(DatabaseModule.class).getCtx().selectFrom(STREAM_USERS)){ + return ctx.where(STREAM_USERS.GUILD_ID.eq(guildId)).fetch(StreamAnnouncement::new); + } + } + +} diff --git a/src/main/java/de/kittybot/kittybot/modules/WebModule.java b/src/main/java/de/kittybot/kittybot/modules/WebModule.java index 29ea46de..5b6e5cc8 100644 --- a/src/main/java/de/kittybot/kittybot/modules/WebModule.java +++ b/src/main/java/de/kittybot/kittybot/modules/WebModule.java @@ -23,6 +23,7 @@ import de.kittybot.kittybot.web.login.PostLoginRoute; import de.kittybot.kittybot.web.shards.GetShardsRoute; import de.kittybot.kittybot.web.user.GetUserInfoRoute; +import de.kittybot.kittybot.web.webhooks.twitch.PostTwitchRoute; import de.kittybot.kittybot.web.webhooks.votes.PostVotesRoute; import io.javalin.Javalin; import io.javalin.http.*; @@ -95,9 +96,14 @@ public void onEnable(){ before("/*", this::checkDiscordLogin); get(new GetUserInfoRoute(this.modules)); }); - path("/webhooks/votes/:botlist", () -> - post(new PostVotesRoute(this.modules)) - ); + path("/webhooks", () -> { + path("/votes/:botlist", () -> + post(new PostVotesRoute(this.modules)) + ); + path("/twitch", () -> + post(new PostTwitchRoute(this.modules)) + ); + }); path("/guilds", () -> { before("/*", this::checkDiscordLogin); get(new GetAllGuildsRoute(this.modules)); diff --git a/src/main/java/de/kittybot/kittybot/objects/settings/StreamAnnouncement.java b/src/main/java/de/kittybot/kittybot/objects/settings/StreamAnnouncement.java index d441d940..5076c850 100644 --- a/src/main/java/de/kittybot/kittybot/objects/settings/StreamAnnouncement.java +++ b/src/main/java/de/kittybot/kittybot/objects/settings/StreamAnnouncement.java @@ -8,7 +8,6 @@ public class StreamAnnouncement{ private final long id, userId, guildId; private final String userName; private final StreamType streamType; - private boolean isLive; public StreamAnnouncement(long userId, String userName, long guildId, StreamType streamType){ this.id = -1; @@ -16,7 +15,6 @@ public StreamAnnouncement(long userId, String userName, long guildId, StreamType this.userName = userName; this.guildId = guildId; this.streamType = streamType; - this.isLive = false; } public StreamAnnouncement(StreamUsersRecord record){ @@ -25,7 +23,6 @@ public StreamAnnouncement(StreamUsersRecord record){ this.userName = record.getUserName(); this.guildId = record.getGuildId(); this.streamType = StreamType.byId(record.getStreamType()); - this.isLive = record.getIsLive(); } public long getId(){ @@ -48,14 +45,6 @@ public StreamType getStreamType(){ return this.streamType; } - public boolean isLive(){ - return this.isLive; - } - - public void setLive(boolean isLive){ - this.isLive = isLive; - } - public String getStreamUrl(){ if(this.streamType == StreamType.TWITCH){ return this.streamType.getBaseUrl() + this.userName; diff --git a/src/main/java/de/kittybot/kittybot/objects/streams/twitch/Subscription.java b/src/main/java/de/kittybot/kittybot/objects/streams/twitch/Subscription.java new file mode 100644 index 00000000..c5efb304 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/objects/streams/twitch/Subscription.java @@ -0,0 +1,182 @@ +package de.kittybot.kittybot.objects.streams.twitch; + +import net.dv8tion.jda.api.utils.data.DataObject; + +import java.time.Instant; +import java.util.Set; +import java.util.stream.Collectors; + +public class Subscription{ + + private final String id; + private Status status; + private final Type type; + private final int version; + private final Set conditions; + private final Instant createdAt; + private final Transport transport; + + public Subscription(String id, Status status, Type type, int version, Set conditions, Instant createdAt, Transport transport){ + this.id = id; + this.status = status; + this.type = type; + this.version = version; + this.conditions = conditions; + this.createdAt = createdAt; + this.transport = transport; + } + + public String getId(){ + return this.id; + } + + public Status getStatus(){ + return this.status; + } + + public void setStatus(Status status){ + this.status = status; + } + + public Type getType(){ + return this.type; + } + + public int getVersion(){ + return this.version; + } + + public Set getConditions(){ + return this.conditions; + } + + public Instant getCreatedAt(){ + return this.createdAt; + } + + public Transport getTransport(){ + return this.transport; + } + + public static Subscription fromJSON(DataObject json){ + return new Subscription( + json.getString("id"), + Status.fromText(json.getString("status")), + Type.fromText(json.getString("type")), + json.getInt("version"), + Condition.fromJSON(json.getObject("condition")), + Instant.parse(json.getString("created_at")), + Transport.fromJSON(json.getObject("transport")) + ); + } + + public enum Status{ + + ENABLED("enabled"), + WEBHOOK_CALLBACK_VERIFICATION_PENDING("webhook_callback_verification_pending"), + WEBHOOK_CALLBACK_VERIFICATION_FAILED("webhook_callback_verification_failed"), + NOTIFICATION_FAILURES_EXCEEDED("notification_failures_exceeded"), + AUTHORIZATION_REVOKED("authorization_revoked"), + USER_REMOVED("user_removed"); + + private final String text; + + Status(String text){ + this.text = text; + } + + public static Status fromText(String text){ + for(var value : values()){ + if(value.text.equals(text)){ + return value; + } + } + throw new IllegalArgumentException("unknown status received"); + } + + public String getText(){ + return this.text; + } + + } + + public enum Type{ + + STREAM_ONLINE("stream.online"), + STREAM_OFFLINE("stream.offline"); + + private final String text; + + Type(String text){ + this.text = text; + } + + public static Type fromText(String text){ + for(var value : values()){ + if(value.text.equals(text)){ + return value; + } + } + throw new IllegalArgumentException("unknown type received"); + } + + public String getText(){ + return this.text; + } + + } + + public static class Condition{ + + private final String key; + private final Object value; + + public Condition(String key, Object value){ + this.key = key; + this.value = value; + } + + public static Set fromJSON(DataObject json){ + var conditions = json.keys(); + return conditions.stream().map(key -> new Condition(key, json.getString(key))).collect(Collectors.toSet()); + } + + public DataObject toJSON(){ + return DataObject.empty() + .put(this.key, this.value); + } + + public String getKey(){ + return this.key; + } + + public Object getValue(){ + return this.value; + } + + } + + public static class Transport{ + + private final String method, callback; + + public Transport(String method, String callback){ + this.method = method; + this.callback = callback; + } + + public static Transport fromJSON(DataObject json){ + return new Transport(json.getString("method"), json.getString("callback")); + } + + public String getMethod(){ + return this.method; + } + + public String getCallback(){ + return this.callback; + } + + } + +} diff --git a/src/main/java/de/kittybot/kittybot/objects/streams/twitch/TwitchWrapper.java b/src/main/java/de/kittybot/kittybot/objects/streams/twitch/TwitchWrapper.java index 8fb75606..cc004614 100644 --- a/src/main/java/de/kittybot/kittybot/objects/streams/twitch/TwitchWrapper.java +++ b/src/main/java/de/kittybot/kittybot/objects/streams/twitch/TwitchWrapper.java @@ -2,17 +2,18 @@ import de.kittybot.kittybot.objects.streams.BearerToken; import de.kittybot.kittybot.objects.streams.Stream; +import de.kittybot.kittybot.utils.Config; import net.dv8tion.jda.api.utils.data.DataObject; -import okhttp3.Call; -import okhttp3.FormBody; -import okhttp3.OkHttpClient; -import okhttp3.Request; +import net.dv8tion.jda.internal.requests.Method; +import net.dv8tion.jda.internal.requests.Requester; +import net.dv8tion.jda.internal.requests.Route; +import okhttp3.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; public class TwitchWrapper{ @@ -20,22 +21,38 @@ public class TwitchWrapper{ private static final Logger LOG = LoggerFactory.getLogger(TwitchWrapper.class); private static final String BASE_URL = "https://api.twitch.tv/helix/"; private static final String OAUTH2_URL = "https://id.twitch.tv/oauth2/token"; + private static final Route CREATE_SUBSCRIPTION = Route.custom(Method.POST, "eventsub/subscriptions"); + private static final Route DELETE_SUBSCRIPTION = Route.custom(Method.DELETE, "eventsub/subscriptions?id={subscription.id}"); + private static final Route GET_SUBSCRIPTIONS = Route.custom(Method.GET, "eventsub/subscriptions"); private final String clientId; private final String clientSecret; + private final String webhookCallback; + private final String webhookSecret; private final OkHttpClient httpClient; private BearerToken bearerToken; + private final Map subscriptions; - public TwitchWrapper(String clientId, String clientSecret, OkHttpClient httpClient){ + public TwitchWrapper(String clientId, String clientSecret, String webhookCallback, String webhookSecret, OkHttpClient httpClient){ this.clientId = clientId; this.clientSecret = clientSecret; + this.webhookCallback = webhookCallback; + this.webhookSecret = webhookSecret; this.httpClient = httpClient; this.bearerToken = requestBearerToken(); + this.subscriptions = new HashMap<>(); if(this.bearerToken == null){ LOG.error("Could not retrieve Bearer Token. Please check your twitch client id & token"); return; } LOG.info("Bearer Token retrieved"); + LOG.info("Bearer Token: {}", bearerToken.getAccessToken()); + var subscriptions = retrieveSubscriptions(); + if(subscriptions == null){ + LOG.error("Error while retrieving active subscriptions"); + return; + } + this.subscriptions.putAll(subscriptions); } private BearerToken requestBearerToken(){ @@ -59,6 +76,66 @@ private BearerToken requestBearerToken(){ return null; } + public boolean subscribe(Subscription.Type type, Subscription.Condition condition){ + var rqBody = DataObject.empty() + .put("type", type.getText()) + .put("version", "1") + .put("condition", condition.toJSON()) + .put("transport", DataObject.empty() + .put("method", "webhook") + .put("callback", this.webhookCallback) + .put("secret", this.webhookSecret) + ); + LOG.info("Body: {}", rqBody.toString()); + try(var response = newCall(CREATE_SUBSCRIPTION.compile(), RequestBody.create(rqBody.toJson(), MediaType.parse("application/json"))).execute()){ + var body = response.body(); + if(body == null){ + return false; + } + var json = DataObject.fromJson(body.byteStream()); + if(response.isSuccessful()){ + var data = json.getArray("data"); + this.subscriptions.putAll(data.stream((array, i) -> Subscription.fromJSON(array.getObject(i))).collect(Collectors.toMap(Subscription::getId, Function.identity()))); + return true; + } + LOG.error("Error while subscribing to events Body: {}", json.toString()); + } + catch(IOException e){ + LOG.error("Error while subscribing to events"); + } + return false; + } + + public boolean unsubscribe(String id){ + try(var response = newCall(DELETE_SUBSCRIPTION.compile(id), null).execute()){ + if(response.isSuccessful()){ + return true; + } + } + catch(IOException e){ + LOG.error("Error while unsubscribing to events"); + } + return false; + } + + public Map retrieveSubscriptions(){ + try(var response = newCall(GET_SUBSCRIPTIONS.compile(), null).execute()){ + if(response.isSuccessful()){ + var body = response.body(); + if(body == null){ + return null; + } + var json = DataObject.fromJson(body.byteStream()); + var data = json.getArray("data"); + return data.stream((array, i) -> Subscription.fromJSON(array.getObject(i))).collect(Collectors.toMap(Subscription::getId, Function.identity())); + } + } + catch(IOException e){ + LOG.error("Error while unsubscribing to events"); + } + return null; + } + public TwitchUser getUserByUsername(String username, boolean reTry){ try(var resp = newRequest("users?login=%s", username).execute()){ var body = resp.body(); @@ -100,35 +177,48 @@ private Call newRequest(String url, Object... params){ ); } - public List getStreams(List userIds, boolean reTry){ - var streams = new ArrayList(); - do{ - var users = userIds.subList(0, Math.min(userIds.size(), 100)); - var query = users.stream().map(user -> "user_id=" + user).collect(Collectors.joining("&")); - users.clear(); - try(var resp = newRequest("streams?" + query).execute()){ - var body = resp.body(); - if(!resp.isSuccessful() || body == null){ - LOG.error("Url: {} Code: {} Body: {}", resp.request().url(), resp.code(), body == null ? "null" : body.string()); - if(resp.code() == 401){ - this.bearerToken = null; - if(!reTry){ - return getStreams(userIds, true); - } + public Stream getStream(long userId, boolean reTry){ + try(var resp = newRequest("streams?user_id=" + userId).execute()){ + var body = resp.body(); + if(!resp.isSuccessful() || body == null){ + LOG.error("Url: {} Code: {} Body: {}", resp.request().url(), resp.code(), body == null ? "null" : body.string()); + if(resp.code() == 401){ + this.bearerToken = null; + if(!reTry){ + return getStream(userId, true); } - continue; } - var data = DataObject.fromJson(body.string()).getArray("data"); - for(var o = 0; o < data.length(); o++){ - streams.add(Stream.fromTwitchJSON(data.getObject(o))); - } - } - catch(IOException e){ - LOG.error("Error while unpacking request body", e); + return null; } + var data = DataObject.fromJson(body.byteStream()).getArray("data"); + return Stream.fromTwitchJSON(data.getObject(0)); } - while(!userIds.isEmpty()); - return streams; + catch(IOException e){ + LOG.error("Error while unpacking request body", e); + } + return null; + } + + private Call newCall(Route.CompiledRoute route, RequestBody body){ + return this.httpClient.newCall(newBuilder(route).method(route.getMethod().name(), body).build()); + } + + private Request.Builder newBuilder(Route.CompiledRoute route){ + if(this.bearerToken == null || this.bearerToken.isExpired()){ + this.bearerToken = requestBearerToken(); + LOG.info("New Bearer Token retrieved"); + } + if(this.bearerToken == null){ + throw new NullPointerException("bearerToken is null"); + } + return new Request.Builder() + .url(BASE_URL + route.getCompiledRoute()) + .addHeader("Client-ID", this.clientId) + .addHeader("Authorization", this.bearerToken.getAccessToken()); + } + + public Map getSubscriptions(){ + return this.subscriptions; } } diff --git a/src/main/java/de/kittybot/kittybot/objects/streams/youtube/YouTubeWrapper.java b/src/main/java/de/kittybot/kittybot/objects/streams/youtube/YouTubeWrapper.java deleted file mode 100644 index 5e8485c4..00000000 --- a/src/main/java/de/kittybot/kittybot/objects/streams/youtube/YouTubeWrapper.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.kittybot.kittybot.objects.streams.youtube; - -public class YouTubeWrapper{ - // TODO -} diff --git a/src/main/java/de/kittybot/kittybot/utils/Config.java b/src/main/java/de/kittybot/kittybot/utils/Config.java index 9e9ffdac..20be1976 100644 --- a/src/main/java/de/kittybot/kittybot/utils/Config.java +++ b/src/main/java/de/kittybot/kittybot/utils/Config.java @@ -34,6 +34,8 @@ public class Config{ public static String TWITCH_CLIENT_ID; public static String TWITCH_CLIENT_SECRET; + public static String TWITCH_WEBHOOK_SECRET; + public static String TWITCH_WEBHOOK_CALLBACK; public static String SIGNING_KEY; @@ -104,6 +106,8 @@ public static void init(String path) throws IOException, MissingConfigValuesExce TWITCH_CLIENT_ID = json.getString("twitch_client_id", ""); TWITCH_CLIENT_SECRET = json.getString("twitch_client_secret", ""); + TWITCH_WEBHOOK_SECRET = json.getString("twitch_webhook_secret", ""); + TWITCH_WEBHOOK_CALLBACK = json.getString("twitch_webhook_callback", ""); SIGNING_KEY = json.getString("signing_key", ""); diff --git a/src/main/java/de/kittybot/kittybot/web/webhooks/twitch/PostTwitchRoute.java b/src/main/java/de/kittybot/kittybot/web/webhooks/twitch/PostTwitchRoute.java new file mode 100644 index 00000000..a3cfca81 --- /dev/null +++ b/src/main/java/de/kittybot/kittybot/web/webhooks/twitch/PostTwitchRoute.java @@ -0,0 +1,53 @@ +package de.kittybot.kittybot.web.webhooks.twitch; + +import de.kittybot.kittybot.modules.StreamModule; +import de.kittybot.kittybot.objects.enums.AnnouncementType; +import de.kittybot.kittybot.objects.module.Modules; +import de.kittybot.kittybot.objects.streams.StreamType; +import de.kittybot.kittybot.objects.streams.twitch.Subscription; +import io.javalin.http.Context; +import io.javalin.http.Handler; +import net.dv8tion.jda.api.utils.data.DataObject; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PostTwitchRoute implements Handler{ + + private static final Logger LOG = LoggerFactory.getLogger(PostTwitchRoute.class); + + private final Modules modules; + + public PostTwitchRoute(Modules modules){ + this.modules = modules; + } + + @Override + public void handle(@NotNull Context ctx){ + // var signature = ctx.header("Twitch-Eventsub-Message-Signature"); + // TODO verify requests + var data = DataObject.fromJson(ctx.bodyAsInputStream()); + System.out.println(data.toString()); + var subscription = Subscription.fromJSON(data.getObject("subscription")); + System.out.println("subscription: " + subscription.toString()); + if(data.hasKey("challenge")){ + ctx.status(200); + ctx.result(data.getString("challenge")); + this.modules.get(StreamModule.class).getTwitchWrapper().getSubscriptions().get(subscription.getId()).setStatus(Subscription.Status.ENABLED); + } + else if(subscription.getType() == Subscription.Type.STREAM_ONLINE){ + var event = data.getObject("event"); + var streamModule = this.modules.get(StreamModule.class); + var stream = streamModule.getTwitchWrapper().getStream(event.getLong("broadcaster_user_id"), true); + var streamAnnouncements = streamModule.getStreamAnnouncements(event.getLong("broadcaster_user_id"), StreamType.TWITCH); + streamModule.sendAnnouncementMessage(streamAnnouncements, stream, AnnouncementType.START); + } + else if(subscription.getType() == Subscription.Type.STREAM_OFFLINE){ + // TODO + } + else{ + LOG.error("unhandled event type received from twitch Body: {}", ctx.body()); + } + } + +} diff --git a/src/main/jooq/de/kittybot/kittybot/jooq/Keys.java b/src/main/jooq/de/kittybot/kittybot/jooq/Keys.java index 6de5da4a..b982c1b6 100644 --- a/src/main/jooq/de/kittybot/kittybot/jooq/Keys.java +++ b/src/main/jooq/de/kittybot/kittybot/jooq/Keys.java @@ -19,7 +19,6 @@ import de.kittybot.kittybot.jooq.tables.SelfAssignableRoles; import de.kittybot.kittybot.jooq.tables.Sessions; import de.kittybot.kittybot.jooq.tables.SnipeDisabledChannels; -import de.kittybot.kittybot.jooq.tables.StreamUserEvents; import de.kittybot.kittybot.jooq.tables.StreamUsers; import de.kittybot.kittybot.jooq.tables.UserStatistics; import de.kittybot.kittybot.jooq.tables.Voters; @@ -38,7 +37,6 @@ import de.kittybot.kittybot.jooq.tables.records.SelfAssignableRolesRecord; import de.kittybot.kittybot.jooq.tables.records.SessionsRecord; import de.kittybot.kittybot.jooq.tables.records.SnipeDisabledChannelsRecord; -import de.kittybot.kittybot.jooq.tables.records.StreamUserEventsRecord; import de.kittybot.kittybot.jooq.tables.records.StreamUsersRecord; import de.kittybot.kittybot.jooq.tables.records.UserStatisticsRecord; import de.kittybot.kittybot.jooq.tables.records.VotersRecord; @@ -61,7 +59,6 @@ public class Keys { // UNIQUE and PRIMARY KEY definitions // ------------------------------------------------------------------------- - public static final UniqueKey BOT_DISABLED_CHANNELS_CHANNEL_ID_KEY = Internal.createUniqueKey(BotDisabledChannels.BOT_DISABLED_CHANNELS, DSL.name("bot_disabled_channels_channel_id_key"), new TableField[] { BotDisabledChannels.BOT_DISABLED_CHANNELS.CHANNEL_ID }, true); public static final UniqueKey BOT_DISABLED_CHANNELS_GUILD_ID_CHANNEL_ID_KEY = Internal.createUniqueKey(BotDisabledChannels.BOT_DISABLED_CHANNELS, DSL.name("bot_disabled_channels_guild_id_channel_id_key"), new TableField[] { BotDisabledChannels.BOT_DISABLED_CHANNELS.GUILD_ID, BotDisabledChannels.BOT_DISABLED_CHANNELS.CHANNEL_ID }, true); public static final UniqueKey BOT_DISABLED_CHANNELS_PKEY = Internal.createUniqueKey(BotDisabledChannels.BOT_DISABLED_CHANNELS, DSL.name("bot_disabled_channels_pkey"), new TableField[] { BotDisabledChannels.BOT_DISABLED_CHANNELS.ID }, true); public static final UniqueKey BOT_IGNORED_MEMBERS_GUILD_ID_USER_ID_KEY = Internal.createUniqueKey(BotIgnoredMembers.BOT_IGNORED_MEMBERS, DSL.name("bot_ignored_members_guild_id_user_id_key"), new TableField[] { BotIgnoredMembers.BOT_IGNORED_MEMBERS.GUILD_ID, BotIgnoredMembers.BOT_IGNORED_MEMBERS.USER_ID }, true); @@ -89,9 +86,7 @@ public class Keys { public static final UniqueKey SESSIONS_USER_ID_KEY = Internal.createUniqueKey(Sessions.SESSIONS, DSL.name("sessions_user_id_key"), new TableField[] { Sessions.SESSIONS.USER_ID }, true); public static final UniqueKey SNIPE_DISABLED_CHANNELS_GUILD_ID_CHANNEL_ID_KEY = Internal.createUniqueKey(SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS, DSL.name("snipe_disabled_channels_guild_id_channel_id_key"), new TableField[] { SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS.GUILD_ID, SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS.CHANNEL_ID }, true); public static final UniqueKey SNIPE_DISABLED_CHANNELS_PKEY = Internal.createUniqueKey(SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS, DSL.name("snipe_disabled_channels_pkey"), new TableField[] { SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS.ID }, true); - public static final UniqueKey STREAM_USER_EVENTS_PKEY = Internal.createUniqueKey(StreamUserEvents.STREAM_USER_EVENTS, DSL.name("stream_user_events_pkey"), new TableField[] { StreamUserEvents.STREAM_USER_EVENTS.ID }, true); - public static final UniqueKey STREAM_USER_EVENTS_STREAM_USER_ID_EVENT_KEY = Internal.createUniqueKey(StreamUserEvents.STREAM_USER_EVENTS, DSL.name("stream_user_events_stream_user_id_event_key"), new TableField[] { StreamUserEvents.STREAM_USER_EVENTS.STREAM_USER_ID, StreamUserEvents.STREAM_USER_EVENTS.EVENT }, true); - public static final UniqueKey STREAM_USERS_GUILD_ID_USER_ID_KEY = Internal.createUniqueKey(StreamUsers.STREAM_USERS, DSL.name("stream_users_guild_id_user_id_key"), new TableField[] { StreamUsers.STREAM_USERS.GUILD_ID, StreamUsers.STREAM_USERS.USER_ID }, true); + public static final UniqueKey STREAM_USERS_GUILD_ID_USER_ID_STREAM_TYPE_KEY = Internal.createUniqueKey(StreamUsers.STREAM_USERS, DSL.name("stream_users_guild_id_user_id_stream_type_key"), new TableField[] { StreamUsers.STREAM_USERS.GUILD_ID, StreamUsers.STREAM_USERS.USER_ID, StreamUsers.STREAM_USERS.STREAM_TYPE }, true); public static final UniqueKey STREAM_USERS_PKEY = Internal.createUniqueKey(StreamUsers.STREAM_USERS, DSL.name("stream_users_pkey"), new TableField[] { StreamUsers.STREAM_USERS.ID }, true); public static final UniqueKey USER_STATISTICS_PKEY = Internal.createUniqueKey(UserStatistics.USER_STATISTICS, DSL.name("user_statistics_pkey"), new TableField[] { UserStatistics.USER_STATISTICS.ID }, true); public static final UniqueKey VOTERS_PKEY = Internal.createUniqueKey(Voters.VOTERS, DSL.name("voters_pkey"), new TableField[] { Voters.VOTERS.ID }, true); @@ -115,7 +110,6 @@ public class Keys { public static final ForeignKey SELF_ASSIGNABLE_ROLES__SELF_ASSIGNABLE_ROLES_GROUP_ID_FKEY = Internal.createForeignKey(SelfAssignableRoles.SELF_ASSIGNABLE_ROLES, DSL.name("self_assignable_roles_group_id_fkey"), new TableField[] { SelfAssignableRoles.SELF_ASSIGNABLE_ROLES.GROUP_ID }, Keys.SELF_ASSIGNABLE_ROLE_GROUPS_PKEY, new TableField[] { SelfAssignableRoleGroups.SELF_ASSIGNABLE_ROLE_GROUPS.ID }, true); public static final ForeignKey SELF_ASSIGNABLE_ROLES__SELF_ASSIGNABLE_ROLES_GUILD_ID_FKEY = Internal.createForeignKey(SelfAssignableRoles.SELF_ASSIGNABLE_ROLES, DSL.name("self_assignable_roles_guild_id_fkey"), new TableField[] { SelfAssignableRoles.SELF_ASSIGNABLE_ROLES.GUILD_ID }, Keys.GUILDS_PKEY, new TableField[] { Guilds.GUILDS.ID }, true); public static final ForeignKey SNIPE_DISABLED_CHANNELS__SNIPE_DISABLED_CHANNELS_GUILD_ID_FKEY = Internal.createForeignKey(SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS, DSL.name("snipe_disabled_channels_guild_id_fkey"), new TableField[] { SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS.GUILD_ID }, Keys.GUILDS_PKEY, new TableField[] { Guilds.GUILDS.ID }, true); - public static final ForeignKey STREAM_USER_EVENTS__STREAM_USER_EVENTS_STREAM_USER_ID_FKEY = Internal.createForeignKey(StreamUserEvents.STREAM_USER_EVENTS, DSL.name("stream_user_events_stream_user_id_fkey"), new TableField[] { StreamUserEvents.STREAM_USER_EVENTS.STREAM_USER_ID }, Keys.STREAM_USERS_PKEY, new TableField[] { StreamUsers.STREAM_USERS.ID }, true); public static final ForeignKey STREAM_USERS__STREAM_USERS_GUILD_ID_FKEY = Internal.createForeignKey(StreamUsers.STREAM_USERS, DSL.name("stream_users_guild_id_fkey"), new TableField[] { StreamUsers.STREAM_USERS.GUILD_ID }, Keys.GUILDS_PKEY, new TableField[] { Guilds.GUILDS.ID }, true); public static final ForeignKey USER_STATISTICS__USER_STATISTICS_GUILD_ID_FKEY = Internal.createForeignKey(UserStatistics.USER_STATISTICS, DSL.name("user_statistics_guild_id_fkey"), new TableField[] { UserStatistics.USER_STATISTICS.GUILD_ID }, Keys.GUILDS_PKEY, new TableField[] { Guilds.GUILDS.ID }, true); } diff --git a/src/main/jooq/de/kittybot/kittybot/jooq/Public.java b/src/main/jooq/de/kittybot/kittybot/jooq/Public.java index 1cc6a754..b47a94e8 100644 --- a/src/main/jooq/de/kittybot/kittybot/jooq/Public.java +++ b/src/main/jooq/de/kittybot/kittybot/jooq/Public.java @@ -19,7 +19,6 @@ import de.kittybot.kittybot.jooq.tables.SelfAssignableRoles; import de.kittybot.kittybot.jooq.tables.Sessions; import de.kittybot.kittybot.jooq.tables.SnipeDisabledChannels; -import de.kittybot.kittybot.jooq.tables.StreamUserEvents; import de.kittybot.kittybot.jooq.tables.StreamUsers; import de.kittybot.kittybot.jooq.tables.UserStatistics; import de.kittybot.kittybot.jooq.tables.Voters; @@ -121,11 +120,6 @@ public class Public extends SchemaImpl { */ public final SnipeDisabledChannels SNIPE_DISABLED_CHANNELS = SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS; - /** - * The table public.stream_user_events. - */ - public final StreamUserEvents STREAM_USER_EVENTS = StreamUserEvents.STREAM_USER_EVENTS; - /** * The table public.stream_users. */ @@ -171,7 +165,6 @@ public final List> getSequences() { Sequences.SELF_ASSIGNABLE_ROLES_ID_SEQ, Sequences.SESSIONS_ID_SEQ, Sequences.SNIPE_DISABLED_CHANNELS_ID_SEQ, - Sequences.STREAM_USER_EVENTS_ID_SEQ, Sequences.STREAM_USERS_ID_SEQ, Sequences.USER_STATISTICS_ID_SEQ, Sequences.VOTERS_ID_SEQ); @@ -195,7 +188,6 @@ public final List> getTables() { SelfAssignableRoles.SELF_ASSIGNABLE_ROLES, Sessions.SESSIONS, SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS, - StreamUserEvents.STREAM_USER_EVENTS, StreamUsers.STREAM_USERS, UserStatistics.USER_STATISTICS, Voters.VOTERS); diff --git a/src/main/jooq/de/kittybot/kittybot/jooq/Sequences.java b/src/main/jooq/de/kittybot/kittybot/jooq/Sequences.java index d5c3d666..98f3ecc8 100644 --- a/src/main/jooq/de/kittybot/kittybot/jooq/Sequences.java +++ b/src/main/jooq/de/kittybot/kittybot/jooq/Sequences.java @@ -85,11 +85,6 @@ public class Sequences { */ public static final Sequence SNIPE_DISABLED_CHANNELS_ID_SEQ = Internal.createSequence("snipe_disabled_channels_id_seq", Public.PUBLIC, SQLDataType.BIGINT.nullable(false), null, null, null, null, false, null); - /** - * The sequence public.stream_user_events_id_seq - */ - public static final Sequence STREAM_USER_EVENTS_ID_SEQ = Internal.createSequence("stream_user_events_id_seq", Public.PUBLIC, SQLDataType.BIGINT.nullable(false), null, null, null, null, false, null); - /** * The sequence public.stream_users_id_seq */ diff --git a/src/main/jooq/de/kittybot/kittybot/jooq/Tables.java b/src/main/jooq/de/kittybot/kittybot/jooq/Tables.java index c6339b0f..1d9e96ff 100644 --- a/src/main/jooq/de/kittybot/kittybot/jooq/Tables.java +++ b/src/main/jooq/de/kittybot/kittybot/jooq/Tables.java @@ -19,7 +19,6 @@ import de.kittybot.kittybot.jooq.tables.SelfAssignableRoles; import de.kittybot.kittybot.jooq.tables.Sessions; import de.kittybot.kittybot.jooq.tables.SnipeDisabledChannels; -import de.kittybot.kittybot.jooq.tables.StreamUserEvents; import de.kittybot.kittybot.jooq.tables.StreamUsers; import de.kittybot.kittybot.jooq.tables.UserStatistics; import de.kittybot.kittybot.jooq.tables.Voters; @@ -106,11 +105,6 @@ public class Tables { */ public static final SnipeDisabledChannels SNIPE_DISABLED_CHANNELS = SnipeDisabledChannels.SNIPE_DISABLED_CHANNELS; - /** - * The table public.stream_user_events. - */ - public static final StreamUserEvents STREAM_USER_EVENTS = StreamUserEvents.STREAM_USER_EVENTS; - /** * The table public.stream_users. */ diff --git a/src/main/jooq/de/kittybot/kittybot/jooq/tables/BotDisabledChannels.java b/src/main/jooq/de/kittybot/kittybot/jooq/tables/BotDisabledChannels.java index 00ea11dc..4faa8e33 100644 --- a/src/main/jooq/de/kittybot/kittybot/jooq/tables/BotDisabledChannels.java +++ b/src/main/jooq/de/kittybot/kittybot/jooq/tables/BotDisabledChannels.java @@ -113,7 +113,7 @@ public UniqueKey getPrimaryKey() { @Override public List> getKeys() { - return Arrays.>asList(Keys.BOT_DISABLED_CHANNELS_PKEY, Keys.BOT_DISABLED_CHANNELS_GUILD_ID_CHANNEL_ID_KEY, Keys.BOT_DISABLED_CHANNELS_CHANNEL_ID_KEY); + return Arrays.>asList(Keys.BOT_DISABLED_CHANNELS_PKEY, Keys.BOT_DISABLED_CHANNELS_GUILD_ID_CHANNEL_ID_KEY); } @Override diff --git a/src/main/jooq/de/kittybot/kittybot/jooq/tables/StreamUserEvents.java b/src/main/jooq/de/kittybot/kittybot/jooq/tables/StreamUserEvents.java deleted file mode 100644 index 6f7d2cb2..00000000 --- a/src/main/jooq/de/kittybot/kittybot/jooq/tables/StreamUserEvents.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * This file is generated by jOOQ. - */ -package de.kittybot.kittybot.jooq.tables; - - -import de.kittybot.kittybot.jooq.Keys; -import de.kittybot.kittybot.jooq.Public; -import de.kittybot.kittybot.jooq.tables.records.StreamUserEventsRecord; - -import java.util.Arrays; -import java.util.List; - -import org.jooq.Field; -import org.jooq.ForeignKey; -import org.jooq.Identity; -import org.jooq.Name; -import org.jooq.Record; -import org.jooq.Row3; -import org.jooq.Schema; -import org.jooq.Table; -import org.jooq.TableField; -import org.jooq.TableOptions; -import org.jooq.UniqueKey; -import org.jooq.impl.DSL; -import org.jooq.impl.SQLDataType; -import org.jooq.impl.TableImpl; - - -/** - * This class is generated by jOOQ. - */ -@SuppressWarnings({ "all", "unchecked", "rawtypes" }) -public class StreamUserEvents extends TableImpl { - - private static final long serialVersionUID = 1L; - - /** - * The reference instance of public.stream_user_events - */ - public static final StreamUserEvents STREAM_USER_EVENTS = new StreamUserEvents(); - - /** - * The class holding records for this type - */ - @Override - public Class getRecordType() { - return StreamUserEventsRecord.class; - } - - /** - * The column public.stream_user_events.id. - */ - public final TableField ID = createField(DSL.name("id"), SQLDataType.BIGINT.nullable(false).identity(true), this, ""); - - /** - * The column public.stream_user_events.stream_user_id. - */ - public final TableField STREAM_USER_ID = createField(DSL.name("stream_user_id"), SQLDataType.BIGINT.nullable(false), this, ""); - - /** - * The column public.stream_user_events.event. - */ - public final TableField EVENT = createField(DSL.name("event"), SQLDataType.INTEGER.nullable(false), this, ""); - - private StreamUserEvents(Name alias, Table aliased) { - this(alias, aliased, null); - } - - private StreamUserEvents(Name alias, Table aliased, Field[] parameters) { - super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table()); - } - - /** - * Create an aliased public.stream_user_events table reference - */ - public StreamUserEvents(String alias) { - this(DSL.name(alias), STREAM_USER_EVENTS); - } - - /** - * Create an aliased public.stream_user_events table reference - */ - public StreamUserEvents(Name alias) { - this(alias, STREAM_USER_EVENTS); - } - - /** - * Create a public.stream_user_events table reference - */ - public StreamUserEvents() { - this(DSL.name("stream_user_events"), null); - } - - public StreamUserEvents(Table child, ForeignKey key) { - super(child, key, STREAM_USER_EVENTS); - } - - @Override - public Schema getSchema() { - return Public.PUBLIC; - } - - @Override - public Identity getIdentity() { - return (Identity) super.getIdentity(); - } - - @Override - public UniqueKey getPrimaryKey() { - return Keys.STREAM_USER_EVENTS_PKEY; - } - - @Override - public List> getKeys() { - return Arrays.>asList(Keys.STREAM_USER_EVENTS_PKEY, Keys.STREAM_USER_EVENTS_STREAM_USER_ID_EVENT_KEY); - } - - @Override - public List> getReferences() { - return Arrays.>asList(Keys.STREAM_USER_EVENTS__STREAM_USER_EVENTS_STREAM_USER_ID_FKEY); - } - - public StreamUsers streamUsers() { - return new StreamUsers(this, Keys.STREAM_USER_EVENTS__STREAM_USER_EVENTS_STREAM_USER_ID_FKEY); - } - - @Override - public StreamUserEvents as(String alias) { - return new StreamUserEvents(DSL.name(alias), this); - } - - @Override - public StreamUserEvents as(Name alias) { - return new StreamUserEvents(alias, this); - } - - /** - * Rename this table - */ - @Override - public StreamUserEvents rename(String name) { - return new StreamUserEvents(DSL.name(name), null); - } - - /** - * Rename this table - */ - @Override - public StreamUserEvents rename(Name name) { - return new StreamUserEvents(name, null); - } - - // ------------------------------------------------------------------------- - // Row3 type methods - // ------------------------------------------------------------------------- - - @Override - public Row3 fieldsRow() { - return (Row3) super.fieldsRow(); - } -} diff --git a/src/main/jooq/de/kittybot/kittybot/jooq/tables/StreamUsers.java b/src/main/jooq/de/kittybot/kittybot/jooq/tables/StreamUsers.java index 3752f301..1d363417 100644 --- a/src/main/jooq/de/kittybot/kittybot/jooq/tables/StreamUsers.java +++ b/src/main/jooq/de/kittybot/kittybot/jooq/tables/StreamUsers.java @@ -69,14 +69,14 @@ public Class getRecordType() { public final TableField USER_NAME = createField(DSL.name("user_name"), SQLDataType.VARCHAR(32).nullable(false), this, ""); /** - * The column public.stream_users.stream_type. + * The column public.stream_users.subscription_id. */ - public final TableField STREAM_TYPE = createField(DSL.name("stream_type"), SQLDataType.INTEGER.nullable(false), this, ""); + public final TableField SUBSCRIPTION_ID = createField(DSL.name("subscription_id"), SQLDataType.VARCHAR(64).nullable(false), this, ""); /** - * The column public.stream_users.is_live. + * The column public.stream_users.stream_type. */ - public final TableField IS_LIVE = createField(DSL.name("is_live"), SQLDataType.BOOLEAN.nullable(false).defaultValue(DSL.field("false", SQLDataType.BOOLEAN)), this, ""); + public final TableField STREAM_TYPE = createField(DSL.name("stream_type"), SQLDataType.INTEGER.nullable(false), this, ""); private StreamUsers(Name alias, Table aliased) { this(alias, aliased, null); @@ -128,7 +128,7 @@ public UniqueKey getPrimaryKey() { @Override public List> getKeys() { - return Arrays.>asList(Keys.STREAM_USERS_PKEY, Keys.STREAM_USERS_GUILD_ID_USER_ID_KEY); + return Arrays.>asList(Keys.STREAM_USERS_PKEY, Keys.STREAM_USERS_GUILD_ID_USER_ID_STREAM_TYPE_KEY); } @Override @@ -171,7 +171,7 @@ public StreamUsers rename(Name name) { // ------------------------------------------------------------------------- @Override - public Row6 fieldsRow() { + public Row6 fieldsRow() { return (Row6) super.fieldsRow(); } } diff --git a/src/main/jooq/de/kittybot/kittybot/jooq/tables/records/StreamUserEventsRecord.java b/src/main/jooq/de/kittybot/kittybot/jooq/tables/records/StreamUserEventsRecord.java deleted file mode 100644 index db34ff7f..00000000 --- a/src/main/jooq/de/kittybot/kittybot/jooq/tables/records/StreamUserEventsRecord.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * This file is generated by jOOQ. - */ -package de.kittybot.kittybot.jooq.tables.records; - - -import de.kittybot.kittybot.jooq.tables.StreamUserEvents; - -import org.jooq.Field; -import org.jooq.Record1; -import org.jooq.Record3; -import org.jooq.Row3; -import org.jooq.impl.UpdatableRecordImpl; - - -/** - * This class is generated by jOOQ. - */ -@SuppressWarnings({ "all", "unchecked", "rawtypes" }) -public class StreamUserEventsRecord extends UpdatableRecordImpl implements Record3 { - - private static final long serialVersionUID = 1L; - - /** - * Setter for public.stream_user_events.id. - */ - public StreamUserEventsRecord setId(Long value) { - set(0, value); - return this; - } - - /** - * Getter for public.stream_user_events.id. - */ - public Long getId() { - return (Long) get(0); - } - - /** - * Setter for public.stream_user_events.stream_user_id. - */ - public StreamUserEventsRecord setStreamUserId(Long value) { - set(1, value); - return this; - } - - /** - * Getter for public.stream_user_events.stream_user_id. - */ - public Long getStreamUserId() { - return (Long) get(1); - } - - /** - * Setter for public.stream_user_events.event. - */ - public StreamUserEventsRecord setEvent(Integer value) { - set(2, value); - return this; - } - - /** - * Getter for public.stream_user_events.event. - */ - public Integer getEvent() { - return (Integer) get(2); - } - - // ------------------------------------------------------------------------- - // Primary key information - // ------------------------------------------------------------------------- - - @Override - public Record1 key() { - return (Record1) super.key(); - } - - // ------------------------------------------------------------------------- - // Record3 type implementation - // ------------------------------------------------------------------------- - - @Override - public Row3 fieldsRow() { - return (Row3) super.fieldsRow(); - } - - @Override - public Row3 valuesRow() { - return (Row3) super.valuesRow(); - } - - @Override - public Field field1() { - return StreamUserEvents.STREAM_USER_EVENTS.ID; - } - - @Override - public Field field2() { - return StreamUserEvents.STREAM_USER_EVENTS.STREAM_USER_ID; - } - - @Override - public Field field3() { - return StreamUserEvents.STREAM_USER_EVENTS.EVENT; - } - - @Override - public Long component1() { - return getId(); - } - - @Override - public Long component2() { - return getStreamUserId(); - } - - @Override - public Integer component3() { - return getEvent(); - } - - @Override - public Long value1() { - return getId(); - } - - @Override - public Long value2() { - return getStreamUserId(); - } - - @Override - public Integer value3() { - return getEvent(); - } - - @Override - public StreamUserEventsRecord value1(Long value) { - setId(value); - return this; - } - - @Override - public StreamUserEventsRecord value2(Long value) { - setStreamUserId(value); - return this; - } - - @Override - public StreamUserEventsRecord value3(Integer value) { - setEvent(value); - return this; - } - - @Override - public StreamUserEventsRecord values(Long value1, Long value2, Integer value3) { - value1(value1); - value2(value2); - value3(value3); - return this; - } - - // ------------------------------------------------------------------------- - // Constructors - // ------------------------------------------------------------------------- - - /** - * Create a detached StreamUserEventsRecord - */ - public StreamUserEventsRecord() { - super(StreamUserEvents.STREAM_USER_EVENTS); - } - - /** - * Create a detached, initialised StreamUserEventsRecord - */ - public StreamUserEventsRecord(Long id, Long streamUserId, Integer event) { - super(StreamUserEvents.STREAM_USER_EVENTS); - - setId(id); - setStreamUserId(streamUserId); - setEvent(event); - } -} diff --git a/src/main/jooq/de/kittybot/kittybot/jooq/tables/records/StreamUsersRecord.java b/src/main/jooq/de/kittybot/kittybot/jooq/tables/records/StreamUsersRecord.java index b7f52014..db580dd6 100644 --- a/src/main/jooq/de/kittybot/kittybot/jooq/tables/records/StreamUsersRecord.java +++ b/src/main/jooq/de/kittybot/kittybot/jooq/tables/records/StreamUsersRecord.java @@ -17,7 +17,7 @@ * This class is generated by jOOQ. */ @SuppressWarnings({ "all", "unchecked", "rawtypes" }) -public class StreamUsersRecord extends UpdatableRecordImpl implements Record6 { +public class StreamUsersRecord extends UpdatableRecordImpl implements Record6 { private static final long serialVersionUID = 1L; @@ -82,33 +82,33 @@ public String getUserName() { } /** - * Setter for public.stream_users.stream_type. + * Setter for public.stream_users.subscription_id. */ - public StreamUsersRecord setStreamType(Integer value) { + public StreamUsersRecord setSubscriptionId(String value) { set(4, value); return this; } /** - * Getter for public.stream_users.stream_type. + * Getter for public.stream_users.subscription_id. */ - public Integer getStreamType() { - return (Integer) get(4); + public String getSubscriptionId() { + return (String) get(4); } /** - * Setter for public.stream_users.is_live. + * Setter for public.stream_users.stream_type. */ - public StreamUsersRecord setIsLive(Boolean value) { + public StreamUsersRecord setStreamType(Integer value) { set(5, value); return this; } /** - * Getter for public.stream_users.is_live. + * Getter for public.stream_users.stream_type. */ - public Boolean getIsLive() { - return (Boolean) get(5); + public Integer getStreamType() { + return (Integer) get(5); } // ------------------------------------------------------------------------- @@ -125,12 +125,12 @@ public Record1 key() { // ------------------------------------------------------------------------- @Override - public Row6 fieldsRow() { + public Row6 fieldsRow() { return (Row6) super.fieldsRow(); } @Override - public Row6 valuesRow() { + public Row6 valuesRow() { return (Row6) super.valuesRow(); } @@ -155,13 +155,13 @@ public Field field4() { } @Override - public Field field5() { - return StreamUsers.STREAM_USERS.STREAM_TYPE; + public Field field5() { + return StreamUsers.STREAM_USERS.SUBSCRIPTION_ID; } @Override - public Field field6() { - return StreamUsers.STREAM_USERS.IS_LIVE; + public Field field6() { + return StreamUsers.STREAM_USERS.STREAM_TYPE; } @Override @@ -185,13 +185,13 @@ public String component4() { } @Override - public Integer component5() { - return getStreamType(); + public String component5() { + return getSubscriptionId(); } @Override - public Boolean component6() { - return getIsLive(); + public Integer component6() { + return getStreamType(); } @Override @@ -215,13 +215,13 @@ public String value4() { } @Override - public Integer value5() { - return getStreamType(); + public String value5() { + return getSubscriptionId(); } @Override - public Boolean value6() { - return getIsLive(); + public Integer value6() { + return getStreamType(); } @Override @@ -249,19 +249,19 @@ public StreamUsersRecord value4(String value) { } @Override - public StreamUsersRecord value5(Integer value) { - setStreamType(value); + public StreamUsersRecord value5(String value) { + setSubscriptionId(value); return this; } @Override - public StreamUsersRecord value6(Boolean value) { - setIsLive(value); + public StreamUsersRecord value6(Integer value) { + setStreamType(value); return this; } @Override - public StreamUsersRecord values(Long value1, Long value2, Long value3, String value4, Integer value5, Boolean value6) { + public StreamUsersRecord values(Long value1, Long value2, Long value3, String value4, String value5, Integer value6) { value1(value1); value2(value2); value3(value3); @@ -285,14 +285,14 @@ public StreamUsersRecord() { /** * Create a detached, initialised StreamUsersRecord */ - public StreamUsersRecord(Long id, Long guildId, Long userId, String userName, Integer streamType, Boolean isLive) { + public StreamUsersRecord(Long id, Long guildId, Long userId, String userName, String subscriptionId, Integer streamType) { super(StreamUsers.STREAM_USERS); setId(id); setGuildId(guildId); setUserId(userId); setUserName(userName); + setSubscriptionId(subscriptionId); setStreamType(streamType); - setIsLive(isLive); } } diff --git a/src/main/resources/sql_tables/stream_users.sql b/src/main/resources/sql_tables/stream_users.sql index a5f6bdb2..ef548f95 100644 --- a/src/main/resources/sql_tables/stream_users.sql +++ b/src/main/resources/sql_tables/stream_users.sql @@ -1,9 +1,8 @@ CREATE TABLE IF NOT EXISTS stream_users( - id BIGSERIAL PRIMARY KEY NOT NULL, - guild_id BIGINT NOT NULL REFERENCES guilds(id) ON DELETE CASCADE, - user_id BIGINT NOT NULL, - user_name VARCHAR(32) NOT NULL, - stream_type INT NOT NULL, - is_live BOOLEAN NOT NULL DEFAULT(false), - UNIQUE(guild_id, user_id) + id BIGSERIAL PRIMARY KEY NOT NULL, + guild_id BIGINT NOT NULL REFERENCES guilds(id) ON DELETE CASCADE, + user_id BIGINT NOT NULL, + user_name VARCHAR(32) NOT NULL, + stream_type INT NOT NULL, + UNIQUE(guild_id, user_id, stream_type) );