Skip to main content

Discord Webhook Notifier

DiscordWebhookNotifier sends embedded alerts to a Discord channel when relevant events occur. All using the standard java.net.http.HttpClient (Java 11+) API — no JDA, no OkHttp, no external dependencies.

Configuration

Activation condition: enabled = !webhook_url.isEmpty() && HttpClient != null. If the JVM cannot instantiate HttpClient.newBuilder(), the notifier is silently disabled.

HttpClient (No External Libraries)

Each request uses:
  • HttpRequest.BodyPublishers.ofString(json, UTF_8) — POST JSON method
  • HttpResponse.BodyHandlers.discarding() — does not parse response
  • Global 8s timeout + CompletableFuture.orTimeout(10s, TimeUnit.SECONDS)
HTTP codes outside the 2xx range are logged as a warning: [Discord] Webhook returned HTTP 404.

Events That Trigger an Embed

DiscordWebhookNotifier is registered as a listener of TransactionLogService:

Embed Structure: Transaction > Threshold

Color depends on flow (green if recipient gains, red if loses). i18n keys for titles/fields are looked up in:
  • discord.threshold.title, discord.threshold.desc
  • discord.dupe.title, discord.error.title
  • discord.tx_type.PLAYER_PAY etc. (24+ keys, one per TxType)
  • discord.field.txid, discord.field.currency, discord.field.amount…
All embeds use the language defined in config.language (of the 11 supported). If a key is missing, the raw TxType name is shown as a fallback.

Anti-spam LRU (500 IDs)

To avoid spam from repeated flushes, a RollingLinkedHashSet extends LinkedHashSet<String> of 500 max entries is used. When it reaches max size, it evicts the oldest by insertion order. Registered keys:
  • Normal transactions → raw txId
  • Duplicates → DUPE: prefix + txId
If the key already exists in the set, the embed is silently discarded.