Skip to content

Thông báo Discord: Hỗ trợ dạng embed - #72

Merged
amadeusmz merged 11 commits into
masterfrom
dev/discord-hook-embed
Dec 21, 2025
Merged

Thông báo Discord: Hỗ trợ dạng embed#72
amadeusmz merged 11 commits into
masterfrom
dev/discord-hook-embed

Conversation

@minhh2792

@minhh2792 minhh2792 commented Oct 12, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Discord notifications now support full webhook payloads (embeds, fields, author/footer, images/thumbnails), multi-line content, customizable username/avatar, and a formatted time placeholder (HH:mm:ss dd/MM/yyyy).
    • Notifications send payload maps with runtime placeholder replacement across all payload fields.
  • Bug Fixes

    • Recursive placeholder replacement now handles strings, lists, maps and normalizes color hex values.
    • Webhook loading skips invalid entries and logs warnings.
  • Documentation

    • Updated Discord config examples and payload guidance.
  • Chores

    • Updated dependency to a newer library patch release.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Oct 12, 2025

Copy link
Copy Markdown
Contributor

Caution

Review failed

The head commit changed during the review from 6feb488 to 96ba0d0.

Walkthrough

Replaces simple per-webhook text with payload-based Discord webhooks: introduces an external Webhook that accepts payload maps and a replacements map, adds recursive placeholder application for strings/maps/lists (including hex color → int), updates DotMan to build a replacements map (adds formatted %TIME%), and bumps a dependency.

Changes

Cohort / File(s) Summary of edits
Discord config
dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt
Loads discord-hooks as payload entries, validates enabled/url/payload, constructs net.minevn.dotman.discord.Webhook instances, exposes webhooks: List<Webhook>, and removes the old internal WebHook DTO and its send(content) logic.
Runtime webhook sender
dotman-plugin/src/main/java/net/minevn/dotman/discord/Webhook.kt
New Webhook(url: String, payload: Map<*, *>) class with send(replacements: Map<String, String>) that applies replacements recursively to the payload, serializes to JSON and POSTs to the URL; logs failures.
Placeholder utilities
dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt
Added recursive replacement utilities: applyReplacements(input: Any?, replacements: Map<String,String>) plus overloads for Map and List, and replaceAllPlaceholders; converts hex color strings to ints via parseHexColorToInt, joins all-string lists into newline, and processes nested structures.
Notification flow
dotman-plugin/src/main/java/net/minevn/dotman/DotMan.kt
Replaced per-entry inline string composition with a replacements map (adds formatted %TIME% using LocalDateTime/DateTimeFormatter) and calls each webhook's send(replacements) instead of sending individual content strings.
Discord YAML schema
dotman-plugin/src/main/resources/discord.yml
Replaced simple content entries with payload structures supporting username, avatar_url, content (array), embeds (title, description, color, fields, image, thumbnail, author, footer) and placeholders; updated examples.
Build
dotman-plugin/build.gradle.kts
Bumped dependency: net.minevn:minevnlib-plugin:1.2.0-beta31.2.1-beta3.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Player as Player Action
  participant DotMan as DotMan.updateLeaderBoard
  participant DiscordCfg as Discord.config (webhooks)
  participant Webhook as Webhook (net.minevn.dotman.discord)
  participant Formatter as FormatUtils.applyReplacements
  participant DiscordAPI as Discord HTTP

  Player->>DotMan: trigger leaderboard update
  DotMan->>DotMan: build replacements map (includes %TIME%)
  DotMan->>DiscordCfg: read configured webhooks
  loop for each webhook
    DotMan->>Webhook: send(replacements)
    Webhook->>Formatter: applyReplacements(payload, replacements)
    Formatter-->>Webhook: resolved payload (maps/lists/strings processed)
    Webhook->>DiscordAPI: POST resolved JSON payload
    alt success (2xx)
      DiscordAPI-->>Webhook: 2xx
    else failure
      DiscordAPI-->>Webhook: error / exception (logged)
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to focus on:
    • Recursive replacement edge cases in FormatUtils (mixed-type lists, non-string map keys).
    • Hex color parsing and numeric conversion when processing color fields.
    • JSON serialization shape and HTTP headers/error handling in Webhook.send.
    • Robust validation and safe casting when loading discord-hooks payloads in Discord.kt.
    • Time formatting and timezone/localization assumptions introduced in DotMan.kt.

Poem

I hop and stitch each payload bright,
Tokens tumble, %TIME% set right.
Maps and lists I gently comb,
Embed the stars, then send them home.
🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Thông báo Discord: Hỗ trợ dạng embed' (Discord notifications: embed format support) directly and clearly describes the main change—adding Discord embed notification support across multiple files and configuration.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3852219 and 2e08acc.

📒 Files selected for processing (3)
  • dotman-plugin/src/main/java/net/minevn/dotman/DotMan.kt (2 hunks)
  • dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1 hunks)
  • dotman-plugin/src/main/resources/discord.yml (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1)
dotman-plugin/src/main/java/net/minevn/dotman/utils/Utils.kt (1)
  • info (27-27)

Comment thread dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt Outdated

@amadeusmz amadeusmz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yêu cầu: Giải quyết các comment này bằng AI (ChatGPT Codex hoặc Junie), chụp lại bằng chứng và commit dưới tên AI

Comment thread dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt
Comment thread dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt Outdated
Comment thread dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt Outdated
Comment thread dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt Outdated
Comment thread dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt Outdated
Comment thread dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt Outdated
Comment thread dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt Outdated
Comment thread dotman-plugin/src/main/resources/discord.yml Outdated
@minhh2792

Copy link
Copy Markdown
Member Author
image

@minhh2792
minhh2792 force-pushed the dev/discord-hook-embed branch from f2300a9 to 19cf963 Compare October 25, 2025 20:04
@minhh2792

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 25, 2025

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (2)

56-62: Consider using fold for more idiomatic Kotlin.

The current implementation works correctly but could be more idiomatic:

-private fun replaceAllPlaceholders(text: String, replacements: Map<String, String>): String {
-    var result: String = text
-    for ((placeholder, replaceValue) in replacements) {
-        result = result.replace(placeholder, replaceValue, ignoreCase = false)
-    }
-    return result
-}
+private fun replaceAllPlaceholders(text: String, replacements: Map<String, String>): String {
+    return replacements.entries.fold(text) { acc, (placeholder, replaceValue) ->
+        acc.replace(placeholder, replaceValue, ignoreCase = false)
+    }
+}

68-76: Consider extracting the magic string "color" as a constant.

The hardcoded string "color" at line 70 could be extracted for better maintainability:

companion object {
    private const val COLOR_FIELD = "color"
}

Then update line 70:

if (key == COLOR_FIELD && value is String) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e08acc and 19cf963.

📒 Files selected for processing (3)
  • dotman-plugin/build.gradle.kts (1 hunks)
  • dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1 hunks)
  • dotman-plugin/src/main/resources/discord.yml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • dotman-plugin/src/main/resources/discord.yml
🔇 Additional comments (2)
dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1)

83-93: The review comment is based on incorrect assumptions about the code design.

The Vietnamese documentation at lines 78-81 explicitly states the intentional behavior: "Nếu list chứa toàn String -> join thành 1 chuỗi với separator \n" (If list contains all strings → join into 1 string with \n separator). An empty list of strings logically becomes an empty string, consistent with this design. This is not a type mismatch bug; it's the documented conversion of string-only lists into multiline text content. The code is working as designed.

Likely an incorrect or invalid review comment.

dotman-plugin/build.gradle.kts (1)

20-20: Dependency version bump requires manual verification—repository server unreachable.

The minevnlib-plugin version upgrade from 1.2.0-beta3 to 1.2.1-beta3 is syntactically correct, but the remote repository (https://repo.minevn.net/releases/) is currently returning HTTP 522 errors, preventing verification of artifact availability. Confirm that your local build succeeds and that this version is accessible from your configured repositories before merging.

Comment thread dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt Outdated
@omdumrotat

Copy link
Copy Markdown
Contributor

@codex review

- chuyển các hàm format vào utils

- bổ sung config mẫu: sử dụng nhiều webhook cùng lúc + EOF
@minhh2792
minhh2792 force-pushed the dev/discord-hook-embed branch from 8afba5c to c90e03f Compare November 2, 2025 09:36

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19cf963 and c90e03f.

📒 Files selected for processing (5)
  • dotman-plugin/src/main/java/net/minevn/dotman/DotMan.kt (2 hunks)
  • dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1 hunks)
  • dotman-plugin/src/main/java/net/minevn/dotman/discord/Webhook.kt (1 hunks)
  • dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt (2 hunks)
  • dotman-plugin/src/main/resources/discord.yml (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-03T09:28:38.800Z
Learnt from: amadeusmz
Repo: minevn/dotman PR: 68
File: dotman-plugin/src/main/java/net/minevn/dotman/config/PlannedExtras.kt:10-10
Timestamp: 2025-08-03T09:28:38.800Z
Learning: In the dotman codebase, SimpleDateFormat is widely used throughout the project. The team prefers to defer thread safety improvements to DateTimeFormatter until they can address it comprehensively across the entire codebase rather than making piecemeal changes.

Applied to files:

  • dotman-plugin/src/main/java/net/minevn/dotman/DotMan.kt
  • dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt
🧬 Code graph analysis (2)
dotman-plugin/src/main/java/net/minevn/dotman/discord/Webhook.kt (1)
dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt (1)
  • applyReplacements (40-58)
dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1)
dotman-plugin/src/main/java/net/minevn/dotman/utils/Utils.kt (1)
  • info (27-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

Comment on lines +11 to +13
if (map["enabled"] as? Boolean != true) {
return@mapNotNull null
}

@coderabbitai coderabbitai Bot Nov 2, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Entries without enabled: true are silently dropped

The loader currently requires enabled == true; when the field is missing (per the YAML comment “mặc định là true”), map["enabled"] is null, so the webhook never registers. Anyone trusting the documented default will lose every notification. Please treat null as enabled and only skip when the flag is explicitly false.

-            if (map["enabled"] as? Boolean != true) {
-                return@mapNotNull null
-            }
+            val enabled = map["enabled"] as? Boolean ?: true
+            if (!enabled) {
+                return@mapNotNull null
+            }
🤖 Prompt for AI Agents
In dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt around lines
11 to 13, the current check drops entries when map["enabled"] is null; change
the logic to only skip when the flag is explicitly false. Replace the condition
so it returns null only if (map["enabled"] as? Boolean == false), thereby
treating missing/null as enabled by default and preserving documented behavior.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, expected behaviour

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@minhh2792, understood! I've noted that the explicit enabled: true requirement is intentional for webhook registration.

 /)_/)
(o.o)
(> <)  *noted*

✏️ Learnings added
Learnt from: minhh2792
Repo: minevn/dotman PR: 72
File: dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt:0-0
Timestamp: 2025-11-02T09:53:20.038Z
Learning: In the Discord webhook configuration (dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt), webhooks must have `enabled: true` explicitly set to be registered. Missing or null `enabled` fields result in the webhook being silently dropped, and this is the expected behavior (explicit opt-in).

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt Outdated
@minhh2792
minhh2792 force-pushed the dev/discord-hook-embed branch from 7c7f5cc to c90e03f Compare November 2, 2025 09:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1)

11-13: The enabled field default behavior is still incorrect.

This issue was flagged in a previous review but remains unaddressed. When enabled is missing or null, the current condition map["enabled"] as? Boolean != true evaluates to true, causing the webhook to be skipped. Per the documented default behavior (and the previous review), webhooks should be enabled by default when the field is omitted.

Users who don't explicitly set enabled: true will have their webhooks silently ignored, breaking expected functionality.

Apply this diff to fix the default behavior:

-            if (map["enabled"] as? Boolean != true) {
-                return@mapNotNull null
-            }
+            val enabled = map["enabled"] as? Boolean ?: true
+            if (!enabled) {
+                return@mapNotNull null
+            }
🧹 Nitpick comments (1)
dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1)

17-19: Consider enhancing error messages with entry context.

The current error handling logs only the exception message. Including the entry index or partial content (e.g., URL if available) would make debugging configuration issues much easier for users.

Consider this enhancement:

-        } catch (e: TypeCastException) {
-            warning("Có lỗi xảy ra khi nạp webhook: ${e.message}")
-            null
+        } catch (e: TypeCastException) {
+            val urlHint = (raw as? Map<*, *>)?.get("url")?.let { " (url: $it)" } ?: ""
+            warning("Có lỗi xảy ra khi nạp webhook${urlHint}: ${e.message}")
+            null
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c90e03f and fb6a9a0.

📒 Files selected for processing (1)
  • dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1)
dotman-plugin/src/main/java/net/minevn/dotman/utils/Utils.kt (1)
  • info (27-27)
🔇 Additional comments (1)
dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt (1)

23-25: Initialization logging looks good.

The init block appropriately logs the number of successfully loaded webhooks, providing useful feedback for configuration validation.

@minhh2792
minhh2792 requested a review from amadeusmz November 2, 2025 13:59
Comment thread dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt Outdated
Comment thread dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt Outdated
@minhh2792

Copy link
Copy Markdown
Member Author

@amadeusmz em đã sửa lại tí
nếu ổn có thể merge beta

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt (1)

86-96: Empty lists are collapsed to an empty String – confirm this is desired

Because inputList.all { it is String } is also true for an empty list, [] becomes "" instead of staying as an empty list. If you prefer to preserve [] (e.g. for JSON shape correctness on fields that are arrays), you could gate the join on isNotEmpty():

fun applyReplacements(inputList: List<*>, replacements: Map<String, String>): Any {
-    val isAllStrings = inputList.all { it is String }
-    if (isAllStrings) {
+    val isAllStrings = inputList.all { it is String }
+    if (isAllStrings && inputList.isNotEmpty()) {
         val joinedText = inputList.filterIsInstance<String>().joinToString("\n")
         return replaceAllPlaceholders(joinedText, replacements)
     } else {
         return inputList.map { element ->
             applyReplacements(element, replacements)
         }
     }
}

If your payloads never use empty lists for “joined-text” fields, current behavior may be fine, but it’s worth deciding explicitly.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 660fbf6 and f4b2066.

📒 Files selected for processing (1)
  • dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: minhh2792
Repo: minevn/dotman PR: 72
File: dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt:0-0
Timestamp: 2025-11-02T09:53:20.064Z
Learning: In the Discord webhook configuration (dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt), webhooks must have `enabled: true` explicitly set to be registered. Missing or null `enabled` fields result in the webhook being silently dropped, and this is the expected behavior (explicit opt-in).
📚 Learning: 2025-11-02T09:53:48.847Z
Learnt from: minhh2792
Repo: minevn/dotman PR: 72
File: dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt:83-90
Timestamp: 2025-11-02T09:53:48.847Z
Learning: In dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt, the processMap function intentionally does NOT replace placeholders in "color" field values before parsing them with parseHexColorToInt. Color values should remain static/literal hex strings rather than supporting dynamic placeholder replacement.

Applied to files:

  • dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt
📚 Learning: 2025-08-03T09:28:38.800Z
Learnt from: amadeusmz
Repo: minevn/dotman PR: 68
File: dotman-plugin/src/main/java/net/minevn/dotman/config/PlannedExtras.kt:10-10
Timestamp: 2025-08-03T09:28:38.800Z
Learning: In the dotman codebase, SimpleDateFormat is widely used throughout the project. The team prefers to defer thread safety improvements to DateTimeFormatter until they can address it comprehensively across the entire codebase rather than making piecemeal changes.

Applied to files:

  • dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (1)
dotman-plugin/src/main/java/net/minevn/dotman/utils/FormatUtils.kt (1)

40-76: Recursive replacement + color handling look consistent with prior intent

The overload-based applyReplacements dispatcher for String / Map / List is clean, and the Map overload’s "color" branch correctly keeps color as a literal hex string and only parses it via parseHexColorToInt instead of running placeholder replacement, matching the documented “static color only” requirement. Based on learnings, this behavior is expected and avoids reintroducing dynamic colors.

If parseHexColorToInt’s behavior changes in future versions of minevnlib-plugin (e.g. error handling or accepted formats), please re-check that invalid hex values here fail gracefully for Discord embeds.

omdumrotat and others added 2 commits December 10, 2025 00:51
* added %server% placeholder to discord.yml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
dotman-plugin/src/main/resources/discord.yml (1)

10-89: Consider consolidating or clearly documenting the duplicate webhook examples.

The configuration includes two nearly identical webhook entries (lines 10–48 and 51–89) for demonstration purposes. While this may be intentional to show multiple channels, the duplication is extensive. Consider:

  • Adding a comment explaining that this is a template/example for multiple channels, or
  • Consolidating into a single example with a note about replication for additional channels.

This will improve clarity and reduce confusion for users copying the configuration.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4b2066 and dca574c.

📒 Files selected for processing (2)
  • dotman-plugin/src/main/java/net/minevn/dotman/DotMan.kt (2 hunks)
  • dotman-plugin/src/main/resources/discord.yml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • dotman-plugin/src/main/java/net/minevn/dotman/DotMan.kt
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-02T09:53:20.064Z
Learnt from: minhh2792
Repo: minevn/dotman PR: 72
File: dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt:0-0
Timestamp: 2025-11-02T09:53:20.064Z
Learning: In the Discord webhook configuration (dotman-plugin/src/main/java/net/minevn/dotman/config/Discord.kt), webhooks must have `enabled: true` explicitly set to be registered. Missing or null `enabled` fields result in the webhook being silently dropped, and this is the expected behavior (explicit opt-in).

Applied to files:

  • dotman-plugin/src/main/resources/discord.yml

Comment thread dotman-plugin/src/main/resources/discord.yml
Comment thread dotman-plugin/src/main/resources/discord.yml
@amadeusmz

Copy link
Copy Markdown
Member

@coderabbitai hãy đọc các comment của tôi trong pull request này, và ghi nhớ những điểm tôi comment để áp dụng cho các pull request tương lai

@coderabbitai

coderabbitai Bot commented Dec 21, 2025

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch all review comments from PR #72
echo "=== Review Comments ==="
gh pr view 72 --repo minevn/dotman --json reviews --jq '.reviews[] | select(.author.login == "amadeusmz") | {author: .author.login, body: .body, state: .state}'

echo ""
echo "=== Review Thread Comments ==="
# Fetch review thread comments
gh api repos/minevn/dotman/pulls/72/comments --jq '.[] | select(.user.login == "amadeusmz") | {author: .user.login, body: .body, path: .path, line: .line}'

echo ""
echo "=== Issue Comments ==="
# Fetch issue comments on the PR
gh api repos/minevn/dotman/issues/72/comments --jq '.[] | select(.user.login == "amadeusmz") | {author: .user.login, body: .body}'

Length of output: 3986


@amadeusmz Tôi đã đọc tất cả các comment của bạn trong pull request này. Đây là những điểm tôi sẽ ghi nhớ cho các pull request tương lai:

Về cấu trúc code:

  • Tổ chức package riêng thay vì lạm dụng subclasses và extension functions
  • Extension functions chỉ dùng khi mở rộng class không thuộc sở hữu hoặc cho nghiệp vụ đặc thù
  • Các utility functions nên đưa vào Utils hoặc MineVNLib

Về cách viết code:

  • Tránh sử dụng tên biến quá ngắn (a, b, c, x, y, z) - dùng tên mô tả rõ vai trò
  • Tránh dùng data làm tên biến vì trùng keyword Kotlin
  • Không lạm dụng lambda và inline if - dùng try/catch truyền thống và xuống dòng với {}
  • Code tường minh hơn luôn tốt hơn

Về error handling:

  • Xử lý lỗi ngay tại giai đoạn load config với guard clauses, không để tới lúc sử dụng
  • Sử dụng null checks và validation sớm

Về technical:

  • File cần có EOF (end-of-file newline)
  • Tắt auto CRLF để tránh line separator issues gây changes cả file

Tôi đã ghi nhớ các guideline này và sẽ áp dụng cho các review trong tương lai.


✏️ Learnings added
Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository (Kotlin project): Avoid using very short variable names like a, b, c, x, y, z. Use descriptive variable names that clearly express the nature and role of the variable (e.g., replaceFrom, replaceTo, string).

Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository (Kotlin project): Avoid using `data` as a variable name because it conflicts with Kotlin's `data` keyword.

Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository (Kotlin project): Instead of creating too many subclasses and extension functions, create a dedicated package for the feature (e.g., a discord package) with necessary classes and functions inside. Extension functions should only be used when extending classes not owned by you or for specific business logic requirements.

Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository (Kotlin project): Don't overuse lambdas for error handling - they may look sophisticated but are hard to read. Use traditional try/catch blocks for better readability.

Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository (Kotlin project): Write more explicit code. When checking boolean values like 'enabled', default should be false. Avoid inline if statements - use newlines and braces `{}` for better readability.

Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository (Kotlin project): Utility functions for common operations (like string replacement, color parsing) should be moved to Utils or higher up to MineVNLib for reusability.

Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository (Kotlin project): Functions should handle errors at config load time with proper null checks and guard clauses, not defer error detection to usage time. Use early validation with guard clauses similar to checking enabled status and type casting.

Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository: All files must have EOF (end-of-file newline).

Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository: Disable auto CRLF on local machine and commit files as-is to prevent line separator issues that cause GitHub to show changes for entire files.

Learnt from: amadeusmz
URL: https://github.com/minevn/dotman/pull/72

Timestamp: 2025-12-21T06:30:03.435Z
Learning: In the minevn/dotman repository (Kotlin project): Use clear and descriptive function names. When creating variations of a function, use method overloading with the same name (e.g., `applyReplacements`) instead of creating functions with different names for similar operations.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@amadeusmz
amadeusmz merged commit 3a6cbc6 into master Dec 21, 2025
3 checks passed
@amadeusmz
amadeusmz deleted the dev/discord-hook-embed branch December 21, 2025 06:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants