fix: put filters under routes and add route logging to startup
/ build-docker-release (push) Successful in 7s
/ build (push) Successful in 21s
/ build-docker-nightly (push) Has been skipped

This commit is contained in:
2026-06-15 15:17:04 +02:00
parent b7df5a3fde
commit 44c63c0f10
4 changed files with 63 additions and 25 deletions
@@ -1,24 +1,56 @@
package dev.webhookproxy.config;
import jakarta.annotation.PostConstruct;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Data
@Component
@ConfigurationProperties(prefix = "proxy")
public class ProxyConfig {
private List<String> routes = List.of();
private Filters filters;
private List<Route> routes = List.of();
@Getter
@Setter
@PostConstruct
public void logConfig() {
log.info("Loaded {} route(s):", routes.size());
for (int i = 0; i < routes.size(); i++) {
Route route = routes.get(i);
log.info(" [{}] {}", i + 1, maskUrl(route.getUrl()));
List<String> usernames = route.getFilters().getUsernameFilter();
if (usernames.isEmpty()) {
log.info(" usernameFilter: (none)");
} else {
log.info(" usernameFilter: {}", usernames);
}
}
}
private String maskUrl(String url) {
if (url == null) return "(null)";
int lastSlash = url.lastIndexOf('/');
if (lastSlash < 0 || lastSlash >= url.length() - 1) return url;
String token = url.substring(lastSlash + 1);
return url.substring(0, lastSlash + 1) + token.substring(0, Math.min(2, token.length())) + "***";
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Route {
private String url;
private Filters filters = new Filters();
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Filters {
private List<String> usernameFilter;
private List<String> usernameFilter = List.of();
}
}
@@ -32,15 +32,6 @@ public class WebhookController {
log.info("Incoming notification type: {}", payload.getNotificationType());
if (payload.getRequest() != null) {
if (proxyConfig.getFilters().getUsernameFilter().contains(payload.getRequest().getRequestedByUsername())) {
String user = payload.getRequest().getRequestedByUsername();
String movie = payload.getSubject();
log.info("Blocked notifications for user {} and movie {}", user, movie);
return ResponseEntity.ok("OK");
}
}
forwardingService.forward(payload, rawBody);
return ResponseEntity.ok("OK");
@@ -32,24 +32,39 @@ public class DiscordForwardingService {
public void forward(SeerrPayload payload, String rawBody) {
String mediaName = payload.getSubject();
List<String> targets = proxyConfig.getRoutes();
List<ProxyConfig.Route> routes = proxyConfig.getRoutes();
if (targets.isEmpty()) {
if (routes.isEmpty()) {
log.warn("No Discord webhooks configured — skipping.");
return;
}
log.info("Forwarding notification for media {} to {} Discord webhook(s).", mediaName, targets.size());
String discordBody = buildDiscordPayload(payload);
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (String webhookUrl : targets) {
futures.add(sendAsync(webhookUrl, discordBody, mediaName));
for (ProxyConfig.Route route : routes) {
if (isBlocked(route, payload)) {
log.info("Route {} blocked notification for user {} and media {}",
maskUrl(route.getUrl()),
payload.getRequest() != null ? payload.getRequest().getRequestedByUsername() : "unknown",
mediaName);
continue;
}
futures.add(sendAsync(route.getUrl(), discordBody, mediaName));
}
if (!futures.isEmpty()) {
log.info("Forwarding notification for media {} to {} Discord webhook(s).", mediaName, futures.size());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
}
}
private boolean isBlocked(ProxyConfig.Route route, SeerrPayload payload) {
List<String> usernameFilter = route.getFilters().getUsernameFilter();
if (usernameFilter.isEmpty()) return false;
if (payload.getRequest() == null) return false;
return usernameFilter.contains(payload.getRequest().getRequestedByUsername());
}
private CompletableFuture<Void> sendAsync(String webhookUrl, String body, String notificationType) {
HttpRequest request = HttpRequest.newBuilder()
+2 -2
View File
@@ -2,11 +2,11 @@ server:
port: 8080
proxy:
routes:
- url: https://discord.com/api/webhooks/1498794785475920022/bwoytZA_iDvza86fbR9aOFXNOcv9_Fl5P5taoOaMHjey_X3YLRt5FGbDjt9uPiKHJ8yi
filters:
usernameFilter:
- private
routes:
- https://discord.com/api/webhooks/1498794785475920022/bwoytZA_iDvza86fbR9aOFXNOcv9_Fl5P5taoOaMHjey_X3YLRt5FGbDjt9uPiKHJ8yi
# Spring Boot Actuator — exposes /actuator/health endpoint
management: