Skip to content

Commit

Permalink
Merge pull request #387 from Rakambda/filter/discord-customization
Browse files Browse the repository at this point in the history
Discord messages customization
  • Loading branch information
Rakambda authored Dec 29, 2022
2 parents 613a97b + f6011e3 commit ba2f139
Show file tree
Hide file tree
Showing 40 changed files with 887 additions and 488 deletions.
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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" }
Expand Down
1 change: 1 addition & 0 deletions miner/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions miner/docs/modules/ROOT/examples/discord-filtering.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"accounts" : [
{
"discord" : {
"embeds" : false,
"webhookUrl" : "https://my-webhook-url",
"events" : {
"DropClaimedEvent" : {},
"MinerStartedEvent" : {},
"PointsSpentEvent" : {}
}
}
}
]
}
16 changes: 16 additions & 0 deletions miner/docs/modules/ROOT/examples/discord-format.json
Original file line number Diff line number Diff line change
@@ -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}!"
}
}
}
}
]
}
3 changes: 2 additions & 1 deletion miner/docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
* xref:configuration/index.adoc[Configuration]
** xref:configuration/global.adoc[Global]
** xref:configuration/streamer.adoc[Streamer]
** xref:configuration/logger.adoc[Logger]
** xref:configuration/logger.adoc[Logger]
** xref:configuration/discord.adoc[Discord]
36 changes: 36 additions & 0 deletions miner/docs/modules/ROOT/pages/configuration/discord.adoc
Original file line number Diff line number Diff line change
@@ -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 <<filtering, filtering>> except that additional parameters are provided.

Placeholders are expected to be between braces, example: `\{placeholder_name}`.
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.

.Example of filtering 2 events with 1 having a custom format
[%collapsible]
====
[source,json]
----
include::example$discord-format.json[]
----
====
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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. 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<String, DiscordEventConfiguration> events = new HashMap<>();
}
Original file line number Diff line number Diff line change
@@ -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. 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;
}
Original file line number Diff line number Diff line change
@@ -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<NumberFormat> numberFormatLocal = ThreadLocal.withInitial(() -> {
Expand All @@ -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<String, String> 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<? extends Field> getEmbedFields(){
return List.of();
}
protected abstract String getEmoji();
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
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;
import lombok.Getter;
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;

Expand All @@ -33,25 +33,17 @@ 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_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);
}
return super.lookup(key);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -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";
}
Original file line number Diff line number Diff line change
@@ -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<String, String> getEmbedFields();
}
Loading

0 comments on commit ba2f139

Please sign in to comment.