From 44271eeec4bae1460228afdf13c62f47f8312e70 Mon Sep 17 00:00:00 2001 From: siujamo Date: Mon, 1 Jun 2026 15:27:35 +0800 Subject: [PATCH] feat: add GitHub webhook DTOs with snake_case mapping and header constants Replace GitHubIssueLabeledWebhookRequest with GitHubIssueRequest. Add number and repository fields for dedup key construction. Add Jackson @JsonNaming/@JsonIgnoreProperties for GitHub payload deserialisation. Add GitHubWebhookHeader constants for webhook header names. --- .../dto/GitHubIssueLabeledWebhookRequest.java | 7 --- .../domain/dto/GitHubIssueRequest.java | 14 +++++ .../domain/dto/GitHubWebhookIssue.java | 7 +++ .../domain/dto/GitHubWebhookLabel.java | 6 ++ .../domain/dto/GitHubWebhookRepository.java | 12 ++++ .../shared/GitHubWebhookHeader.java | 56 +++++++++++++++++++ 6 files changed, 95 insertions(+), 7 deletions(-) delete mode 100644 src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubIssueLabeledWebhookRequest.java create mode 100644 src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubIssueRequest.java create mode 100644 src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookRepository.java create mode 100644 src/main/java/com/onixbyte/deltaforceguide/shared/GitHubWebhookHeader.java diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubIssueLabeledWebhookRequest.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubIssueLabeledWebhookRequest.java deleted file mode 100644 index b7384ef..0000000 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubIssueLabeledWebhookRequest.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.onixbyte.deltaforceguide.domain.dto; - -public record GitHubIssueLabeledWebhookRequest( - String action, - GitHubWebhookIssue issue -) { -} diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubIssueRequest.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubIssueRequest.java new file mode 100644 index 0000000..449591b --- /dev/null +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubIssueRequest.java @@ -0,0 +1,14 @@ +package com.onixbyte.deltaforceguide.domain.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public record GitHubIssueRequest( + String action, + GitHubWebhookIssue issue, + GitHubWebhookRepository repository +) { +} diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookIssue.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookIssue.java index abc3655..91263cc 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookIssue.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookIssue.java @@ -1,10 +1,17 @@ package com.onixbyte.deltaforceguide.domain.dto; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + import java.util.List; +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) public record GitHubWebhookIssue( String url, Long id, + Long number, String title, String body, List labels diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookLabel.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookLabel.java index fb3407a..33954ab 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookLabel.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookLabel.java @@ -1,5 +1,11 @@ package com.onixbyte.deltaforceguide.domain.dto; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) public record GitHubWebhookLabel( String name ) { diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookRepository.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookRepository.java new file mode 100644 index 0000000..e3858d6 --- /dev/null +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/GitHubWebhookRepository.java @@ -0,0 +1,12 @@ +package com.onixbyte.deltaforceguide.domain.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public record GitHubWebhookRepository( + String fullName +) { +} diff --git a/src/main/java/com/onixbyte/deltaforceguide/shared/GitHubWebhookHeader.java b/src/main/java/com/onixbyte/deltaforceguide/shared/GitHubWebhookHeader.java new file mode 100644 index 0000000..05b9d58 --- /dev/null +++ b/src/main/java/com/onixbyte/deltaforceguide/shared/GitHubWebhookHeader.java @@ -0,0 +1,56 @@ +package com.onixbyte.deltaforceguide.shared; + +/** + * This class lists the header names that GitHub sends in webhook requests. + * + * @author siujamo + */ +public class GitHubWebhookHeader { + + /** + * The unique identifier of the webhook. + */ + public static final String HOOK_ID = "X-GitHub-Hook-ID"; + + /** + * The name of the event that triggered the delivery. + */ + public static final String EVENT = "X-GitHub-Event"; + + /** + * A globally unique identifier (GUID) to identify the event. + */ + public static final String DELIVERY = "X-GitHub-Delivery"; + + /** + * This header is sent if the webhook is configured with a {@code secret}. This is the HMAC hex + * digest of the request body, and is generated using the SHA-1 hash function and the secret as + * the HMAC {@code key}. {@code X-Hub-Signature} is provided for compatibility with + * existing integrations. We recommend that you use the more secure + * {@code X-Hub-Signature-256} instead. + */ + public static final String SIGNATURE = "X-Hub-Signature"; + + /** + * This header is sent if the webhook is configured with a {@code secret}. This is the HMAC hex + * digest of the request body, and is generated using the SHA-256 hash function and the + * {@code secret} as the HMAC key. For more information, see Validating webhook deliveries. + */ + public static final String SIGNATURE_256 = "X-Hub-Signature-256"; + + /** + * This header will always have the prefix {@code GitHub-Hookshot/}. + */ + public static final String USER_AGENT = "User-Agent"; + + /** + * The type of resource where the webhook was created. + */ + public static final String INSTALLATION_TARGET_TYPE = "X-GitHub-Hook-Installation-Target-Type"; + + /** + * The unique identifier of the resource where the webhook was created. + */ + public static final String INSTALLATION_TARGET_ID = "X-GitHub-Hook-Installation-Target-ID"; +}