From 1e4830d4ecb4a0de54bc0c245cc3449e4de93abe Mon Sep 17 00:00:00 2001 From: Thomas Couchoud Date: Tue, 27 Dec 2022 20:32:39 +0100 Subject: [PATCH 1/7] Event filtering --- .../factory/LogEventListenerFactory.java | 2 +- .../miner/log/DiscordEventListener.java | 6 ++ .../log/DiscordEventListenerEmbedTest.java | 2 +- .../log/DiscordEventListenerMessageTest.java | 2 +- .../miner/log/DiscordEventListenerTest.java | 62 +++++++++++++++++++ 5 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerTest.java diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactory.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactory.java index d6ea0765..e86fa402 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactory.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactory.java @@ -17,6 +17,6 @@ public static IEventHandler createLogger(){ @NotNull public static IEventHandler createDiscordLogger(@NotNull DiscordApi discordApi, boolean useEmbeds){ - return new DiscordEventListener(discordApi, useEmbeds); + return new DiscordEventListener(discordApi, useEmbeds, e -> true); } } \ No newline at end of file diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListener.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListener.java index 011e37e4..65a80373 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListener.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListener.java @@ -7,16 +7,22 @@ import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.jetbrains.annotations.NotNull; +import java.util.function.Predicate; @Log4j2 @RequiredArgsConstructor public class DiscordEventListener extends EventHandlerAdapter{ private final DiscordApi discordApi; private final boolean useEmbeds; + private final Predicate eventFilter; @Override public void onILoggableEvent(@NotNull ILoggableEvent event){ try(var context = LogContext.with(event.getMiner())){ + if(!eventFilter.test(event)){ + return; + } + if(event instanceof IStreamerEvent e){ e.getStreamerUsername().ifPresent(context::withStreamer); } diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerEmbedTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerEmbedTest.java index 944d9235..26c5b1db 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerEmbedTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerEmbedTest.java @@ -90,7 +90,7 @@ class DiscordEventListenerEmbedTest{ @BeforeEach void setUp() throws MalformedURLException{ - tested = new DiscordEventListener(discordApi, true); + tested = new DiscordEventListener(discordApi, true, e -> true); var streamerProfileUrl = new URL("https://streamer-image"); var channelUrl = new URL("https://streamer"); diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerMessageTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerMessageTest.java index 49b2b8d9..48bdc545 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerMessageTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerMessageTest.java @@ -78,7 +78,7 @@ class DiscordEventListenerMessageTest{ @BeforeEach void setUp(){ - tested = new DiscordEventListener(discordApi, false); + tested = new DiscordEventListener(discordApi, false, e -> true); lenient().when(miner.getStreamerById(STREAMER_ID)).thenReturn(Optional.of(streamer)); lenient().when(miner.getUsername()).thenReturn(USERNAME); diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerTest.java new file mode 100644 index 00000000..1ecd5901 --- /dev/null +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerTest.java @@ -0,0 +1,62 @@ +package fr.rakambda.channelpointsminer.miner.log; + +import fr.rakambda.channelpointsminer.miner.api.discord.DiscordApi; +import fr.rakambda.channelpointsminer.miner.api.ws.data.request.topic.Topic; +import fr.rakambda.channelpointsminer.miner.event.IEvent; +import fr.rakambda.channelpointsminer.miner.miner.IMiner; +import fr.rakambda.channelpointsminer.miner.streamer.Streamer; +import fr.rakambda.channelpointsminer.miner.tests.ParallelizableTest; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Optional; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +@ParallelizableTest +@ExtendWith(MockitoExtension.class) +class DiscordEventListenerTest{ + private static final String STREAMER_ID = "streamer-id"; + private static final String STREAMER_USERNAME = "streamer-name"; + private static final String USERNAME = "username"; + + @Mock + private IMiner miner; + @Mock + private DiscordApi discordApi; + @Mock + private Streamer streamer; + @Mock + private Topic topic; + + @BeforeEach + void setUp() throws MalformedURLException{ + var streamerProfileUrl = new URL("https://streamer-image"); + var channelUrl = new URL("https://streamer"); + + lenient().when(miner.getStreamerById(STREAMER_ID)).thenReturn(Optional.of(streamer)); + lenient().when(miner.getUsername()).thenReturn(USERNAME); + lenient().when(streamer.getUsername()).thenReturn(STREAMER_USERNAME); + lenient().when(streamer.getProfileImage()).thenReturn(Optional.of(streamerProfileUrl)); + lenient().when(streamer.getChannelUrl()).thenReturn(channelUrl); + + lenient().when(topic.getTarget()).thenReturn(STREAMER_ID); + } + + @Test + void eventIsFiltered(){ + var event = mock(IEvent.class); + + var tested = new DiscordEventListener(discordApi, true, e -> false); + tested.onEvent(event); + + verify(discordApi, never()).sendMessage(any()); + } +} \ No newline at end of file From a9b57f4a01fe0a565c6adb11506cac8afb5213cd Mon Sep 17 00:00:00 2001 From: Thomas Couchoud Date: Tue, 27 Dec 2022 23:15:26 +0100 Subject: [PATCH 2/7] Start adding customizable messages (WIP: embeds tests to fix + take into account config) --- gradle/libs.versions.toml | 2 + miner/build.gradle.kts | 1 + .../miner/api/discord/data/Author.java | 9 +- .../miner/config/DiscordConfiguration.java | 6 + .../config/DiscordEventConfiguration.java | 24 ++++ .../miner/event/AbstractLoggableEvent.java | 73 +++-------- .../event/AbstractLoggableStreamerEvent.java | 29 ++--- .../miner/event/EventVariableKey.java | 25 ++++ .../miner/event/ILoggableEvent.java | 11 +- .../miner/event/impl/ClaimAvailableEvent.java | 16 +-- .../miner/event/impl/ClaimMomentEvent.java | 14 +- .../miner/event/impl/ClaimedMomentEvent.java | 14 +- .../miner/event/impl/DropClaimEvent.java | 34 +++-- .../miner/event/impl/DropClaimedEvent.java | 34 +++-- .../miner/event/impl/EventCreatedEvent.java | 37 +++--- .../miner/event/impl/MinerStartedEvent.java | 47 ++++--- .../miner/event/impl/PointsEarnedEvent.java | 50 ++++--- .../miner/event/impl/PointsSpentEvent.java | 37 +++--- .../miner/event/impl/PredictionMadeEvent.java | 59 +++++---- .../event/impl/PredictionResultEvent.java | 72 ++++++----- .../miner/event/impl/StreamDownEvent.java | 13 +- .../miner/event/impl/StreamUpEvent.java | 13 +- .../miner/event/impl/StreamerAddedEvent.java | 13 +- .../event/impl/StreamerRemovedEvent.java | 13 +- .../event/impl/StreamerUnknownEvent.java | 24 ++-- .../factory/LogEventListenerFactory.java | 8 +- .../miner/factory/MinerFactory.java | 2 +- .../miner/log/DiscordEventListener.java | 38 ------ .../miner/log/LoggerEventListener.java | 2 +- .../log/discord/DiscordEventListener.java | 49 +++++++ .../log/discord/DiscordMessageBuilder.java | 74 +++++++++++ .../factory/LogEventListenerFactoryTest.java | 7 +- .../miner/factory/MinerFactoryTest.java | 2 +- .../miner/log/DiscordEventListenerTest.java | 62 --------- .../log/discord/DiscordEventListenerTest.java | 111 ++++++++++++++++ .../DiscordMessageBuilderEmbedTest.java} | 122 ++++++++---------- .../DiscordMessageBuilderMessageTest.java} | 120 ++++++++--------- 37 files changed, 735 insertions(+), 532 deletions(-) create mode 100644 miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java create mode 100644 miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/EventVariableKey.java delete mode 100644 miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListener.java create mode 100644 miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListener.java create mode 100644 miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java delete mode 100644 miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerTest.java create mode 100644 miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListenerTest.java rename miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/{DiscordEventListenerEmbedTest.java => discord/DiscordMessageBuilderEmbedTest.java} (78%) rename miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/{DiscordEventListenerMessageTest.java => discord/DiscordMessageBuilderMessageTest.java} (72%) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a63a8a0e..3e98eda1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,6 +8,7 @@ jackson-version = "2.14.1" jsonschema-generator-version = "4.28.0" httpclient-version = "4.5.14" lang3-version = "3.12.0" +commons-text-version = "1.10.0" jetbrains-annotations-version = "23.1.0" websocket-version = "1.5.3" junit-version = "5.9.1" @@ -48,6 +49,7 @@ jsonschema-generator = { group = "com.github.victools", name = "jsonschema-gener jsonschema-module-jackson = { group = "com.github.victools", name = "jsonschema-module-jackson", version.ref = "jsonschema-generator-version" } httpclient = { group = "org.apache.httpcomponents", name = "httpclient", version.ref = "httpclient-version" } lang3 = { group = "org.apache.commons", name = "commons-lang3", version.ref = "lang3-version" } +commonsText = { group = "org.apache.commons", name = "commons-text", version.ref = "commons-text-version" } jetbrainsAnnotations = { group = "org.jetbrains", name = "annotations", version.ref = "jetbrains-annotations-version" } websocket = { group = "org.java-websocket", name = "Java-WebSocket", version.ref = "websocket-version" } kittehIrc = { group = "org.kitteh.irc", name = "client-lib", version.ref = "kitteh-irc-version" } diff --git a/miner/build.gradle.kts b/miner/build.gradle.kts index c37dde56..f318923c 100644 --- a/miner/build.gradle.kts +++ b/miner/build.gradle.kts @@ -17,6 +17,7 @@ dependencies { implementation(libs.bundles.jackson) implementation(libs.httpclient) implementation(libs.lang3) + implementation(libs.commonsText) implementation(libs.websocket) implementation(libs.kittehIrc) implementation(libs.selenide) diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/api/discord/data/Author.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/api/discord/data/Author.java index 828bfa16..ee024807 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/api/discord/data/Author.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/api/discord/data/Author.java @@ -3,8 +3,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import fr.rakambda.channelpointsminer.miner.util.json.URLSerializer; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.EqualsAndHashCode; @@ -13,7 +11,6 @@ import lombok.ToString; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.net.URL; @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) @@ -28,11 +25,9 @@ public class Author{ @NotNull private String name; @JsonProperty("url") - @JsonSerialize(using = URLSerializer.class) @Nullable - private URL url; + private String url; @JsonProperty("icon_url") - @JsonSerialize(using = URLSerializer.class) @Nullable - private URL iconUrl; + private String iconUrl; } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordConfiguration.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordConfiguration.java index 98a2aeb1..559b2f64 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordConfiguration.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordConfiguration.java @@ -12,6 +12,8 @@ import lombok.ToString; import org.jetbrains.annotations.Nullable; import java.net.URL; +import java.util.HashMap; +import java.util.Map; @Getter @NoArgsConstructor @@ -29,4 +31,8 @@ public class DiscordConfiguration{ @JsonPropertyDescription("Use embeds in the messages or not. Default: false") @Builder.Default private boolean embeds = false; + @JsonProperty("events") + @JsonPropertyDescription("Customize events that are sent. Default: all") + @Builder.Default + private Map events = new HashMap<>(); } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java new file mode 100644 index 00000000..4afcbef8 --- /dev/null +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java @@ -0,0 +1,24 @@ +package fr.rakambda.channelpointsminer.miner.config; + +import com.fasterxml.jackson.annotation.JsonClassDescription; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.jetbrains.annotations.Nullable; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@ToString +@JsonClassDescription("Customization of the event sent.") +public class DiscordEventConfiguration{ + @JsonProperty("format") + @JsonPropertyDescription(value = "Format of the message sent.") + @Nullable + private String format; +} diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableEvent.java index 377bf135..21518120 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableEvent.java @@ -1,32 +1,25 @@ package fr.rakambda.channelpointsminer.miner.event; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Author; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Embed; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Footer; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Webhook; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.ToString; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.awt.Color; import java.text.NumberFormat; import java.time.Instant; -import java.util.Collection; -import java.util.List; import java.util.Locale; +import java.util.Map; @RequiredArgsConstructor @EqualsAndHashCode @ToString public abstract class AbstractLoggableEvent implements IEvent, ILoggableEvent{ - protected static final int COLOR_INFO = Color.CYAN.getRGB(); - protected static final int COLOR_PREDICTION = Color.PINK.getRGB(); - protected static final int COLOR_POINTS_WON = Color.GREEN.getRGB(); - protected static final int COLOR_POINTS_LOST = Color.RED.getRGB(); + protected static final String COLOR_INFO = Integer.toString(Color.CYAN.getRGB()); + protected static final String COLOR_PREDICTION = Integer.toString(Color.PINK.getRGB()); + protected static final String COLOR_POINTS_WON = Integer.toString(Color.GREEN.getRGB()); + protected static final String COLOR_POINTS_LOST = Integer.toString(Color.RED.getRGB()); @EqualsAndHashCode.Exclude private final ThreadLocal numberFormatLocal = ThreadLocal.withInitial(() -> { @@ -48,55 +41,29 @@ public String millify(int value, boolean includeSign){ return sign + numberFormatLocal.get().format(value); } - @NotNull @Override - public Webhook getAsWebhookEmbed(){ - var embed = Embed.builder() - .author(getEmbedAuthor()) - .footer(Footer.builder().text(miner.getUsername()).build()) - .color(getEmbedColor()) - .description(getEmbedDescription()) - .fields(getEmbedFields()) - .build(); - return Webhook.builder() - .embeds(List.of(embed)) - .build(); + public String lookup(String key){ + if(EventVariableKey.USERNAME.equals(key)){ + return getMiner().getUsername(); + } + if(EventVariableKey.EMOJI.equals(key)){ + return getEmoji(); + } + if(EventVariableKey.COLOR.equals(key)){ + return getColor(); + } + return null; } - @NotNull @Override - public Webhook getAsWebhookMessage(){ - return Webhook.builder().content(getWebhookContent()).build(); - } - @NotNull - protected String getWebhookContent(){ - return "[%s] %s : %s".formatted( - miner.getUsername(), - getEmoji(), - getWebhookMessage()); + public Map getEmbedFields(){ + return Map.of(); } @NotNull - protected abstract String getEmoji(); + protected abstract String getColor(); @NotNull - protected String getWebhookMessage(){ - return getAsLog(); - } - - @Nullable - protected Author getEmbedAuthor(){ - return null; - } - - protected abstract int getEmbedColor(); - - @NotNull - protected abstract String getEmbedDescription(); - - @NotNull - protected Collection getEmbedFields(){ - return List.of(); - } + protected abstract String getEmoji(); } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableStreamerEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableStreamerEvent.java index 1f500466..579fed1d 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableStreamerEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableStreamerEvent.java @@ -1,6 +1,5 @@ package fr.rakambda.channelpointsminer.miner.event; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Author; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import fr.rakambda.channelpointsminer.miner.streamer.Streamer; import lombok.EqualsAndHashCode; @@ -8,6 +7,7 @@ import lombok.ToString; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.net.URL; import java.time.Instant; import java.util.Optional; @@ -33,25 +33,14 @@ public AbstractLoggableStreamerEvent(@NotNull IMiner miner, @NotNull String stre } @Override - @NotNull - protected String getWebhookContent(){ - return "[%s] %s %s : %s".formatted( - getMiner().getUsername(), - getEmoji(), - getStreamerUsername().orElse(UNKNOWN_STREAMER), - getWebhookMessage()); - } - - @Nullable - @Override - protected Author getEmbedAuthor(){ - return getStreamerUsername() - .map(username -> Author.builder().name(username) - .iconUrl(getStreamer().flatMap(Streamer::getProfileImage).orElse(null)) - .url(getStreamer().map(Streamer::getChannelUrl).orElse(null)) - .build() - ) - .orElse(null); + public String lookup(String key){ + if(EventVariableKey.STREAMER.equals(key)){ + return getStreamerUsername().orElse(UNKNOWN_STREAMER); + } + if(EventVariableKey.STREAMER_PROFILE_PICTURE_URL.equals(key)){ + return getStreamer().flatMap(Streamer::getProfileImage).map(URL::toString).orElse(null); + } + return super.lookup(key); } @Override diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/EventVariableKey.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/EventVariableKey.java new file mode 100644 index 00000000..666daf4d --- /dev/null +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/EventVariableKey.java @@ -0,0 +1,25 @@ +package fr.rakambda.channelpointsminer.miner.event; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class EventVariableKey{ + public static final String BALANCE = "balance"; + public static final String BRANCH = "branch"; + public static final String COLOR = "color"; + public static final String COMMIT = "commit"; + public static final String DROP_NAME = "drop_name"; + public static final String EMOJI = "emoji"; + public static final String POINTS = "points"; + public static final String PREDICTION_NAME = "prediction_name"; + public static final String PREDICTION_OUTCOME = "prediction_outcome"; + public static final String PREDICTION_POINTS = "prediction_points"; + public static final String PREDICTION_TYPE = "prediction_type"; + public static final String REASON = "reason"; + public static final String USERNAME = "username"; + public static final String STREAMER = "streamer"; + public static final String STREAMER_URL = "streamer_url"; + public static final String STREAMER_PROFILE_PICTURE_URL = "streamer_profile_picture_url"; + public static final String VERSION = "version"; +} diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/ILoggableEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/ILoggableEvent.java index 87857555..6d615996 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/ILoggableEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/ILoggableEvent.java @@ -1,15 +1,16 @@ package fr.rakambda.channelpointsminer.miner.event; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Webhook; +import org.apache.commons.text.lookup.StringLookup; import org.jetbrains.annotations.NotNull; +import java.util.Map; -public interface ILoggableEvent extends IEvent{ +public interface ILoggableEvent extends IEvent, StringLookup{ @NotNull - String getAsLog(); + String getConsoleLogFormat(); @NotNull - Webhook getAsWebhookEmbed(); + String getDefaultFormat(); @NotNull - Webhook getAsWebhookMessage(); + Map getEmbedFields(); } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimAvailableEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimAvailableEvent.java index a942afff..c0f39f88 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimAvailableEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimAvailableEvent.java @@ -1,8 +1,8 @@ package fr.rakambda.channelpointsminer.miner.event.impl; +import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableStreamerEvent; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import fr.rakambda.channelpointsminer.miner.streamer.Streamer; -import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableStreamerEvent; import lombok.EqualsAndHashCode; import lombok.ToString; import org.jetbrains.annotations.NotNull; @@ -18,25 +18,25 @@ public ClaimAvailableEvent(@NotNull IMiner miner, @NotNull String streamerId, @N @Override @NotNull - public String getAsLog(){ + public String getConsoleLogFormat(){ return "Claim available"; } @Override @NotNull - protected String getEmoji(){ - return "đŸŽĢ"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Claim available"; } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_INFO; } @Override - @NotNull - protected String getEmbedDescription(){ - return "Claim available"; + protected String getEmoji(){ + return "đŸŽĢ"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimMomentEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimMomentEvent.java index a475d369..b7742dc3 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimMomentEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimMomentEvent.java @@ -18,25 +18,25 @@ public ClaimMomentEvent(@NotNull IMiner miner, @NotNull String streamerId, @Null @Override @NotNull - public String getAsLog(){ + public String getConsoleLogFormat(){ return "Moment available"; } @Override @NotNull - protected String getEmoji(){ - return "🎖ī¸"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Moment available"; } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_INFO; } @Override - @NotNull - protected String getEmbedDescription(){ - return "Moment available"; + protected String getEmoji(){ + return "🎖ī¸"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimedMomentEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimedMomentEvent.java index e4daf16f..4bfe88d7 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimedMomentEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/ClaimedMomentEvent.java @@ -18,25 +18,25 @@ public ClaimedMomentEvent(@NotNull IMiner miner, @NotNull String streamerId, @Nu @Override @NotNull - public String getAsLog(){ + public String getConsoleLogFormat(){ return "Moment claimed"; } @Override @NotNull - protected String getEmoji(){ - return "🎖ī¸"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Moment claimed"; } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_INFO; } @Override - @NotNull - protected String getEmbedDescription(){ - return "Moment claimed"; + protected String getEmoji(){ + return "🎖ī¸"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/DropClaimEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/DropClaimEvent.java index 739650ba..e8970c52 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/DropClaimEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/DropClaimEvent.java @@ -1,15 +1,14 @@ package fr.rakambda.channelpointsminer.miner.event.impl; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; import fr.rakambda.channelpointsminer.miner.api.gql.gql.data.types.TimeBasedDrop; import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableEvent; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import lombok.EqualsAndHashCode; import lombok.ToString; import org.jetbrains.annotations.NotNull; import java.time.Instant; -import java.util.Collection; -import java.util.List; +import java.util.Map; @EqualsAndHashCode(callSuper = true) @ToString @@ -23,32 +22,39 @@ public DropClaimEvent(@NotNull IMiner miner, @NotNull TimeBasedDrop drop, @NotNu @Override @NotNull - public String getAsLog(){ - return "Drop available [%s]".formatted(drop.getName()); + public String getConsoleLogFormat(){ + return "Drop available [{drop_name}]"; } @Override @NotNull - protected String getEmoji(){ - return "🎁"; + public String getDefaultFormat(){ + return "[{username}] {emoji} : Drop available [{drop_name}]"; } @Override - protected int getEmbedColor(){ - return COLOR_INFO; + public String lookup(String key){ + if(EventVariableKey.DROP_NAME.equals(key)){ + return drop.getName(); + } + return super.lookup(key); } @Override + @NotNull + public Map getEmbedFields(){ + return Map.of("Name", EventVariableKey.DROP_NAME); + } + @Override @NotNull - protected String getEmbedDescription(){ - return "Drop available"; + protected String getColor(){ + return COLOR_INFO; } @Override @NotNull - protected Collection getEmbedFields(){ - return List.of( - Field.builder().name("Name").value(drop.getName()).build()); + protected String getEmoji(){ + return "🎁"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/DropClaimedEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/DropClaimedEvent.java index c2bcc451..d6f0cc6d 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/DropClaimedEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/DropClaimedEvent.java @@ -1,15 +1,14 @@ package fr.rakambda.channelpointsminer.miner.event.impl; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; import fr.rakambda.channelpointsminer.miner.api.gql.gql.data.types.TimeBasedDrop; import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableEvent; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import lombok.EqualsAndHashCode; import lombok.ToString; import org.jetbrains.annotations.NotNull; import java.time.Instant; -import java.util.Collection; -import java.util.List; +import java.util.Map; @EqualsAndHashCode(callSuper = true) @ToString @@ -23,32 +22,39 @@ public DropClaimedEvent(@NotNull IMiner miner, @NotNull TimeBasedDrop drop, @Not @Override @NotNull - public String getAsLog(){ - return "Drop claimed [%s]".formatted(drop.getName()); + public String getConsoleLogFormat(){ + return "Drop claimed [{drop_name}]"; } @Override @NotNull - protected String getEmoji(){ - return "🎁"; + public String getDefaultFormat(){ + return "[{username}] {emoji} : Drop claimed [{drop_name}]"; } @Override - protected int getEmbedColor(){ - return COLOR_INFO; + public String lookup(String key){ + if(EventVariableKey.DROP_NAME.equals(key)){ + return drop.getName(); + } + return super.lookup(key); } @Override + @NotNull + public Map getEmbedFields(){ + return Map.of("Name", EventVariableKey.DROP_NAME); + } + @Override @NotNull - protected String getEmbedDescription(){ - return "Drop claimed"; + protected String getColor(){ + return COLOR_INFO; } @Override @NotNull - protected Collection getEmbedFields(){ - return List.of( - Field.builder().name("Name").value(drop.getName()).build()); + protected String getEmoji(){ + return "🎁"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/EventCreatedEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/EventCreatedEvent.java index c68def44..c9d6cf2b 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/EventCreatedEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/EventCreatedEvent.java @@ -1,15 +1,14 @@ package fr.rakambda.channelpointsminer.miner.event.impl; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.subtype.Event; import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableStreamerEvent; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import fr.rakambda.channelpointsminer.miner.streamer.Streamer; import lombok.EqualsAndHashCode; import lombok.ToString; import org.jetbrains.annotations.NotNull; -import java.util.Collection; -import java.util.List; +import java.util.Map; @EqualsAndHashCode(callSuper = true) @ToString @@ -23,33 +22,39 @@ public EventCreatedEvent(@NotNull IMiner miner, @NotNull Streamer streamer, @Not @Override @NotNull - public String getAsLog(){ - return "Prediction created [%s]".formatted(event.getTitle()); + public String getConsoleLogFormat(){ + return "Prediction created [{prediction_name}]"; } @Override @NotNull - protected String getEmoji(){ - return "📑"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Prediction created [{prediction_name}]"; } @Override - protected int getEmbedColor(){ - return COLOR_PREDICTION; + public String lookup(String key){ + if(EventVariableKey.PREDICTION_NAME.equals(key)){ + return event.getTitle(); + } + return super.lookup(key); + } + + @Override + @NotNull + public Map getEmbedFields(){ + return Map.of("Title", EventVariableKey.PREDICTION_NAME); } @Override @NotNull - protected String getEmbedDescription(){ - return "Prediction created"; + protected String getColor(){ + return COLOR_PREDICTION; } @Override @NotNull - protected Collection getEmbedFields(){ - return List.of(Field.builder() - .name("Title") - .value(event.getTitle()) - .build()); + protected String getEmoji(){ + return "📑"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/MinerStartedEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/MinerStartedEvent.java index e265bcb0..532b230c 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/MinerStartedEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/MinerStartedEvent.java @@ -1,14 +1,13 @@ package fr.rakambda.channelpointsminer.miner.event.impl; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableEvent; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import lombok.EqualsAndHashCode; import lombok.ToString; import org.jetbrains.annotations.NotNull; import java.time.Instant; -import java.util.Collection; -import java.util.List; +import java.util.Map; @EqualsAndHashCode(callSuper = true) @ToString @@ -26,33 +25,49 @@ public MinerStartedEvent(@NotNull IMiner miner, @NotNull String version, @NotNul @Override @NotNull - public String getAsLog(){ - return "Miner started (version: %s [%s - %s])".formatted(version, commit, branch); + public String getConsoleLogFormat(){ + return "Miner started (version: {version} [{commit} - {branch}])"; } @Override @NotNull - protected String getEmoji(){ - return "✅"; + public String getDefaultFormat(){ + return "[{username}] {emoji} : Miner started with version {version} [{commit} - {branch}]"; } @Override - protected int getEmbedColor(){ - return COLOR_INFO; + public String lookup(String key){ + if(EventVariableKey.VERSION.equals(key)){ + return version; + } + if(EventVariableKey.COMMIT.equals(key)){ + return commit; + } + if(EventVariableKey.BRANCH.equals(key)){ + return branch; + } + return super.lookup(key); + } + + @Override + @NotNull + public Map getEmbedFields(){ + return Map.of( + "Version", EventVariableKey.VERSION, + "Commit", EventVariableKey.COMMIT, + "Branch", EventVariableKey.BRANCH + ); } @Override @NotNull - protected String getEmbedDescription(){ - return "Miner started"; + protected String getColor(){ + return COLOR_INFO; } @Override @NotNull - protected Collection getEmbedFields(){ - return List.of( - Field.builder().name("Version").value(version).build(), - Field.builder().name("Commit").value(commit).build(), - Field.builder().name("Branch").value(branch).build()); + protected String getEmoji(){ + return "✅"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PointsEarnedEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PointsEarnedEvent.java index 492b8116..db6524dc 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PointsEarnedEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PointsEarnedEvent.java @@ -1,8 +1,8 @@ package fr.rakambda.channelpointsminer.miner.event.impl; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.pointsearned.PointsEarnedData; import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableStreamerEvent; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import fr.rakambda.channelpointsminer.miner.streamer.Streamer; import lombok.EqualsAndHashCode; @@ -10,8 +10,7 @@ import lombok.ToString; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.List; +import java.util.Map; @EqualsAndHashCode(callSuper = true) @ToString @@ -26,36 +25,49 @@ public PointsEarnedEvent(@NotNull IMiner miner, @NotNull String streamerId, @Nul @Override @NotNull - public String getAsLog(){ - return "Points earned [%s | %s | %s]".formatted( - millify(pointsEarnedData.getPointGain().getTotalPoints(), true), - pointsEarnedData.getPointGain().getReasonCode(), - millify(pointsEarnedData.getBalance().getBalance(), false)); + public String getConsoleLogFormat(){ + return "Points earned [{points} | {reason} | {balance}]"; } @Override @NotNull - protected String getEmoji(){ - return "💰"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Points earned [{points} | {reason} | {balance}]"; } @Override - protected int getEmbedColor(){ - return COLOR_POINTS_WON; + public String lookup(String key){ + if(EventVariableKey.POINTS.equals(key)){ + return millify(pointsEarnedData.getPointGain().getTotalPoints(), true); + } + if(EventVariableKey.REASON.equals(key)){ + return pointsEarnedData.getPointGain().getReasonCode().toString(); + } + if(EventVariableKey.BALANCE.equals(key)){ + return millify(pointsEarnedData.getBalance().getBalance(), false); + } + return super.lookup(key); + } + + @Override + @NotNull + public Map getEmbedFields(){ + return Map.of( + "Points", EventVariableKey.POINTS, + "Reason", EventVariableKey.REASON, + "Balance", EventVariableKey.BALANCE + ); } @Override @NotNull - protected String getEmbedDescription(){ - return "Points earned"; + protected String getColor(){ + return COLOR_POINTS_WON; } @Override @NotNull - protected Collection getEmbedFields(){ - return List.of( - Field.builder().name("Points").value(millify(pointsEarnedData.getPointGain().getTotalPoints(), true)).build(), - Field.builder().name("Reason").value(pointsEarnedData.getPointGain().getReasonCode().toString()).build(), - Field.builder().name("Balance").value(millify(pointsEarnedData.getBalance().getBalance(), false)).build()); + protected String getEmoji(){ + return "💰"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PointsSpentEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PointsSpentEvent.java index 8852bd97..e87a1c37 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PointsSpentEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PointsSpentEvent.java @@ -1,8 +1,8 @@ package fr.rakambda.channelpointsminer.miner.event.impl; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.pointsspent.PointsSpentData; import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableStreamerEvent; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import fr.rakambda.channelpointsminer.miner.streamer.Streamer; import lombok.EqualsAndHashCode; @@ -10,8 +10,7 @@ import lombok.ToString; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.List; +import java.util.Map; @EqualsAndHashCode(callSuper = true) @ToString @@ -26,33 +25,39 @@ public PointsSpentEvent(@NotNull IMiner miner, @NotNull String streamerId, @Null @Override @NotNull - public String getAsLog(){ - return "Points spent [%s]".formatted(millify(pointsSpentData.getBalance().getBalance(), false)); + public String getConsoleLogFormat(){ + return "Points spent [{balance}]"; } @Override @NotNull - protected String getEmoji(){ - return "💸"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Points spent [{balance}]"; } @Override - protected int getEmbedColor(){ - return COLOR_POINTS_LOST; + public String lookup(String key){ + if(EventVariableKey.BALANCE.equals(key)){ + return millify(pointsSpentData.getBalance().getBalance(), false); + } + return super.lookup(key); + } + + @Override + @NotNull + public Map getEmbedFields(){ + return Map.of("Balance", EventVariableKey.BALANCE); } @Override @NotNull - protected String getEmbedDescription(){ - return "Points spent"; + protected String getColor(){ + return COLOR_POINTS_LOST; } @Override @NotNull - protected Collection getEmbedFields(){ - return List.of(Field.builder() - .name("Balance") - .value(millify(pointsSpentData.getBalance().getBalance(), false)) - .build()); + protected String getEmoji(){ + return "💸"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PredictionMadeEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PredictionMadeEvent.java index f1437894..3da4ca6c 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PredictionMadeEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PredictionMadeEvent.java @@ -1,8 +1,8 @@ package fr.rakambda.channelpointsminer.miner.event.impl; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.subtype.Event; import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableStreamerEvent; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; import fr.rakambda.channelpointsminer.miner.handler.data.BettingPrediction; import fr.rakambda.channelpointsminer.miner.handler.data.PlacedPrediction; import fr.rakambda.channelpointsminer.miner.miner.IMiner; @@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; -import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -32,44 +32,57 @@ public PredictionMadeEvent(@NotNull IMiner miner, @NotNull String streamerId, @N @Override @NotNull - public String getAsLog(){ - return "Bet placed [%s | %s]".formatted(millify(placedPrediction.getAmount(), false), getOutcome()); + public String getConsoleLogFormat(){ + return "Bet placed [{prediction_points} | {prediction_outcome}]"; } + @Override @NotNull - private String getOutcome(){ - return Optional.ofNullable(placedPrediction.getBettingPrediction()) - .map(BettingPrediction::getEvent) - .map(Event::getOutcomes).stream() - .flatMap(Collection::stream) - .filter(outcome -> Objects.equals(outcome.getId(), placedPrediction.getOutcomeId())) - .findFirst() - .map(outcome -> outcome.getColor() + ": " + outcome.getTitle()) - .orElse(UNKNOWN_OUTCOME); + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Bet placed [{prediction_points} | {prediction_outcome}]"; + } + + @Override + public String lookup(String key){ + if(EventVariableKey.PREDICTION_POINTS.equals(key)){ + return millify(placedPrediction.getAmount(), false); + } + if(EventVariableKey.PREDICTION_OUTCOME.equals(key)){ + return getOutcome(); + } + return super.lookup(key); } @Override @NotNull - protected String getEmoji(){ - return "đŸĒ™"; + public Map getEmbedFields(){ + return Map.of( + "Points placed", EventVariableKey.PREDICTION_POINTS, + "Outcome", EventVariableKey.PREDICTION_OUTCOME + ); } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_PREDICTION; } @Override @NotNull - protected String getEmbedDescription(){ - return "Bet placed"; + protected String getEmoji(){ + return "đŸĒ™"; } - @Override @NotNull - protected Collection getEmbedFields(){ - return List.of( - Field.builder().name("Points placed").value(millify(placedPrediction.getAmount(), false)).build(), - Field.builder().name("Outcome").value(getOutcome()).build()); + private String getOutcome(){ + return Optional.ofNullable(placedPrediction.getBettingPrediction()) + .map(BettingPrediction::getEvent) + .map(Event::getOutcomes).stream() + .flatMap(Collection::stream) + .filter(outcome -> Objects.equals(outcome.getId(), placedPrediction.getOutcomeId())) + .findFirst() + .map(outcome -> outcome.getColor() + ": " + outcome.getTitle()) + .orElse(UNKNOWN_OUTCOME); } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PredictionResultEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PredictionResultEvent.java index 50400c26..e39243d1 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PredictionResultEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/PredictionResultEvent.java @@ -1,10 +1,10 @@ package fr.rakambda.channelpointsminer.miner.event.impl; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.predictionresult.PredictionResultData; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.subtype.PredictionResultPayload; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.subtype.PredictionResultType; import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableStreamerEvent; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; import fr.rakambda.channelpointsminer.miner.handler.data.PlacedPrediction; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import fr.rakambda.channelpointsminer.miner.streamer.Streamer; @@ -13,8 +13,7 @@ import lombok.ToString; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.List; +import java.util.Map; import java.util.Optional; @EqualsAndHashCode(callSuper = true) @@ -32,53 +31,66 @@ public PredictionResultEvent(@NotNull IMiner miner, @NotNull String streamerId, @Override @NotNull - public String getAsLog(){ - return "Bet result [%s | %s]".formatted(getType(), getGain()); + public String getConsoleLogFormat(){ + return "Bet result [{prediction_type} | {prediction_points}]"; } + @Override @NotNull - private PredictionResultType getType(){ - var result = Optional.ofNullable(predictionResultData.getPrediction().getResult()); - return result.map(PredictionResultPayload::getType).orElse(PredictionResultType.UNKNOWN); + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Bet result [{prediction_type} | {prediction_points}]"; } - @NotNull - public String getGain(){ - if(getType() == PredictionResultType.REFUND){ - return "0"; + @Override + public String lookup(String key){ + if(EventVariableKey.PREDICTION_TYPE.equals(key)){ + return getType().toString(); } - - var result = Optional.ofNullable(predictionResultData.getPrediction().getResult()); - int pointsWon = result.map(PredictionResultPayload::getPointsWon).orElse(0); - - return Optional.ofNullable(placedPrediction) - .map(prediction -> pointsWon - prediction.getAmount()) - .map(value -> millify(value, true)) - .orElse("Unknown final gain, obtained %s points".formatted(millify(pointsWon, true))); + if(EventVariableKey.PREDICTION_POINTS.equals(key)){ + return getGain(); + } + return super.lookup(key); } @Override @NotNull - protected String getEmoji(){ - return "🧧"; + public Map getEmbedFields(){ + return Map.of( + "Type", EventVariableKey.PREDICTION_TYPE, + "Points gained", EventVariableKey.PREDICTION_POINTS + ); } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_PREDICTION; } @Override @NotNull - protected String getEmbedDescription(){ - return "Bet result"; + protected String getEmoji(){ + return "🧧"; } - @Override @NotNull - protected Collection getEmbedFields(){ - return List.of( - Field.builder().name("Type").value(getType().toString()).build(), - Field.builder().name("Points gained").value(getGain()).build()); + private PredictionResultType getType(){ + var result = Optional.ofNullable(predictionResultData.getPrediction().getResult()); + return result.map(PredictionResultPayload::getType).orElse(PredictionResultType.UNKNOWN); + } + + @NotNull + public String getGain(){ + if(getType() == PredictionResultType.REFUND){ + return "0"; + } + + var result = Optional.ofNullable(predictionResultData.getPrediction().getResult()); + int pointsWon = result.map(PredictionResultPayload::getPointsWon).orElse(0); + + return Optional.ofNullable(placedPrediction) + .map(prediction -> pointsWon - prediction.getAmount()) + .map(value -> millify(value, true)) + .orElse("Unknown final gain, obtained %s points".formatted(millify(pointsWon, true))); } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamDownEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamDownEvent.java index c85a2db1..2f6dfa34 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamDownEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamDownEvent.java @@ -18,24 +18,25 @@ public StreamDownEvent(@NotNull IMiner miner, @NotNull String streamerId, @Nulla @Override @NotNull - public String getAsLog(){ + public String getConsoleLogFormat(){ return "Stream stopped"; } @Override @NotNull - protected String getEmoji(){ - return "⏚ī¸"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Stream stopped"; } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_INFO; } @Override @NotNull - protected String getEmbedDescription(){ - return "Stream stopped"; + protected String getEmoji(){ + return "⏚ī¸"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamUpEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamUpEvent.java index c826c71d..74f8274d 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamUpEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamUpEvent.java @@ -18,24 +18,25 @@ public StreamUpEvent(@NotNull IMiner miner, @NotNull String streamerId, @Nullabl @Override @NotNull - public String getAsLog(){ + public String getConsoleLogFormat(){ return "Stream started"; } @Override @NotNull - protected String getEmoji(){ - return "â–ļī¸"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Stream started"; } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_INFO; } @Override @NotNull - protected String getEmbedDescription(){ - return "Stream started"; + protected String getEmoji(){ + return "â–ļī¸"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerAddedEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerAddedEvent.java index d61771f6..b6acf200 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerAddedEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerAddedEvent.java @@ -17,24 +17,25 @@ public StreamerAddedEvent(@NotNull IMiner miner, @NotNull Streamer streamer, @No @Override @NotNull - public String getAsLog(){ + public String getConsoleLogFormat(){ return "Streamer added"; } @Override @NotNull - protected String getEmoji(){ - return "➕"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Streamer added"; } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_INFO; } @Override @NotNull - protected String getEmbedDescription(){ - return "Streamer added"; + protected String getEmoji(){ + return "➕"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerRemovedEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerRemovedEvent.java index 888301be..3b348535 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerRemovedEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerRemovedEvent.java @@ -17,24 +17,25 @@ public StreamerRemovedEvent(@NotNull IMiner miner, @NotNull Streamer streamer, @ @Override @NotNull - public String getAsLog(){ + public String getConsoleLogFormat(){ return "Streamer removed"; } @Override @NotNull - protected String getEmoji(){ - return "➖"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Streamer removed"; } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_INFO; } @Override @NotNull - protected String getEmbedDescription(){ - return "Streamer removed"; + protected String getEmoji(){ + return "➖"; } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerUnknownEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerUnknownEvent.java index 7abb3635..27bfc223 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerUnknownEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl/StreamerUnknownEvent.java @@ -1,14 +1,13 @@ package fr.rakambda.channelpointsminer.miner.event.impl; -import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableStreamerEvent; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; import fr.rakambda.channelpointsminer.miner.miner.IMiner; import lombok.EqualsAndHashCode; import lombok.ToString; import org.jetbrains.annotations.NotNull; import java.time.Instant; -import java.util.Collection; -import java.util.List; +import java.util.Map; @EqualsAndHashCode(callSuper = true) @ToString @@ -19,30 +18,31 @@ public StreamerUnknownEvent(@NotNull IMiner miner, @NotNull String streamerUsern @Override @NotNull - public String getAsLog(){ + public String getConsoleLogFormat(){ return "Streamer unknown"; } @Override @NotNull - protected String getEmoji(){ - return "❌"; + public String getDefaultFormat(){ + return "[{username}] {emoji} {streamer} : Streamer unknown"; } @Override - protected int getEmbedColor(){ + @NotNull + protected String getColor(){ return COLOR_INFO; } @Override @NotNull - protected String getEmbedDescription(){ - return "Streamer unknown"; + protected String getEmoji(){ + return "❌"; } - @NotNull @Override - protected Collection getEmbedFields(){ - return List.of(Field.builder().name("Username").value(getStreamerUsername().orElseThrow()).build()); + @NotNull + public Map getEmbedFields(){ + return Map.of("Streamer", EventVariableKey.STREAMER); } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactory.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactory.java index e86fa402..a24b6809 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactory.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactory.java @@ -1,9 +1,11 @@ package fr.rakambda.channelpointsminer.miner.factory; import fr.rakambda.channelpointsminer.miner.api.discord.DiscordApi; +import fr.rakambda.channelpointsminer.miner.config.DiscordConfiguration; import fr.rakambda.channelpointsminer.miner.event.IEventHandler; -import fr.rakambda.channelpointsminer.miner.log.DiscordEventListener; import fr.rakambda.channelpointsminer.miner.log.LoggerEventListener; +import fr.rakambda.channelpointsminer.miner.log.discord.DiscordEventListener; +import fr.rakambda.channelpointsminer.miner.log.discord.DiscordMessageBuilder; import lombok.NoArgsConstructor; import org.jetbrains.annotations.NotNull; import static lombok.AccessLevel.PRIVATE; @@ -16,7 +18,7 @@ public static IEventHandler createLogger(){ } @NotNull - public static IEventHandler createDiscordLogger(@NotNull DiscordApi discordApi, boolean useEmbeds){ - return new DiscordEventListener(discordApi, useEmbeds, e -> true); + public static IEventHandler createDiscordLogger(@NotNull DiscordApi discordApi, @NotNull DiscordConfiguration discordConfiguration){ + return new DiscordEventListener(discordApi, discordConfiguration, new DiscordMessageBuilder()); } } \ No newline at end of file diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/MinerFactory.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/MinerFactory.java index 9a2c60aa..e76b1fa4 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/MinerFactory.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/factory/MinerFactory.java @@ -38,7 +38,7 @@ public static Miner create(@NotNull AccountConfiguration config){ miner.addEventHandler(LogEventListenerFactory.createLogger()); if(Objects.nonNull(config.getDiscord().getUrl())){ var discordApi = ApiFactory.createdDiscordApi(config.getDiscord().getUrl()); - miner.addEventHandler(LogEventListenerFactory.createDiscordLogger(discordApi, config.getDiscord().isEmbeds())); + miner.addEventHandler(LogEventListenerFactory.createDiscordLogger(discordApi, config.getDiscord())); } if(config.getAnalytics().isEnabled()){ diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListener.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListener.java deleted file mode 100644 index 65a80373..00000000 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListener.java +++ /dev/null @@ -1,38 +0,0 @@ -package fr.rakambda.channelpointsminer.miner.log; - -import fr.rakambda.channelpointsminer.miner.api.discord.DiscordApi; -import fr.rakambda.channelpointsminer.miner.event.EventHandlerAdapter; -import fr.rakambda.channelpointsminer.miner.event.ILoggableEvent; -import fr.rakambda.channelpointsminer.miner.event.IStreamerEvent; -import lombok.RequiredArgsConstructor; -import lombok.extern.log4j.Log4j2; -import org.jetbrains.annotations.NotNull; -import java.util.function.Predicate; - -@Log4j2 -@RequiredArgsConstructor -public class DiscordEventListener extends EventHandlerAdapter{ - private final DiscordApi discordApi; - private final boolean useEmbeds; - private final Predicate eventFilter; - - @Override - public void onILoggableEvent(@NotNull ILoggableEvent event){ - try(var context = LogContext.with(event.getMiner())){ - if(!eventFilter.test(event)){ - return; - } - - if(event instanceof IStreamerEvent e){ - e.getStreamerUsername().ifPresent(context::withStreamer); - } - - if(useEmbeds){ - discordApi.sendMessage(event.getAsWebhookEmbed()); - } - else{ - discordApi.sendMessage(event.getAsWebhookMessage()); - } - } - } -} diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/LoggerEventListener.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/LoggerEventListener.java index bc5c2ed7..1300ff5c 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/LoggerEventListener.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/LoggerEventListener.java @@ -16,7 +16,7 @@ public void onILoggableEvent(@NotNull ILoggableEvent event){ if(event instanceof IStreamerEvent e){ e.getStreamerUsername().ifPresent(context::withStreamer); } - log.info(event.getAsLog()); + log.info(event.getConsoleLogFormat()); } } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListener.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListener.java new file mode 100644 index 00000000..3e9594a8 --- /dev/null +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListener.java @@ -0,0 +1,49 @@ +package fr.rakambda.channelpointsminer.miner.log.discord; + +import fr.rakambda.channelpointsminer.miner.api.discord.DiscordApi; +import fr.rakambda.channelpointsminer.miner.api.discord.data.Webhook; +import fr.rakambda.channelpointsminer.miner.config.DiscordConfiguration; +import fr.rakambda.channelpointsminer.miner.config.DiscordEventConfiguration; +import fr.rakambda.channelpointsminer.miner.event.EventHandlerAdapter; +import fr.rakambda.channelpointsminer.miner.event.ILoggableEvent; +import fr.rakambda.channelpointsminer.miner.event.IStreamerEvent; +import fr.rakambda.channelpointsminer.miner.log.LogContext; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.Objects; + +@Log4j2 +@RequiredArgsConstructor +public class DiscordEventListener extends EventHandlerAdapter{ + private final DiscordApi discordApi; + private final DiscordConfiguration discordConfiguration; + private final DiscordMessageBuilder discordMessageBuilder; + + @Override + public void onILoggableEvent(@NotNull ILoggableEvent event){ + try(var context = LogContext.with(event.getMiner())){ + if(event instanceof IStreamerEvent e){ + e.getStreamerUsername().ifPresent(context::withStreamer); + } + + var eventType = event.getClass().getSimpleName(); + var config = discordConfiguration.getEvents().get(eventType); + if(Objects.isNull(config) && !discordConfiguration.getEvents().isEmpty()){ + log.trace("Event of type {} skipped", eventType); + return; + } + + discordApi.sendMessage(buildMessage(event, config)); + } + } + + @NotNull + private Webhook buildMessage(@NotNull ILoggableEvent event, @Nullable DiscordEventConfiguration config){ + if(discordConfiguration.isEmbeds()){ + return discordMessageBuilder.createEmbedMessage(event, config); + } + return discordMessageBuilder.createSimpleMessage(event, config); + } +} diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java new file mode 100644 index 00000000..15f7831d --- /dev/null +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java @@ -0,0 +1,74 @@ +package fr.rakambda.channelpointsminer.miner.log.discord; + +import fr.rakambda.channelpointsminer.miner.api.discord.data.Author; +import fr.rakambda.channelpointsminer.miner.api.discord.data.Embed; +import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; +import fr.rakambda.channelpointsminer.miner.api.discord.data.Footer; +import fr.rakambda.channelpointsminer.miner.api.discord.data.Webhook; +import fr.rakambda.channelpointsminer.miner.config.DiscordEventConfiguration; +import fr.rakambda.channelpointsminer.miner.event.EventVariableKey; +import fr.rakambda.channelpointsminer.miner.event.ILoggableEvent; +import org.apache.commons.text.StringSubstitutor; +import org.apache.commons.text.lookup.StringLookup; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class DiscordMessageBuilder{ + @NotNull + public Webhook createSimpleMessage(@NotNull ILoggableEvent event, @Nullable DiscordEventConfiguration config){ + return Webhook.builder().content(formatMessage(event, event.getDefaultFormat())).build(); + } + + @NotNull + public Webhook createEmbedMessage(@NotNull ILoggableEvent event, @Nullable DiscordEventConfiguration config){ + var fields = event.getEmbedFields().entrySet().stream() + .map(e -> Field.builder().name(e.getKey()).value(formatMessage(event, e.getValue())).build()) + .collect(Collectors.toList()); + + var embed = Embed.builder() + .author(getEmbedAuthor(event)) + .footer(getEmbedFooter(event)) + .color(getEmbedColor(event)) + .description(formatMessage(event, event.getDefaultFormat())) + .fields(fields) + .build(); + + return Webhook.builder() + .embeds(List.of(embed)) + .build(); + } + + @NotNull + private String formatMessage(@NotNull StringLookup event, @NotNull String format){ + var substitutor = new StringSubstitutor(event, "{", "}", '$'); + return substitutor.replace(format); + } + + @Nullable + protected Author getEmbedAuthor(@NotNull StringLookup event){ + return Optional.ofNullable(event.lookup(EventVariableKey.STREAMER)) + .map(username -> Author.builder().name(username) + .url(event.lookup(EventVariableKey.STREAMER_URL)) + .iconUrl(event.lookup(EventVariableKey.STREAMER_PROFILE_PICTURE_URL)) + .build() + ) + .orElse(null); + } + + @Nullable + protected Footer getEmbedFooter(@NotNull StringLookup event){ + return Optional.ofNullable(event.lookup(EventVariableKey.USERNAME)) + .map(username -> Footer.builder().text(username).build()) + .orElse(null); + } + + @Nullable + protected Integer getEmbedColor(@NotNull StringLookup event){ + return Optional.ofNullable(event.lookup(EventVariableKey.COLOR)) + .map(Integer::parseInt) + .orElse(null); + } +} diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactoryTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactoryTest.java index 6029c14c..b4ffea6a 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactoryTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/factory/LogEventListenerFactoryTest.java @@ -1,8 +1,9 @@ package fr.rakambda.channelpointsminer.miner.factory; import fr.rakambda.channelpointsminer.miner.api.discord.DiscordApi; -import fr.rakambda.channelpointsminer.miner.log.DiscordEventListener; +import fr.rakambda.channelpointsminer.miner.config.DiscordConfiguration; import fr.rakambda.channelpointsminer.miner.log.LoggerEventListener; +import fr.rakambda.channelpointsminer.miner.log.discord.DiscordEventListener; import fr.rakambda.channelpointsminer.miner.tests.ParallelizableTest; import org.assertj.core.api.Assertions; import org.mockito.Mock; @@ -15,6 +16,8 @@ class LogEventListenerFactoryTest{ @Mock private DiscordApi discordApi; + @Mock + private DiscordConfiguration discordConfiguration; @Test void createLogger(){ @@ -23,6 +26,6 @@ void createLogger(){ @Test void createDiscordLogger(){ - Assertions.assertThat(LogEventListenerFactory.createDiscordLogger(discordApi, true)).isNotNull().isInstanceOf(DiscordEventListener.class); + Assertions.assertThat(LogEventListenerFactory.createDiscordLogger(discordApi, discordConfiguration)).isNotNull().isInstanceOf(DiscordEventListener.class); } } \ No newline at end of file diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/factory/MinerFactoryTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/factory/MinerFactoryTest.java index e2cbaec9..6d05acaf 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/factory/MinerFactoryTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/factory/MinerFactoryTest.java @@ -15,8 +15,8 @@ import fr.rakambda.channelpointsminer.miner.handler.PointsHandler; import fr.rakambda.channelpointsminer.miner.handler.PredictionsHandler; import fr.rakambda.channelpointsminer.miner.handler.StreamStartEndHandler; -import fr.rakambda.channelpointsminer.miner.log.DiscordEventListener; import fr.rakambda.channelpointsminer.miner.log.LoggerEventListener; +import fr.rakambda.channelpointsminer.miner.log.discord.DiscordEventListener; import fr.rakambda.channelpointsminer.miner.tests.ParallelizableTest; import org.assertj.core.api.Assertions; import org.mockito.Mock; diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerTest.java deleted file mode 100644 index 1ecd5901..00000000 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package fr.rakambda.channelpointsminer.miner.log; - -import fr.rakambda.channelpointsminer.miner.api.discord.DiscordApi; -import fr.rakambda.channelpointsminer.miner.api.ws.data.request.topic.Topic; -import fr.rakambda.channelpointsminer.miner.event.IEvent; -import fr.rakambda.channelpointsminer.miner.miner.IMiner; -import fr.rakambda.channelpointsminer.miner.streamer.Streamer; -import fr.rakambda.channelpointsminer.miner.tests.ParallelizableTest; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Optional; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -@ParallelizableTest -@ExtendWith(MockitoExtension.class) -class DiscordEventListenerTest{ - private static final String STREAMER_ID = "streamer-id"; - private static final String STREAMER_USERNAME = "streamer-name"; - private static final String USERNAME = "username"; - - @Mock - private IMiner miner; - @Mock - private DiscordApi discordApi; - @Mock - private Streamer streamer; - @Mock - private Topic topic; - - @BeforeEach - void setUp() throws MalformedURLException{ - var streamerProfileUrl = new URL("https://streamer-image"); - var channelUrl = new URL("https://streamer"); - - lenient().when(miner.getStreamerById(STREAMER_ID)).thenReturn(Optional.of(streamer)); - lenient().when(miner.getUsername()).thenReturn(USERNAME); - lenient().when(streamer.getUsername()).thenReturn(STREAMER_USERNAME); - lenient().when(streamer.getProfileImage()).thenReturn(Optional.of(streamerProfileUrl)); - lenient().when(streamer.getChannelUrl()).thenReturn(channelUrl); - - lenient().when(topic.getTarget()).thenReturn(STREAMER_ID); - } - - @Test - void eventIsFiltered(){ - var event = mock(IEvent.class); - - var tested = new DiscordEventListener(discordApi, true, e -> false); - tested.onEvent(event); - - verify(discordApi, never()).sendMessage(any()); - } -} \ No newline at end of file diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListenerTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListenerTest.java new file mode 100644 index 00000000..19b44bc2 --- /dev/null +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListenerTest.java @@ -0,0 +1,111 @@ +package fr.rakambda.channelpointsminer.miner.log.discord; + +import fr.rakambda.channelpointsminer.miner.api.discord.DiscordApi; +import fr.rakambda.channelpointsminer.miner.api.discord.data.Webhook; +import fr.rakambda.channelpointsminer.miner.config.DiscordConfiguration; +import fr.rakambda.channelpointsminer.miner.config.DiscordEventConfiguration; +import fr.rakambda.channelpointsminer.miner.event.IEvent; +import fr.rakambda.channelpointsminer.miner.event.ILoggableEvent; +import fr.rakambda.channelpointsminer.miner.tests.ParallelizableTest; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import java.util.Map; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ParallelizableTest +@ExtendWith(MockitoExtension.class) +class DiscordEventListenerTest{ + @InjectMocks + private DiscordEventListener tested; + + @Mock + private DiscordApi discordApi; + @Mock + private DiscordConfiguration discordConfiguration; + @Mock + private DiscordMessageBuilder discordMessageBuilder; + + @BeforeEach + void setUp(){ + lenient().when(discordConfiguration.isEmbeds()).thenReturn(false); + lenient().when(discordConfiguration.getEvents()).thenReturn(Map.of()); + } + + @Test + void notLoggableEventIsIgnored(){ + var event = mock(IEvent.class); + + tested.onEvent(event); + + verify(discordApi, never()).sendMessage(any()); + } + + @Test + void eventIsFiltered(){ + var event = mock(ILoggableEvent.class); + + when(discordConfiguration.getEvents()).thenReturn(Map.of("unknown", mock(DiscordEventConfiguration.class))); + tested.onEvent(event); + + verify(discordApi, never()).sendMessage(any()); + } + + @Test + void messageIsSent(){ + var event = mock(ILoggableEvent.class); + var eventConfiguration = mock(DiscordEventConfiguration.class); + var webhook = mock(Webhook.class); + + when(discordConfiguration.getEvents()).thenReturn(Map.of(event.getClass().getSimpleName(), eventConfiguration)); + when(discordMessageBuilder.createSimpleMessage(event, eventConfiguration)).thenReturn(webhook); + tested.onEvent(event); + + verify(discordApi).sendMessage(webhook); + } + + @Test + void messageIsSentDefaultConfig(){ + var event = mock(ILoggableEvent.class); + var webhook = mock(Webhook.class); + + when(discordMessageBuilder.createSimpleMessage(event, null)).thenReturn(webhook); + tested.onEvent(event); + + verify(discordApi).sendMessage(webhook); + } + + @Test + void embedIsSent(){ + var event = mock(ILoggableEvent.class); + var eventConfiguration = mock(DiscordEventConfiguration.class); + var webhook = mock(Webhook.class); + + when(discordConfiguration.isEmbeds()).thenReturn(true); + when(discordConfiguration.getEvents()).thenReturn(Map.of(event.getClass().getSimpleName(), eventConfiguration)); + when(discordMessageBuilder.createEmbedMessage(event, eventConfiguration)).thenReturn(webhook); + tested.onEvent(event); + + verify(discordApi).sendMessage(webhook); + } + + @Test + void embedIsSentDefaultConfig(){ + var event = mock(ILoggableEvent.class); + var webhook = mock(Webhook.class); + + when(discordConfiguration.isEmbeds()).thenReturn(true); + when(discordMessageBuilder.createEmbedMessage(event, null)).thenReturn(webhook); + tested.onEvent(event); + + verify(discordApi).sendMessage(webhook); + } +} \ No newline at end of file diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerEmbedTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java similarity index 78% rename from miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerEmbedTest.java rename to miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java index 26c5b1db..1765ff96 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerEmbedTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java @@ -1,6 +1,5 @@ -package fr.rakambda.channelpointsminer.miner.log; +package fr.rakambda.channelpointsminer.miner.log.discord; -import fr.rakambda.channelpointsminer.miner.api.discord.DiscordApi; import fr.rakambda.channelpointsminer.miner.api.discord.data.Author; import fr.rakambda.channelpointsminer.miner.api.discord.data.Embed; import fr.rakambda.channelpointsminer.miner.api.discord.data.Field; @@ -20,7 +19,7 @@ import fr.rakambda.channelpointsminer.miner.api.ws.data.message.subtype.PredictionResultPayload; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.subtype.PredictionResultType; import fr.rakambda.channelpointsminer.miner.api.ws.data.request.topic.Topic; -import fr.rakambda.channelpointsminer.miner.event.IEvent; +import fr.rakambda.channelpointsminer.miner.config.DiscordEventConfiguration; import fr.rakambda.channelpointsminer.miner.event.impl.ClaimAvailableEvent; import fr.rakambda.channelpointsminer.miner.event.impl.ClaimMomentEvent; import fr.rakambda.channelpointsminer.miner.event.impl.ClaimedMomentEvent; @@ -42,6 +41,7 @@ import fr.rakambda.channelpointsminer.miner.miner.IMiner; import fr.rakambda.channelpointsminer.miner.streamer.Streamer; import fr.rakambda.channelpointsminer.miner.tests.ParallelizableTest; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.BeforeEach; @@ -58,28 +58,27 @@ import static java.awt.Color.GREEN; import static java.awt.Color.PINK; import static java.awt.Color.RED; -import static org.mockito.ArgumentMatchers.any; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @ParallelizableTest @ExtendWith(MockitoExtension.class) -class DiscordEventListenerEmbedTest{ +class DiscordMessageBuilderEmbedTest{ private static final String STREAMER_ID = "streamer-id"; private static final String STREAMER_USERNAME = "streamer-name"; private static final String USERNAME = "username"; private static final Instant NOW = Instant.parse("2020-05-17T12:14:20.000Z"); private static final ZonedDateTime ZONED_NOW = ZonedDateTime.ofInstant(NOW, ZoneId.systemDefault()); - private DiscordEventListener tested; + @InjectMocks + private DiscordMessageBuilder tested; @Mock - private IMiner miner; + private DiscordEventConfiguration discordEventConfiguration; @Mock - private DiscordApi discordApi; + private IMiner miner; @Mock private Streamer streamer; @Mock @@ -90,15 +89,13 @@ class DiscordEventListenerEmbedTest{ @BeforeEach void setUp() throws MalformedURLException{ - tested = new DiscordEventListener(discordApi, true, e -> true); - var streamerProfileUrl = new URL("https://streamer-image"); var channelUrl = new URL("https://streamer"); author = Author.builder() .name(STREAMER_USERNAME) - .url(channelUrl) - .iconUrl(streamerProfileUrl) + .url(channelUrl.toString()) + .iconUrl(streamerProfileUrl.toString()) .build(); footer = Footer.builder() .text(USERNAME) @@ -113,20 +110,11 @@ void setUp() throws MalformedURLException{ lenient().when(topic.getTarget()).thenReturn(STREAMER_ID); } - @Test - void notLoggableEventIsIgnored(){ - var event = mock(IEvent.class); - - tested.onEvent(event); - - verify(discordApi, never()).sendMessage(any()); - } - @Test void onClaimAvailable(){ - tested.onEvent(new ClaimAvailableEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createEmbedMessage(new ClaimAvailableEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -138,9 +126,9 @@ void onClaimAvailable(){ @Test void onClaimMoment(){ - tested.onEvent(new ClaimMomentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createEmbedMessage(new ClaimMomentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -152,9 +140,9 @@ void onClaimMoment(){ @Test void onClaimedMoment(){ - tested.onEvent(new ClaimedMomentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createEmbedMessage(new ClaimedMomentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -177,9 +165,9 @@ void onPointsEarned(){ when(pointGain.getReasonCode()).thenReturn(PointReasonCode.CLAIM); when(balance.getBalance()).thenReturn(200); - tested.onEvent(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data)); + var webhook = tested.createEmbedMessage(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -205,9 +193,9 @@ void onPointsEarnedBigValue(){ when(pointGain.getReasonCode()).thenReturn(PointReasonCode.CLAIM); when(balance.getBalance()).thenReturn(12345678); - tested.onEvent(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data)); + var webhook = tested.createEmbedMessage(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -233,9 +221,9 @@ void onPointsEarnedBigNegativeValue(){ when(pointGain.getReasonCode()).thenReturn(PointReasonCode.CLAIM); when(balance.getBalance()).thenReturn(12345678); - tested.onEvent(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data)); + var webhook = tested.createEmbedMessage(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -257,9 +245,9 @@ void onPointsSpent(){ when(data.getTimestamp()).thenReturn(ZONED_NOW); when(balance.getBalance()).thenReturn(25); - tested.onEvent(new PointsSpentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data)); + var webhook = tested.createEmbedMessage(new PointsSpentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -272,9 +260,9 @@ void onPointsSpent(){ @Test void onStreamUp(){ - tested.onEvent(new StreamUpEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createEmbedMessage(new StreamUpEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -286,9 +274,9 @@ void onStreamUp(){ @Test void authorNotFound(){ - tested.onEvent(new StreamUpEvent(miner, STREAMER_ID, null, null, NOW)); + var webhook = tested.createEmbedMessage(new StreamUpEvent(miner, STREAMER_ID, null, null, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .footer(footer) .color(CYAN.getRGB()) @@ -299,9 +287,9 @@ void authorNotFound(){ @Test void onStreamDown(){ - tested.onEvent(new StreamDownEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createEmbedMessage(new StreamDownEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -319,9 +307,9 @@ void onEventCreated(){ when(event.getTitle()).thenReturn(title); when(event.getCreatedAt()).thenReturn(ZONED_NOW); - tested.onEvent(new EventCreatedEvent(miner, streamer, event)); + var webhook = tested.createEmbedMessage(new EventCreatedEvent(miner, streamer, event), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -353,9 +341,9 @@ void onPredictionMade(){ when(outcome2.getColor()).thenReturn(OutcomeColor.BLUE); when(outcome2.getTitle()).thenReturn(outcomeName); - tested.onEvent(new PredictionMadeEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction)); + var webhook = tested.createEmbedMessage(new PredictionMadeEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -382,9 +370,9 @@ void onPredictionMadeUnknownOutcome(){ when(event.getOutcomes()).thenReturn(List.of(outcome1)); when(outcome1.getId()).thenReturn("bad-id"); - tested.onEvent(new PredictionMadeEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction)); + var webhook = tested.createEmbedMessage(new PredictionMadeEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -410,9 +398,9 @@ void onPredictionResult(){ when(result.getType()).thenReturn(PredictionResultType.WIN); when(result.getPointsWon()).thenReturn(56); - tested.onEvent(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction, predictionResultData)); + var webhook = tested.createEmbedMessage(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction, predictionResultData), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -436,9 +424,9 @@ void onPredictionResultRefund(){ when(prediction.getResult()).thenReturn(result); when(result.getType()).thenReturn(PredictionResultType.REFUND); - tested.onEvent(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction, predictionResultData)); + var webhook = tested.createEmbedMessage(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction, predictionResultData), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -462,9 +450,9 @@ void onPredictionResultNoPlacedPrediction(){ when(result.getType()).thenReturn(PredictionResultType.WIN); when(result.getPointsWon()).thenReturn(56); - tested.onEvent(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, null, predictionResultData)); + var webhook = tested.createEmbedMessage(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, null, predictionResultData), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -481,9 +469,9 @@ void onMinerStarted(){ var version = "test-version"; var commit = "test-commit"; var branch = "test-branch"; - tested.onEvent(new MinerStartedEvent(miner, version, commit, branch, NOW)); + var webhook = tested.createEmbedMessage(new MinerStartedEvent(miner, version, commit, branch, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .footer(footer) .color(CYAN.getRGB()) @@ -497,9 +485,9 @@ void onMinerStarted(){ @Test void onStreamerAdded(){ - tested.onEvent(new StreamerAddedEvent(miner, streamer, NOW)); + var webhook = tested.createEmbedMessage(new StreamerAddedEvent(miner, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -511,9 +499,9 @@ void onStreamerAdded(){ @Test void onStreamerRemoved(){ - tested.onEvent(new StreamerRemovedEvent(miner, streamer, NOW)); + var webhook = tested.createEmbedMessage(new StreamerRemovedEvent(miner, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(author) .footer(footer) @@ -525,9 +513,9 @@ void onStreamerRemoved(){ @Test void onStreamerUnknown(){ - tested.onEvent(new StreamerUnknownEvent(miner, STREAMER_USERNAME, NOW)); + var webhook = tested.createEmbedMessage(new StreamerUnknownEvent(miner, STREAMER_USERNAME, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .author(Author.builder() .name(STREAMER_USERNAME) @@ -546,9 +534,9 @@ void onDropClaim(){ var drop = mock(TimeBasedDrop.class); when(drop.getName()).thenReturn(name); - tested.onEvent(new DropClaimEvent(miner, drop, NOW)); + var webhook = tested.createEmbedMessage(new DropClaimEvent(miner, drop, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .footer(footer) .color(CYAN.getRGB()) @@ -564,9 +552,9 @@ void onDropClaimed(){ var drop = mock(TimeBasedDrop.class); when(drop.getName()).thenReturn(name); - tested.onEvent(new DropClaimedEvent(miner, drop, NOW)); + var webhook = tested.createEmbedMessage(new DropClaimedEvent(miner, drop, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() .footer(footer) .color(CYAN.getRGB()) diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerMessageTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderMessageTest.java similarity index 72% rename from miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerMessageTest.java rename to miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderMessageTest.java index 48bdc545..6f9247d9 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/DiscordEventListenerMessageTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderMessageTest.java @@ -1,6 +1,5 @@ -package fr.rakambda.channelpointsminer.miner.log; +package fr.rakambda.channelpointsminer.miner.log.discord; -import fr.rakambda.channelpointsminer.miner.api.discord.DiscordApi; import fr.rakambda.channelpointsminer.miner.api.discord.data.Webhook; import fr.rakambda.channelpointsminer.miner.api.gql.gql.data.types.TimeBasedDrop; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.pointsearned.Balance; @@ -16,7 +15,7 @@ import fr.rakambda.channelpointsminer.miner.api.ws.data.message.subtype.PredictionResultPayload; import fr.rakambda.channelpointsminer.miner.api.ws.data.message.subtype.PredictionResultType; import fr.rakambda.channelpointsminer.miner.api.ws.data.request.topic.Topic; -import fr.rakambda.channelpointsminer.miner.event.IEvent; +import fr.rakambda.channelpointsminer.miner.config.DiscordEventConfiguration; import fr.rakambda.channelpointsminer.miner.event.impl.ClaimAvailableEvent; import fr.rakambda.channelpointsminer.miner.event.impl.ClaimMomentEvent; import fr.rakambda.channelpointsminer.miner.event.impl.ClaimedMomentEvent; @@ -38,6 +37,7 @@ import fr.rakambda.channelpointsminer.miner.miner.IMiner; import fr.rakambda.channelpointsminer.miner.streamer.Streamer; import fr.rakambda.channelpointsminer.miner.tests.ParallelizableTest; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.BeforeEach; @@ -48,16 +48,14 @@ import java.time.ZonedDateTime; import java.util.List; import java.util.Optional; -import static org.mockito.ArgumentMatchers.any; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @ParallelizableTest @ExtendWith(MockitoExtension.class) -class DiscordEventListenerMessageTest{ +class DiscordMessageBuilderMessageTest{ private static final String STREAMER_ID = "streamer-id"; private static final String STREAMER_USERNAME = "streamer-name"; private static final String USERNAME = "username"; @@ -65,12 +63,13 @@ class DiscordEventListenerMessageTest{ private static final Instant NOW = Instant.parse("2020-05-17T12:14:20.000Z"); private static final ZonedDateTime ZONED_NOW = ZonedDateTime.ofInstant(NOW, ZoneId.systemDefault()); - private DiscordEventListener tested; + @InjectMocks + private DiscordMessageBuilder tested; @Mock - private IMiner miner; + private DiscordEventConfiguration discordEventConfiguration; @Mock - private DiscordApi discordApi; + private IMiner miner; @Mock private Streamer streamer; @Mock @@ -78,8 +77,6 @@ class DiscordEventListenerMessageTest{ @BeforeEach void setUp(){ - tested = new DiscordEventListener(discordApi, false, e -> true); - lenient().when(miner.getStreamerById(STREAMER_ID)).thenReturn(Optional.of(streamer)); lenient().when(miner.getUsername()).thenReturn(USERNAME); lenient().when(streamer.getUsername()).thenReturn(STREAMER_USERNAME); @@ -87,38 +84,29 @@ void setUp(){ lenient().when(topic.getTarget()).thenReturn(STREAMER_ID); } - @Test - void notLoggableEventIsIgnored(){ - var event = mock(IEvent.class); - - tested.onEvent(event); - - verify(discordApi, never()).sendMessage(any()); - } - @Test void onClaimAvailable(){ - tested.onEvent(new ClaimAvailableEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createSimpleMessage(new ClaimAvailableEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] đŸŽĢ %s : Claim available".formatted(USERNAME, STREAMER_USERNAME)) .build()); } @Test void onClaimMoment(){ - tested.onEvent(new ClaimMomentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createSimpleMessage(new ClaimMomentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 🎖ī¸ %s : Moment available".formatted(USERNAME, STREAMER_USERNAME)) .build()); } @Test void onClaimedMoment(){ - tested.onEvent(new ClaimedMomentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createSimpleMessage(new ClaimedMomentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 🎖ī¸ %s : Moment claimed".formatted(USERNAME, STREAMER_USERNAME)) .build()); } @@ -136,9 +124,9 @@ void onPointsEarned(){ when(pointGain.getReasonCode()).thenReturn(PointReasonCode.CLAIM); when(balance.getBalance()).thenReturn(200); - tested.onEvent(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data)); + var webhook = tested.createSimpleMessage(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 💰 %s : Points earned [%+d | %s | %d]".formatted(USERNAME, STREAMER_USERNAME, 25, "CLAIM", 200)) .build()); } @@ -156,9 +144,9 @@ void onPointsEarnedBigValue(){ when(pointGain.getReasonCode()).thenReturn(PointReasonCode.CLAIM); when(balance.getBalance()).thenReturn(12345678); - tested.onEvent(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data)); + var webhook = tested.createSimpleMessage(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 💰 %s : Points earned [%s | %s | %s]".formatted(USERNAME, STREAMER_USERNAME, "+2.5K", "CLAIM", "12.35M")) .build()); } @@ -176,9 +164,9 @@ void onPointsEarnedBigNegativeValue(){ when(pointGain.getReasonCode()).thenReturn(PointReasonCode.CLAIM); when(balance.getBalance()).thenReturn(12345678); - tested.onEvent(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data)); + var webhook = tested.createSimpleMessage(new PointsEarnedEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 💰 %s : Points earned [%s | %s | %s]".formatted(USERNAME, STREAMER_USERNAME, "-2.5K", "CLAIM", "12.35M")) .build()); } @@ -192,36 +180,36 @@ void onPointsSpent(){ when(data.getTimestamp()).thenReturn(ZONED_NOW); when(balance.getBalance()).thenReturn(25); - tested.onEvent(new PointsSpentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data)); + var webhook = tested.createSimpleMessage(new PointsSpentEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, data), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 💸 %s : Points spent [%d]".formatted(USERNAME, STREAMER_USERNAME, 25)) .build()); } @Test void onStreamUp(){ - tested.onEvent(new StreamUpEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createSimpleMessage(new StreamUpEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] â–ļī¸ %s : Stream started".formatted(USERNAME, STREAMER_USERNAME)) .build()); } @Test void authorNotFound(){ - tested.onEvent(new StreamUpEvent(miner, STREAMER_ID, null, null, NOW)); + var webhook = tested.createSimpleMessage(new StreamUpEvent(miner, STREAMER_ID, null, null, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] â–ļī¸ %s : Stream started".formatted(USERNAME, UNKNOWN_STREAMER)) .build()); } @Test void onStreamDown(){ - tested.onEvent(new StreamDownEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW)); + var webhook = tested.createSimpleMessage(new StreamDownEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] ⏚ī¸ %s : Stream stopped".formatted(USERNAME, STREAMER_USERNAME)) .build()); } @@ -234,9 +222,9 @@ void onEventCreated(){ when(event.getTitle()).thenReturn(title); when(event.getCreatedAt()).thenReturn(ZONED_NOW); - tested.onEvent(new EventCreatedEvent(miner, streamer, event)); + var webhook = tested.createSimpleMessage(new EventCreatedEvent(miner, streamer, event), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 📑 %s : Prediction created [%s]".formatted(USERNAME, STREAMER_USERNAME, title)) .build()); } @@ -262,9 +250,9 @@ void onPredictionMade(){ when(outcome2.getColor()).thenReturn(OutcomeColor.BLUE); when(outcome2.getTitle()).thenReturn(outcomeName); - tested.onEvent(new PredictionMadeEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction)); + var webhook = tested.createSimpleMessage(new PredictionMadeEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] đŸĒ™ %s : Bet placed [%d | %s: %s]".formatted(USERNAME, STREAMER_USERNAME, 25, "BLUE", outcomeName)) .build()); } @@ -284,9 +272,9 @@ void onPredictionMadeUnknownOutcome(){ when(event.getOutcomes()).thenReturn(List.of(outcome1)); when(outcome1.getId()).thenReturn("bad-id"); - tested.onEvent(new PredictionMadeEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction)); + var webhook = tested.createSimpleMessage(new PredictionMadeEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] đŸĒ™ %s : Bet placed [%d | %s]".formatted(USERNAME, STREAMER_USERNAME, 25, "UnknownOutcome")) .build()); } @@ -305,9 +293,9 @@ void onPredictionResult(){ when(result.getType()).thenReturn(PredictionResultType.WIN); when(result.getPointsWon()).thenReturn(56); - tested.onEvent(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction, predictionResultData)); + var webhook = tested.createSimpleMessage(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction, predictionResultData), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 🧧 %s : Bet result [%s | +%d]".formatted(USERNAME, STREAMER_USERNAME, "WIN", 40)) .build()); } @@ -324,9 +312,9 @@ void onPredictionResultRefund(){ when(prediction.getResult()).thenReturn(result); when(result.getType()).thenReturn(PredictionResultType.REFUND); - tested.onEvent(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction, predictionResultData)); + var webhook = tested.createSimpleMessage(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, placedPrediction, predictionResultData), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 🧧 %s : Bet result [%s | %d]".formatted(USERNAME, STREAMER_USERNAME, "REFUND", 0)) .build()); } @@ -343,9 +331,9 @@ void onPredictionResultNoPlacedPrediction(){ when(result.getType()).thenReturn(PredictionResultType.WIN); when(result.getPointsWon()).thenReturn(56); - tested.onEvent(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, null, predictionResultData)); + var webhook = tested.createSimpleMessage(new PredictionResultEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, null, predictionResultData), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 🧧 %s : Bet result [%s | Unknown final gain, obtained %+d points]".formatted(USERNAME, STREAMER_USERNAME, "WIN", 56)) .build()); } @@ -355,36 +343,36 @@ void onMinerStarted(){ var version = "test-version"; var commit = "test-commit"; var branch = "test-branch"; - tested.onEvent(new MinerStartedEvent(miner, version, commit, branch, NOW)); + var webhook = tested.createSimpleMessage(new MinerStartedEvent(miner, version, commit, branch, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() - .content("[%s] ✅ : Miner started (version: %s [%s - %s])".formatted(USERNAME, version, commit, branch)) + assertThat(webhook).isEqualTo(Webhook.builder() + .content("[%s] ✅ : Miner started with version %s [%s - %s]".formatted(USERNAME, version, commit, branch)) .build()); } @Test void onStreamerAdded(){ - tested.onEvent(new StreamerAddedEvent(miner, streamer, NOW)); + var webhook = tested.createSimpleMessage(new StreamerAddedEvent(miner, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] ➕ %s : Streamer added".formatted(USERNAME, STREAMER_USERNAME)) .build()); } @Test void onStreamerRemoved(){ - tested.onEvent(new StreamerRemovedEvent(miner, streamer, NOW)); + var webhook = tested.createSimpleMessage(new StreamerRemovedEvent(miner, streamer, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] ➖ %s : Streamer removed".formatted(USERNAME, STREAMER_USERNAME)) .build()); } @Test void onStreamerUnknown(){ - tested.onEvent(new StreamerUnknownEvent(miner, STREAMER_USERNAME, NOW)); + var webhook = tested.createSimpleMessage(new StreamerUnknownEvent(miner, STREAMER_USERNAME, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] ❌ %s : Streamer unknown".formatted(USERNAME, STREAMER_USERNAME)) .build()); } @@ -395,9 +383,9 @@ void onDropClaim(){ var drop = mock(TimeBasedDrop.class); when(drop.getName()).thenReturn(name); - tested.onEvent(new DropClaimEvent(miner, drop, NOW)); + var webhook = tested.createSimpleMessage(new DropClaimEvent(miner, drop, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 🎁 : Drop available [%s]".formatted(USERNAME, name)) .build()); } @@ -408,9 +396,9 @@ void onDropClaimed(){ var drop = mock(TimeBasedDrop.class); when(drop.getName()).thenReturn(name); - tested.onEvent(new DropClaimedEvent(miner, drop, NOW)); + var webhook = tested.createSimpleMessage(new DropClaimedEvent(miner, drop, NOW), discordEventConfiguration); - verify(discordApi).sendMessage(Webhook.builder() + assertThat(webhook).isEqualTo(Webhook.builder() .content("[%s] 🎁 : Drop claimed [%s]".formatted(USERNAME, name)) .build()); } From 06d639ee43abcf1264811c74661ceb05259120b5 Mon Sep 17 00:00:00 2001 From: Thomas Couchoud Date: Wed, 28 Dec 2022 18:11:46 +0100 Subject: [PATCH 3/7] Adapt embed tests to pass --- .../config/DiscordEventConfiguration.java | 2 +- .../event/AbstractLoggableStreamerEvent.java | 3 + .../miner/log/LoggerEventListener.java | 10 ++- .../log/discord/DiscordMessageBuilder.java | 4 +- .../DiscordMessageBuilderEmbedTest.java | 67 ++++++++++--------- 5 files changed, 50 insertions(+), 36 deletions(-) diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java index 4afcbef8..14ea9cab 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java @@ -18,7 +18,7 @@ @JsonClassDescription("Customization of the event sent.") public class DiscordEventConfiguration{ @JsonProperty("format") - @JsonPropertyDescription(value = "Format of the message sent.") + @JsonPropertyDescription(value = "Format of the message sent. Will be either the text, or the description of the embed.") @Nullable private String format; } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableStreamerEvent.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableStreamerEvent.java index 579fed1d..af96c86c 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableStreamerEvent.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/AbstractLoggableStreamerEvent.java @@ -37,6 +37,9 @@ public String lookup(String key){ if(EventVariableKey.STREAMER.equals(key)){ return getStreamerUsername().orElse(UNKNOWN_STREAMER); } + if(EventVariableKey.STREAMER_URL.equals(key)){ + return getStreamer().map(Streamer::getChannelUrl).map(URL::toString).orElse(null); + } if(EventVariableKey.STREAMER_PROFILE_PICTURE_URL.equals(key)){ return getStreamer().flatMap(Streamer::getProfileImage).map(URL::toString).orElse(null); } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/LoggerEventListener.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/LoggerEventListener.java index 1300ff5c..d22af1e2 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/LoggerEventListener.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/LoggerEventListener.java @@ -5,6 +5,8 @@ import fr.rakambda.channelpointsminer.miner.event.IStreamerEvent; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; +import org.apache.commons.text.StringSubstitutor; +import org.apache.commons.text.lookup.StringLookup; import org.jetbrains.annotations.NotNull; @Log4j2 @@ -16,7 +18,13 @@ public void onILoggableEvent(@NotNull ILoggableEvent event){ if(event instanceof IStreamerEvent e){ e.getStreamerUsername().ifPresent(context::withStreamer); } - log.info(event.getConsoleLogFormat()); + log.info(formatMessage(event, event.getConsoleLogFormat())); } } + + @NotNull + private String formatMessage(@NotNull StringLookup event, @NotNull String format){ + var substitutor = new StringSubstitutor(event, "{", "}", '$'); + return substitutor.replace(format); + } } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java index 15f7831d..01a2d07c 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java @@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -25,7 +26,8 @@ public Webhook createSimpleMessage(@NotNull ILoggableEvent event, @Nullable Disc @NotNull public Webhook createEmbedMessage(@NotNull ILoggableEvent event, @Nullable DiscordEventConfiguration config){ var fields = event.getEmbedFields().entrySet().stream() - .map(e -> Field.builder().name(e.getKey()).value(formatMessage(event, e.getValue())).build()) + .sorted(Map.Entry.comparingByKey()) + .map(e -> Field.builder().name(e.getKey()).value(formatMessage(event, "{%s}".formatted(e.getValue()))).build()) .collect(Collectors.toList()); var embed = Embed.builder() diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java index 1765ff96..0ac33c20 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java @@ -119,7 +119,7 @@ void onClaimAvailable(){ .author(author) .footer(footer) .color(CYAN.getRGB()) - .description("Claim available") + .description("[username] đŸŽĢ streamer-name : Claim available") .build())) .build()); } @@ -133,7 +133,7 @@ void onClaimMoment(){ .author(author) .footer(footer) .color(CYAN.getRGB()) - .description("Moment available") + .description("[username] \uD83C\uDF96ī¸ streamer-name : Moment available") .build())) .build()); } @@ -147,7 +147,7 @@ void onClaimedMoment(){ .author(author) .footer(footer) .color(CYAN.getRGB()) - .description("Moment claimed") + .description("[username] 🎖ī¸ streamer-name : Moment claimed") .build())) .build()); } @@ -172,10 +172,10 @@ void onPointsEarned(){ .author(author) .footer(footer) .color(GREEN.getRGB()) - .description("Points earned") + .description("[username] 💰 streamer-name : Points earned [+25 | CLAIM | 200]") + .field(Field.builder().name("Balance").value("200").build()) .field(Field.builder().name("Points").value("+25").build()) .field(Field.builder().name("Reason").value("CLAIM").build()) - .field(Field.builder().name("Balance").value("200").build()) .build())) .build()); } @@ -200,10 +200,10 @@ void onPointsEarnedBigValue(){ .author(author) .footer(footer) .color(GREEN.getRGB()) - .description("Points earned") + .description("[username] 💰 streamer-name : Points earned [+2.5K | CLAIM | 12.35M]") + .field(Field.builder().name("Balance").value("12.35M").build()) .field(Field.builder().name("Points").value("+2.5K").build()) .field(Field.builder().name("Reason").value("CLAIM").build()) - .field(Field.builder().name("Balance").value("12.35M").build()) .build())) .build()); } @@ -228,10 +228,10 @@ void onPointsEarnedBigNegativeValue(){ .author(author) .footer(footer) .color(GREEN.getRGB()) - .description("Points earned") + .description("[username] 💰 streamer-name : Points earned [-2.5K | CLAIM | 12.35M]") + .field(Field.builder().name("Balance").value("12.35M").build()) .field(Field.builder().name("Points").value("-2.5K").build()) .field(Field.builder().name("Reason").value("CLAIM").build()) - .field(Field.builder().name("Balance").value("12.35M").build()) .build())) .build()); } @@ -252,7 +252,7 @@ void onPointsSpent(){ .author(author) .footer(footer) .color(RED.getRGB()) - .description("Points spent") + .description("[username] 💸 streamer-name : Points spent [25]") .field(Field.builder().name("Balance").value("25").build()) .build())) .build()); @@ -267,7 +267,7 @@ void onStreamUp(){ .author(author) .footer(footer) .color(CYAN.getRGB()) - .description("Stream started") + .description("[username] â–ļī¸ streamer-name : Stream started") .build())) .build()); } @@ -278,9 +278,10 @@ void authorNotFound(){ assertThat(webhook).isEqualTo(Webhook.builder() .embeds(List.of(Embed.builder() + .author(Author.builder().name("UnknownStreamer").build()) .footer(footer) .color(CYAN.getRGB()) - .description("Stream started") + .description("[username] â–ļī¸ UnknownStreamer : Stream started") .build())) .build()); } @@ -294,7 +295,7 @@ void onStreamDown(){ .author(author) .footer(footer) .color(CYAN.getRGB()) - .description("Stream stopped") + .description("[username] ⏚ī¸ streamer-name : Stream stopped") .build())) .build()); } @@ -314,7 +315,7 @@ void onEventCreated(){ .author(author) .footer(footer) .color(PINK.getRGB()) - .description("Prediction created") + .description("[username] 📑 streamer-name : Prediction created [MyTitle]") .field(Field.builder().name("Title").value(title).build()) .build())) .build()); @@ -348,9 +349,9 @@ void onPredictionMade(){ .author(author) .footer(footer) .color(PINK.getRGB()) - .description("Bet placed") - .field(Field.builder().name("Points placed").value("25").build()) + .description("[username] đŸĒ™ streamer-name : Bet placed [25 | BLUE: Out2]") .field(Field.builder().name("Outcome").value("BLUE: " + outcomeName).build()) + .field(Field.builder().name("Points placed").value("25").build()) .build())) .build()); } @@ -377,9 +378,9 @@ void onPredictionMadeUnknownOutcome(){ .author(author) .footer(footer) .color(PINK.getRGB()) - .description("Bet placed") - .field(Field.builder().name("Points placed").value("25").build()) + .description("[username] đŸĒ™ streamer-name : Bet placed [25 | UnknownOutcome]") .field(Field.builder().name("Outcome").value("UnknownOutcome").build()) + .field(Field.builder().name("Points placed").value("25").build()) .build())) .build()); } @@ -405,9 +406,9 @@ void onPredictionResult(){ .author(author) .footer(footer) .color(PINK.getRGB()) - .description("Bet result") - .field(Field.builder().name("Type").value("WIN").build()) + .description("[username] 🧧 streamer-name : Bet result [WIN | +40]") .field(Field.builder().name("Points gained").value("+40").build()) + .field(Field.builder().name("Type").value("WIN").build()) .build())) .build()); } @@ -431,9 +432,9 @@ void onPredictionResultRefund(){ .author(author) .footer(footer) .color(PINK.getRGB()) - .description("Bet result") - .field(Field.builder().name("Type").value("REFUND").build()) + .description("[username] 🧧 streamer-name : Bet result [REFUND | 0]") .field(Field.builder().name("Points gained").value("0").build()) + .field(Field.builder().name("Type").value("REFUND").build()) .build())) .build()); } @@ -457,9 +458,9 @@ void onPredictionResultNoPlacedPrediction(){ .author(author) .footer(footer) .color(PINK.getRGB()) - .description("Bet result") - .field(Field.builder().name("Type").value("WIN").build()) + .description("[username] 🧧 streamer-name : Bet result [WIN | Unknown final gain, obtained +56 points]") .field(Field.builder().name("Points gained").value("Unknown final gain, obtained +56 points").build()) + .field(Field.builder().name("Type").value("WIN").build()) .build())) .build()); } @@ -475,10 +476,10 @@ void onMinerStarted(){ .embeds(List.of(Embed.builder() .footer(footer) .color(CYAN.getRGB()) - .description("Miner started") - .field(Field.builder().name("Version").value(version).build()) - .field(Field.builder().name("Commit").value(commit).build()) + .description("[username] ✅ : Miner started with version test-version [test-commit - test-branch]") .field(Field.builder().name("Branch").value(branch).build()) + .field(Field.builder().name("Commit").value(commit).build()) + .field(Field.builder().name("Version").value(version).build()) .build())) .build()); } @@ -492,7 +493,7 @@ void onStreamerAdded(){ .author(author) .footer(footer) .color(CYAN.getRGB()) - .description("Streamer added") + .description("[username] ➕ streamer-name : Streamer added") .build())) .build()); } @@ -506,7 +507,7 @@ void onStreamerRemoved(){ .author(author) .footer(footer) .color(CYAN.getRGB()) - .description("Streamer removed") + .description("[username] ➖ streamer-name : Streamer removed") .build())) .build()); } @@ -522,8 +523,8 @@ void onStreamerUnknown(){ .build()) .footer(footer) .color(CYAN.getRGB()) - .description("Streamer unknown") - .field(Field.builder().name("Username").value(STREAMER_USERNAME).build()) + .description("[username] ❌ streamer-name : Streamer unknown") + .field(Field.builder().name("Streamer").value(STREAMER_USERNAME).build()) .build())) .build()); } @@ -540,7 +541,7 @@ void onDropClaim(){ .embeds(List.of(Embed.builder() .footer(footer) .color(CYAN.getRGB()) - .description("Drop available") + .description("[username] 🎁 : Drop available [drop-name]") .field(Field.builder().name("Name").value(name).build()) .build())) .build()); @@ -558,7 +559,7 @@ void onDropClaimed(){ .embeds(List.of(Embed.builder() .footer(footer) .color(CYAN.getRGB()) - .description("Drop claimed") + .description("[username] \uD83C\uDF81 : Drop claimed [drop-name]") .field(Field.builder().name("Name").value(name).build()) .build())) .build()); From 7bd07b62497077e1e747ea562c3faed209a94080 Mon Sep 17 00:00:00 2001 From: Thomas Couchoud Date: Wed, 28 Dec 2022 18:18:06 +0100 Subject: [PATCH 4/7] Use provided custom format --- .../miner/config/DiscordConfiguration.java | 2 +- .../miner/config/DiscordEventConfiguration.java | 2 +- .../miner/log/discord/DiscordMessageBuilder.java | 7 +++++-- .../discord/DiscordMessageBuilderEmbedTest.java | 16 ++++++++++++++++ .../DiscordMessageBuilderMessageTest.java | 11 +++++++++++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordConfiguration.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordConfiguration.java index 559b2f64..81c226c5 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordConfiguration.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordConfiguration.java @@ -32,7 +32,7 @@ public class DiscordConfiguration{ @Builder.Default private boolean embeds = false; @JsonProperty("events") - @JsonPropertyDescription("Customize events that are sent. Default: all") + @JsonPropertyDescription("Customize events that are sent. Key is the name of an event (can be seen in the event/impl package). Default: all events with default format") @Builder.Default private Map events = new HashMap<>(); } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java index 14ea9cab..e10b8797 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/config/DiscordEventConfiguration.java @@ -18,7 +18,7 @@ @JsonClassDescription("Customization of the event sent.") public class DiscordEventConfiguration{ @JsonProperty("format") - @JsonPropertyDescription(value = "Format of the message sent. Will be either the text, or the description of the embed.") + @JsonPropertyDescription(value = "Format of the message sent. Will be either the text, or the description of the embed. Placeholders are between braces {example_key} . Keys can be seen in EventVariableKey class.") @Nullable private String format; } diff --git a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java index 01a2d07c..0a803bc4 100644 --- a/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java +++ b/miner/src/main/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilder.java @@ -20,11 +20,14 @@ public class DiscordMessageBuilder{ @NotNull public Webhook createSimpleMessage(@NotNull ILoggableEvent event, @Nullable DiscordEventConfiguration config){ - return Webhook.builder().content(formatMessage(event, event.getDefaultFormat())).build(); + var format = Optional.ofNullable(config).map(DiscordEventConfiguration::getFormat).orElseGet(event::getDefaultFormat); + return Webhook.builder().content(formatMessage(event, format)).build(); } @NotNull public Webhook createEmbedMessage(@NotNull ILoggableEvent event, @Nullable DiscordEventConfiguration config){ + var format = Optional.ofNullable(config).map(DiscordEventConfiguration::getFormat).orElseGet(event::getDefaultFormat); + var fields = event.getEmbedFields().entrySet().stream() .sorted(Map.Entry.comparingByKey()) .map(e -> Field.builder().name(e.getKey()).value(formatMessage(event, "{%s}".formatted(e.getValue()))).build()) @@ -34,7 +37,7 @@ public Webhook createEmbedMessage(@NotNull ILoggableEvent event, @Nullable Disco .author(getEmbedAuthor(event)) .footer(getEmbedFooter(event)) .color(getEmbedColor(event)) - .description(formatMessage(event, event.getDefaultFormat())) + .description(formatMessage(event, format)) .fields(fields) .build(); diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java index 0ac33c20..fb2ca4e1 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderEmbedTest.java @@ -110,6 +110,22 @@ void setUp() throws MalformedURLException{ lenient().when(topic.getTarget()).thenReturn(STREAMER_ID); } + @Test + void onClaimAvailableWithCustomFormat(){ + when(discordEventConfiguration.getFormat()).thenReturn("{streamer} override test"); + + var webhook = tested.createEmbedMessage(new ClaimAvailableEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); + + assertThat(webhook).isEqualTo(Webhook.builder() + .embeds(List.of(Embed.builder() + .author(author) + .footer(footer) + .color(CYAN.getRGB()) + .description("streamer-name override test") + .build())) + .build()); + } + @Test void onClaimAvailable(){ var webhook = tested.createEmbedMessage(new ClaimAvailableEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderMessageTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderMessageTest.java index 6f9247d9..8852d07d 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderMessageTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordMessageBuilderMessageTest.java @@ -84,6 +84,17 @@ void setUp(){ lenient().when(topic.getTarget()).thenReturn(STREAMER_ID); } + @Test + void onClaimAvailableWithCustomFormat(){ + when(discordEventConfiguration.getFormat()).thenReturn("{streamer} override test"); + + var webhook = tested.createSimpleMessage(new ClaimAvailableEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); + + assertThat(webhook).isEqualTo(Webhook.builder() + .content("%s override test".formatted(STREAMER_USERNAME)) + .build()); + } + @Test void onClaimAvailable(){ var webhook = tested.createSimpleMessage(new ClaimAvailableEvent(miner, STREAMER_ID, STREAMER_USERNAME, streamer, NOW), discordEventConfiguration); From 489f12d4908178c6dfbd38fbf938b8b267037fd0 Mon Sep 17 00:00:00 2001 From: Thomas Couchoud Date: Wed, 28 Dec 2022 18:29:21 +0100 Subject: [PATCH 5/7] Add some doc --- .../ROOT/examples/discord-filtering.json | 15 ++++++++ .../modules/ROOT/examples/discord-format.json | 16 +++++++++ miner/docs/modules/ROOT/nav.adoc | 3 +- .../ROOT/pages/configuration/discord.adoc | 36 +++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 miner/docs/modules/ROOT/examples/discord-filtering.json create mode 100644 miner/docs/modules/ROOT/examples/discord-format.json create mode 100644 miner/docs/modules/ROOT/pages/configuration/discord.adoc diff --git a/miner/docs/modules/ROOT/examples/discord-filtering.json b/miner/docs/modules/ROOT/examples/discord-filtering.json new file mode 100644 index 00000000..f45752b1 --- /dev/null +++ b/miner/docs/modules/ROOT/examples/discord-filtering.json @@ -0,0 +1,15 @@ +{ + "accounts" : [ + { + "discord" : { + "embeds" : false, + "webhookUrl" : "https://my-webhook-url", + "events" : { + "DropClaimedEvent" : {}, + "MinerStartedEvent" : {}, + "PointsSpentEvent" : {} + } + } + } + ] +} \ No newline at end of file diff --git a/miner/docs/modules/ROOT/examples/discord-format.json b/miner/docs/modules/ROOT/examples/discord-format.json new file mode 100644 index 00000000..794d2bf4 --- /dev/null +++ b/miner/docs/modules/ROOT/examples/discord-format.json @@ -0,0 +1,16 @@ +{ + "accounts" : [ + { + "discord" : { + "embeds" : false, + "webhookUrl" : "https://my-webhook-url", + "events" : { + "DropClaimedEvent" : {}, + "MinerStartedEvent" : { + "format" : "Oh my, the miner started for my account {username} and it uses the brand new version {version}!" + } + } + } + } + ] +} \ No newline at end of file diff --git a/miner/docs/modules/ROOT/nav.adoc b/miner/docs/modules/ROOT/nav.adoc index 8fff1e28..f220e80b 100644 --- a/miner/docs/modules/ROOT/nav.adoc +++ b/miner/docs/modules/ROOT/nav.adoc @@ -5,4 +5,5 @@ * xref:configuration/index.adoc[Configuration] ** xref:configuration/global.adoc[Global] ** xref:configuration/streamer.adoc[Streamer] -** xref:configuration/logger.adoc[Logger] \ No newline at end of file +** xref:configuration/logger.adoc[Logger] +** xref:configuration/discord.adoc[Discord] \ No newline at end of file diff --git a/miner/docs/modules/ROOT/pages/configuration/discord.adoc b/miner/docs/modules/ROOT/pages/configuration/discord.adoc new file mode 100644 index 00000000..083fd75b --- /dev/null +++ b/miner/docs/modules/ROOT/pages/configuration/discord.adoc @@ -0,0 +1,36 @@ += Discord settings + +Discord settings can be customized to filter events and/or customize the format of messages sent. + +== Filtering [[filtering]] + +To filter messages, you need to provide a list of events you want to be sent, and set no customization. + +The name of the events can be found in link:https://github.com/Rakambda/ChannelPointsMiner/tree/develop/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl[miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/impl] as the name of the classes (name of the file without `.java`). + +.Example to sent only 3 type of events with default format +[%collapsible] +==== +[source,json] +---- +include::example$discord-filtering.json[] +---- +==== + +== Format + +Format works the same way as <> except that additional parameters are provided. + +Placeholders are expected to be between braces, example: `\{placeholder_name}`. +List of available are available in link:https://github.com/Rakambda/ChannelPointsMiner/blob/filter/develop/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/EventVariableKey.java[EventVariableKey]. + +NOTE: If you want to override the format of one event, you'll have to do the all as it'll also act as a filter. + +.Example of filtering 2 events with 1 having a custom format +[%collapsible] +==== +[source,json] +---- +include::example$discord-format.json[] +---- +==== From d5b9b0a6bb1cba664877d7c94a7bb6d2731823dd Mon Sep 17 00:00:00 2001 From: Thomas Couchoud Date: Wed, 28 Dec 2022 18:33:26 +0100 Subject: [PATCH 6/7] Improve test --- .../log/discord/DiscordEventListenerTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListenerTest.java b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListenerTest.java index 19b44bc2..f914dc02 100644 --- a/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListenerTest.java +++ b/miner/src/test/java/fr/rakambda/channelpointsminer/miner/log/discord/DiscordEventListenerTest.java @@ -4,6 +4,7 @@ import fr.rakambda.channelpointsminer.miner.api.discord.data.Webhook; import fr.rakambda.channelpointsminer.miner.config.DiscordConfiguration; import fr.rakambda.channelpointsminer.miner.config.DiscordEventConfiguration; +import fr.rakambda.channelpointsminer.miner.event.AbstractLoggableStreamerEvent; import fr.rakambda.channelpointsminer.miner.event.IEvent; import fr.rakambda.channelpointsminer.miner.event.ILoggableEvent; import fr.rakambda.channelpointsminer.miner.tests.ParallelizableTest; @@ -14,6 +15,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import java.util.Map; +import java.util.Optional; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; @@ -72,6 +74,20 @@ void messageIsSent(){ verify(discordApi).sendMessage(webhook); } + @Test + void messageIsSentStreamerEvent(){ + var event = mock(AbstractLoggableStreamerEvent.class); + var eventConfiguration = mock(DiscordEventConfiguration.class); + var webhook = mock(Webhook.class); + + when(event.getStreamerUsername()).thenReturn(Optional.of("streamer")); + when(discordConfiguration.getEvents()).thenReturn(Map.of(event.getClass().getSimpleName(), eventConfiguration)); + when(discordMessageBuilder.createSimpleMessage(event, eventConfiguration)).thenReturn(webhook); + tested.onEvent(event); + + verify(discordApi).sendMessage(webhook); + } + @Test void messageIsSentDefaultConfig(){ var event = mock(ILoggableEvent.class); From f6011e3b8d80bb17f404a2cc0448e7dd17f2a9cf Mon Sep 17 00:00:00 2001 From: Thomas Couchoud Date: Wed, 28 Dec 2022 18:38:37 +0100 Subject: [PATCH 7/7] Wording --- miner/docs/modules/ROOT/pages/configuration/discord.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/docs/modules/ROOT/pages/configuration/discord.adoc b/miner/docs/modules/ROOT/pages/configuration/discord.adoc index 083fd75b..f62b7c6d 100644 --- a/miner/docs/modules/ROOT/pages/configuration/discord.adoc +++ b/miner/docs/modules/ROOT/pages/configuration/discord.adoc @@ -22,7 +22,7 @@ include::example$discord-filtering.json[] Format works the same way as <> except that additional parameters are provided. Placeholders are expected to be between braces, example: `\{placeholder_name}`. -List of available are available in link:https://github.com/Rakambda/ChannelPointsMiner/blob/filter/develop/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/EventVariableKey.java[EventVariableKey]. +Available values can be seen in link:https://github.com/Rakambda/ChannelPointsMiner/blob/filter/develop/miner/src/main/java/fr/rakambda/channelpointsminer/miner/event/EventVariableKey.java[EventVariableKey]. NOTE: If you want to override the format of one event, you'll have to do the all as it'll also act as a filter.